TYPO3 offers a number of ways to attach custom functionality to the backend. They fall into these categories:
The backend menu reflects the hierarchy of modules in TYPO3, divided into Main modules and Sub modules. This was discussed in the introduction to the backend interface. Their properties are:
Backend MenuThey appear in the backend menu and "About modules" screen. They have an icon, title, description etc.
Access controlThey can be access controlled for backend users and groups automatically (depends on configuration).
There is a special kind of module; Frameset modules are main modules in TYPO3 which provides a navigation/list frameset for sub-modules. The "Web" and "File" main modules are frameset modules.
The "Function Menu" is the selector box menu you will often find in the upper right corner of backend modules. By that selector you can select sub-functionality within that module. Often this functionality is hardcoded into the backend module. In other cases (like the core modules Web>Info and Web>Functions) there is an API which allows you to add additional items to the function menu and specify which PHP-class to call for rendering the content of that item.
The idea of Function Menu modules is that you can add minor functionalities without introducing a whole new backend module which shows up in the menu. Their properties are:
DiscreteAdds functionality discretely or in certain contexts (like in the Web>Template module you would add functionality related to TypoScript Templates).
SimpleInherits access control and default configuration from main module.
Finally, a script can also work in the backend without being a "real" module (like those in the menu) or Function Menu module. Such a script basically needs to include the "init.php" file from the TYPO3 main folder in order to authenticate the backend users and include the standard classes of TYPO3. Technically this is done by using a subset of the module API. Such a stand alone script is what you will normally get if you create a new CSM item that has to link to a backend enabled script.
In TYPO3 all modules are configured in the global variable, $TBE_MODULES (see t3lib/stddb/tables.php). $TBE_MODULES contains the structure of the backend modules as they are arranged in main- and sub-modules. Every entry in this array represents a menu item on either first level (array key) or second level (value from list) in the left menu in the TYPO3 backend.
$TBE_MODULES = Array (
'web' => 'list,info,perm,func',
'file' => 'list',
'doc' => '', // This should always be empty!
'user' => '',
'tools' => 'em',
'help' => 'about,cshmanual'
);
The syntax is:
$TBE_MODULES[ module ] => "submodule_1,submodule_2,submodule_3,submodule_4"
There are two special keys in the $TBE_MODULES array to be aware of:
$TBE_MODULES['_PATHS'] is an array used by extensions to register module file locations (for backend modules located in extensions). Obviously, this is not representing a main module.
$TBE_MODULES['doc'] is a main module which cannot have any sub modules.
Modules can be located in the file system after three different principles:
Core modulesThe file location of the core modules is "typo3/mod/". Here you will find a number of folders (main modules) and sub-folders (sub modules) with "conf.php" files and icons in. It's unlikely that new core modules are added since extensions should provide all future modules. You should never add core modules by yourself.Core modules are arranged in folders after the schemes "typo3/mod/[module]" and "typo3/mod/[module]/[submodule]".
User defined modules (OBSOLETE)Modules located in "../typo3conf/" directory after the same principles as core modules (typo3conf/[module key]/[sub-module key]). If a module or sub-module key in $TBE_MODULES is not found in "typo3/mod/" then it is looked for in "../typo3conf/". Module/Sub-module keys of user defined modules should be prefixed with a lowercase "u", eg. "web_uEtest" (located in "typo3conf/web/uEtest/" or "uMaintest" (located in "typo3conf/uMaintest")(Deprecated concept; Do not create user defined modules any more! Create modules in extensions instead.)
Modules from extensionsCustom modules supplied from extensions are located somewhere inside the extension file space. The extension adds the module to the system by an API call in the "ext_tables.php" file. The API call will add the module key to the $TBE_MODULES array and set an entry in $TBE_MODULES['_PATH'] pointing to the absolute path for the module.
The backend determines if a module is a core/user or extension module by first looking for a path-entry in $TBE_MODULES['_PATHS'] using "[module]_[submodule]" as key (this is also the "name" of the module). If an entry is found, this location is set as the path. Otherwise "t3lib_loadmodules" will look first for the module in the core location ("typo3/mod/") and if not found, then in "../typo3conf/".
In any case, a module is only detected if a "conf.php" file was found in its filepath! This file contains configuration of the module; The module name, script, access criteria, type etc.
When the backend needs to get a list of available modules for a backend user the class "t3lib_loadmodules" is used. This code snippet does the trick:
// Backend Modules:
$loadModules = t3lib_div::makeInstance('t3lib_loadModules');
$loadModules->load($TBE_MODULES);
foreach($loadModules->modules as $mainMod => $info) {
...
}
The array $loadModules->modules contains information about the modules that were accessible; their names, types, sub modules (if any) and the filepath to their scripts (relative to PATH_typo3).
Adding new modules should be done by extensions. The API is easy; in the "ext_tables.php" file of the extension you simply need to add code like this:
For main modules:
if (TYPO3_MODE=='BE') {
t3lib_extMgm::addModule('txtempM1','','',t3lib_extMgm::extPath($_EXTKEY).'mod1/');
}
"txtempM1" is the module key of the main module created. It could appear like this in the menu:
For sub modules:
if (TYPO3_MODE=='BE') {
t3lib_extMgm::addModule('web','txtempM2','',t3lib_extMgm::extPath($_EXTKEY).'mod2/');
}
"web" is the name of the main module (the "Web>" module) and "txtempM2" is the sub-module key. In the menu this module could appear like this:
After such two modules has been added the $TBE_MODULES array could look like this:
Notice that "txtempM1" became a key in the array (main modules) and "txtempM2" was added to the list of modules in the "Web" main module (sub-modules are listed). Also notice that the "_PATHS" key contains an array of file locations of all the modules that are coming from extensions! The last two entries in the list defines the locations of the two modules from our example!
The "conf.php" file is used to configure both Backend Modules and Stand-alone scripts - but not Function Menu modules (which are running inside a backend modules environment!).
The file contains variable and constants definitions according to this scheme:
Variable/Constant | Description | Examples |
|---|---|---|
TYPO3_MOD_PATH | PHP Constant. Defines the path from the main backend folder (where init.php is, PATH_typo3) to the base folder of the module (where the conf.php file is). Used in init.php to determine the sitepath. Very, very important. If this is not correct, your module will not pass init.php without an error. | // Configures path for a core module: define('TYPO3_MOD_PATH', 'mod/web/info/'); // Configures path for an extension module: define('TYPO3_MOD_PATH', '../typo3conf/ext/temp/mod2/'); |
$BACK_PATH | Global Variable. Defines the path "back" to the main folder (PATH_typo3) from the module folder. Used by file references primarily. This is the reverse of "TYPO3_MOD_PATH". | // Configures backpath for a core module: $BACK_PATH = '../../../'; // Configures backpath for extension module: $BACK_PATH = '../../../../typo3/'; |
$MLANG | Global variable containing title, descriptions and icon reference for the backend menu. Applies only to Backend Modules. | $MLANG["default"]["tabs_images"]["tab"] = "moduleicon.gif"; $MLANG["default"]["ll_ref"] = "LLL:EXT:temp/mod1/locallang_mod.php"; |
$MCONF | Global variable containing settings like access criteria, navigation frame script, default submodule and the module name. Applies only to Backend Modules. | // For the "Web" main module: $MCONF['defaultMod'] = 'list'; $MCONF['navFrameScript'] = '../../alt_db_navframe.php'; $MCONF['name'] = 'web'; $MCONF['access'] = 'user,group'; // More common for extension backend modules: $MCONF["access"] = "user,group"; $MCONF["script"] = "index.php"; |
When you create backend modules in extensions there is a tricky thing to be aware of (exception: When using typo3/mod.php to dispatch to a module, see later); The "conf.php" file has to change depending on whether the extension is installed as "global"/"system" extension or "local". The reason is that the TYPO3_MOD_PATH and $BACK_PATH values has to be different when an extension is in the "typo3conf/" folder which is located outside the main TYPO3 directory, PATH_typo3. For instance TYPO3_MOD_PATH could look like "../typo3conf/ext/myext/mod/" for a locally installed extensions while it would be "ext/myext/mod/" for a globally installed extension!
If you install extensions via the Extension Manager this is no problem since the Extension Manager (EM) corrects it before writing the "conf.php" file to the servers file-system. But you need to make your "conf.php" file compatible with this behaviour. Basically that includes:
Insert the two lines with "defined('TYPO3_MOD_PATH'......" and "$BACK_PATH = ....." as the first ones and do not prefix or suffix them with anything; then the EM should be able to detect them.
In the "ext_emconf.php" file of the extension you need to add the directory of the module to the list of backend modules configured in the key $EM_CONF[extension-key]["module"] - otherwise the EM will not know that there is a "conf.php" file to modify!
An example would look like this:
<?php
// DO NOT REMOVE OR CHANGE THESE 3 LINES:
define('TYPO3_MOD_PATH', '../typo3conf/ext/temp/mod2/');
$BACK_PATH='../../../../typo3/';
$MCONF["name"]="web_txtempM2";
$MCONF["access"]="user,group";
$MCONF["script"]="index.php";
$MLANG["default"]["tabs_images"]["tab"] = "moduleicon.gif";
$MLANG["default"]["ll_ref"]="LLL:EXT:temp/mod2/locallang_mod.php";
?>
$MLANG keys | Description |
|---|---|
$MLANG['default']['tabs_images']['tab'] | Icon reference |
$MLANG['default']['ll_ref'] | "locallang" file reference where the keys "mlang_tabs_tab", "mlang_labels_tablabel" and "mlang_labels_tabdescr" defines titles and description text for the module. |
$MLANG[ language-key ]['labels']['tablabel']$MLANG[ language-key ]['labels']['tabdescr']$MLANG[ language-key ]['tabs']['tab'] | Obsolete |
The $MLANG variable contains the icon reference and title / description for a Backend Module. Originally the $MLANG variable defined values for all languages inside the conf.php file. This (obsolete) codelisting shows it:
$MLANG["default"]["labels"]["tablabel"] = "Advanced functions";
$MLANG["default"]["tabs"]["tab"] = "Func";
$MLANG["default"]["tabs_images"]["tab"] = "func.gif";
$MLANG["dk"]["labels"]["tablabel"] = "Avancerede funktioner";
$MLANG["dk"]["tabs"]["tab"] = "Funk.";
$MLANG["de"]["labels"]["tablabel"] = "Erweiterte Funktionen";
$MLANG["de"]["tabs"]["tab"] = "Funk.";
$MLANG["no"]["labels"]["tablabel"] = "Avanserte funksjoner";
$MLANG["no"]["tabs"]["tab"] = "Funk.";
$MLANG["it"]["labels"]["tablabel"] = "Funzioni avanzate";
$MLANG["it"]["tabs"]["tab"] = "Funzione";
...
(OBSOLETE!)
This is still supported for backwards compatibility reasons. Today you need to configure only two lines, one for a "locallang" file reference and one for the icon image:
$MLANG['default']['tabs_images']['tab'] = 'func.gif';
$MLANG['default']['ll_ref']='LLL:EXT:lang/locallang_mod_web_func.php';
The icon reference (line 1) points to an icon image relative to the current directory (normally located there).
The "locallang" file reference in line 2 points to a "locallang"-file which in this case looks like this:
<?php
# TYPO3 CVS ID: $Id: locallang_mod_web_func.php,v 1.5 2004/04/30 16:19:54 typo3 Exp $
$LOCAL_LANG = Array (
'default' => Array (
'title' => 'Advanced functions',
'clickAPage_content' => 'Please click a page title in the page tree.',
'mlang_labels_tablabel' => 'Advanced functions',
'mlang_labels_tabdescr' => 'You\'ll find general export and import functions here. ... sorting of pages.',
'mlang_tabs_tab' => 'Functions',
),
'dk' => Array (
'title' => 'Avancerede funktioner',
'clickAPage_content' => 'Klik på en sidetitel i sidetræet.',
'mlang_labels_tablabel' => 'Avancerede funktioner',
'mlang_labels_tabdescr' => 'Her vil du finde generelle eksport og import funktioner. ... sortering af sider.',
'mlang_tabs_tab' => 'Funktioner',
),
...
);
?>
In this locallang file, some keys are reserved words that point out information related to the "conf.php" file:
mlang_tabs_tab : Title of the module in the menu.
mlang_labels_tablabel : Long title of the module. Used as "title" attribute for menu link and title in the "About modules" list.
mlang_labels_tabdescr : Description of the module (used in "About modules")
$MCONF keys | Description |
|---|---|
$MCONF['name'] | Module name.
Examples (Backend Modules): // Main module (from extension) $MCONF["name"]="txtempM1"; // Submodule of "Web" main module: $MCONF["name"]="web_txtempM2"; // File>Filelist module: $MCONF['name']='file_list'; Example (Stand-alone scripts): // Setting pseudo module name $this->MCONF['name']='xMOD_alt_clickmenu.php'; // Setting pseudo module name for CSM item$MCONF["name"]="xMOD_tx_temp_cm1"; |
$MCONF['script'] | Defines the PHP script which the module is run by. The backend will link to this script when the module is activated. Special keyword is “_DISPATCH” which will indicate that the “typo3/mod.php” script is used to access the module. |
$MCONF['access'] | Defines access criteria by list of keywords. If "admin", only admin-users have access. If "user", "group" or "user,group" then the module is by default inaccessible.
Example: "user,group" - No one (except "admin") has access except the module is specifically added in their user / group profile. This is how the Module selector looks for both backend users and groups:
(For Backend Usergroups you have to enable "Include Access Lists" in order to access the module selector). |
$MCONF['workspaces'] | Defines which workspaces the module is allowed to work under. Empty string means all workspaces. Otherwise this list of keywords can be combined to set access:
|
$MCONF['defaultMod'] | Sub-module key of sub-module to be default for main module. (Only for Main modules) |
$MCONF['navFrameScript'] | If set, the module will become a "Frameset" module and this will point to the script running in the navigation frame. (Only for Main modules) Example (From "Web" main module): $MCONF['navFrameScript']='../../alt_db_navframe.php'; |
$MCONF['navFrameScriptParam'] | GET parameters to pass to the navigation frame script (only Sub-modules of a frameset module). Parameters set for the main module will be inherited to submodules if not overridden. |
$MCONF['shy'] | If TRUE then the module will not be visible in the backend menu or anywhere modules are displayed based on the processing of t3lib_loadModules::load() |
The difference between a stand-alone backend script and a backend module is that the backend module has an API for access control and a menu item. But they share the same requirements for basic initialization.
The most basic configuration for a backend script is setting the TYPO3_MOD_PATH constant and the $BACK_PATH variable before including "init.php". The script "typo3/install/index.php" is an example of this:
define('TYPO3_MOD_PATH', 'install/');
$BACK_PATH='../';
...
require('../init.php');
It is more common to define the TYPO3_MOD_PATH constant and $BACK_PATH variable in a separate conf-file - that is always done for modules and when you are supplying backend scripts from extensions. In such a case the initialization of the backend script will look like this:
unset($MCONF);
require('conf.php');
require($BACK_PATH.'init.php');
...
The file "conf.php" looks like this:
<?php
// DO NOT REMOVE OR CHANGE THESE 3 LINES:
define('TYPO3_MOD_PATH', '../typo3conf/ext/temp/cm1/');
$BACK_PATH = '../../../../typo3/';
$MCONF['name'] = 'xMOD_tx_temp_cm1';
?>
The line defining $MCONF['name'] is optional since the script is a stand-alone script. It might be used as a key for Function menus or otherwise. You can tell that it is a pseudo module name since it is prefixed "xMOD_".
The main point of TYPO3_MOD_PATH and $BACK_PATH is to set the environment so TYPO3 knows the position of the backend script in relation to the main backend folder, PATH_typo3. And the inclusion of "init.php" is required in order to initialize the backend environment and authenticate the backend user. If the script returns from "init.php" it went well and you can be safe that a backend user is logged in (unless configured otherwise).
The conf.php file for a backend module compared to a stand-alone script is different mainly by defining values for $MCONF and $MLANG. This is an example:
<?php
// DO NOT REMOVE OR CHANGE THESE 3 LINES:
define('TYPO3_MOD_PATH', '../typo3conf/ext/temp/mod2/');
$BACK_PATH = '../../../../typo3/';
$MCONF['name'] = 'web_txtempM2';
$MCONF['access'] = 'user,group';
$MCONF['script'] = 'index.php';
$MLANG['default']['tabs_images']['tab'] = 'moduleicon.gif';
$MLANG['default']['ll_ref'] = 'LLL:EXT:temp/mod2/locallang_mod.php';
?>
It doesn't do any difference whether the module is a main- or sub-module. Only the $MCONF['name'] will change in that case.
After the initialization a Backend Module or Stand-Alone script can contain any custom PHP code you wish. However most scripts from the core and system extensions will follow the same model as all other backend modules. An example looks like this:
29: // DEFAULT initialization of a module [BEGIN]
30: unset($MCONF);
31: require('conf.php');
32: require($BACK_PATH.'init.php');
33: require($BACK_PATH.'template.php');
34: $LANG->includeLLFile('EXT:temp/cm1/locallang.php');
36: require_once (PATH_t3lib.'class.t3lib_scbase.php');
37: // ....(But no access check here...)
38: // DEFAULT initialization of a module [END]
...
40: class tx_temp_cm1 extends t3lib_SCbase {... 132: } 133: 134: 135:
136: if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/temp/cm1/index.php']) {
137: include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/temp/cm1/index.php']);
138: }
139:
140:
141:
142:
143: // Make instance:
144: $SOBE = t3lib_div::makeInstance('tx_temp_cm1');
145: $SOBE->init();
146:
147:
148: $SOBE->main();
149: $SOBE->printContent();
Lines 30-32 does the basic initialization
Line 33 includes the backend document template class and language class (provides the $LANG and $TBE_TEMPLATE objects).
Line 34 includes the main "locallang" file for the script
Line 36 includes the base class for the class in the script
Line 37 is where you should do your access check if you want to apply any.
Line 40 to 132 defines the class that is called to create all output from this file. Notice that it extends "t3lib_SCbase" which is normal (but not required!) for backend modules and stand-alone scripts. The "SCbase" class provides some APIs for various things you often need.
Line 136-138 checks for XCLASS extensions of the scripts class.
Finally, line 144-149 instantiates the script class and calls the methods inside to render and output the content.
If the script is a true backend module you should check for module access in line 37 where there is currently just a comment. The access is easily checked by this API function where you simply give the $MCONF array as argument. The function will check what kind of access criteria are in the $MCONF array and then evaluate the situation accordingly. In this case it will exit with a an error message if the user is not logged in.
// This checks permissions and exits if the users has no permission for entry.
$BE_USER->modAccess($MCONF,1);
In case your backend script requires the "admin" user to be logged in it is easy to do a check:
if (!$BE_USER->isAdmin()) die('No access for you...');
See the API for the $BE_USER object for more details.
Please refer to the comments inside of the class file "t3lib/class.t3lib_scbase.php" for more details on a basic framework for backend modules ("script classes"). If you want to start a new backend module you should definitely use the Kicstarter Wizard to do so. It will set up all the basics for you.
With version 4.1 of TYPO3 there is a new and better framework for integration of backend modules into the backend. The main principle is, that all backend modules using this method are called through a central script, “mod.php” in typo3/. This way, we get rid of the trouble with conf.php files in need of modification when installing extensions in local, global and system scopes.
Traditionally, a backend module runs directly from its own “index.php” script (or named otherwise as set up with $MCONF['script']). In order to initialize it must include the typo3/init.php file. Accessing this file requires the module conf.php file to hold the “BACK_PATH” to the typo3/ directory. This will differ depending on where the extension the module is in is installed: locally in typo3conf/ext/ or as a global/system extension. So not only is the conf.php file changed by the Extension Manager when installing extensions, it also makes it very tricky and possibly error-prone to share local extensions between sites with symlinks!
Using mod.php makes it all work differently. Examples in the core can already be seen. For instance the “Tools > User Admin” uses this method now. Instead of directly calling the script “typo3/sysext/beuser/mod/index.php”, the script “typo3/mod.php?M=tools_beuser” is called which will look up (in $TBE_MODULES['_PATHS']) which script is associated with “tools_beuser” and include that. The mod.php script also initializes the backend, includes configuration and so on.
Generally, you can create a module as you always did and then make these changes:
conf.php
Comment out (or remove!) the lines with the TYPO3_MOD_PATH and BACK_PATH definitions. They are not needed anymore ($BACK_PATH is blank for scripts running in typo3/ as mod.php does).Examples:#define('TYPO3_MOD_PATH', 'sysext/beuser/mod/');#$BACK_PATH='../../../';
Set the value of $MCONF['script'] to “_DISPATCH”. This will make sure links to the module are pointed to “mod.php” instead of the real script of the module. This is only needed for modules appearing in the menu as a main- or submodule. Example:$MCONF['script']='_DISPATCH';
ext_emconf.php
Remove the module name from the “module” entry in the array! This entry was what instructed the Extension Manager to modify TYPO3_MOD_PATH and BACK_PATH in the conf.php file of the module during installation of the extension. Since this is not needed any more.
Module script name
Must be “index.php” - but most modules will be that anyway. That's the convension.
index.php (the module script)
In the module script you will have to comment out / remove those lines that are initializing the module:#unset($MCONF);#require ('conf.php');#require ($BACK_PATH.'init.php');#require ($BACK_PATH.'template.php');This is logical because this initialization is now done by mod.php.
Observe that the main script changed! When the module is calling it self, any hardcoded values for the script name (like “index.php?id=123”) must be changed. Now you must call “mod.php?M=[moduleKey]&id=123”. Its suggested you use htmlspecialchars($GLOBALS['MCONF']['_']) as a reference to "thisScript" and add parameters like ."&par=val"
Context Menus: You will of course have to modify the clickmenu-class to call "mod.php?M=[module name here]" where module name most logically is the value of "$MCONF['name']" from the conf.php file.
Also, if you use this method for not-menu-modules, you must call t3lib_extMgm::addModulePath() from ext_tables.php to register the path of the module. Example:
t3lib_extMgm::addModulePath('xMOD_tximpexp',t3lib_extMgm::extPath($_EXTKEY).'app/');
Function Menu modules are integrated in existing backend modules that supports this feature. In the core the modules Web>Info and Web>Function does so. Also Web>Template and even User>Taskcenter does!
Function Menu modules are accessed through the function menu of the host module:
In this example the Web>Functions module is the host backend module and the selector box in the upper right corner shows the two Function menu modules attached to Web>Functions. It turns out that the function menu module "Wizards" supports even another level of externally attached scripts - a "second level Function Menu module". The API for adding elements to the second level is the same as for the first.
Function Menu modules live in the environment of the host backend module. Therefore they have no conf.php files etc. All they do is to supply a PHP class which is called when they need to be activated. Like any other module they have to render the content and return it then.
Attaching Function Menu modules to a host backend module is done by adding some values to an array in the global scope. To make this easy there is API function calls to do that which you should use. To create a Function Menu on the first level you would include this code in the "ext_tables.php" file of the extension:
if (TYPO3_MODE=='BE') {
t3lib_extMgm::insertModuleFunction(
'web_func',
'tx_temp_modfunc1',
t3lib_extMgm::extPath($_EXTKEY).'modfunc1/class.tx_temp_modfunc1.php',
'LLL:EXT:temp/locallang_db.php:moduleFunction.tx_temp_modfunc1'
);
}
If you want to insert it on the second level this would be used (for the Wizards example above):
if (TYPO3_MODE=='BE') {
t3lib_extMgm::insertModuleFunction(
'web_func',
'tx_temp_modfunc2',
t3lib_extMgm::extPath($_EXTKEY).'modfunc2/class.tx_temp_modfunc2.php',
'LLL:EXT:temp/locallang_db.php:moduleFunction.tx_temp_modfunc2',
'wiz'
);
}
Notice the only difference; The addition of the fifth argument in the function call pointing to the first level Function Menu item.
The Function Menu module code is found in a class in the scripts pointed to in the configuration. Such a class extends the class "t3lib_extobjbase" which is designed to handle all the basic management of a Function Menu module.
A basic framework for a Function Menu module looks like this:
1: require_once(PATH_t3lib."class.t3lib_extobjbase.php");
2:
3: class tx_temp_modfunc1 extends t3lib_extobjbase {
4: function modMenu() {
5: global $LANG;
6:
7: return Array (
8: "tx_temp_modfunc1_check" => "",
9: );
10: }
11:
12: function main() {
13: // Initializes the module. Done in this function because we may need to re-initialize if data is submitted!
14: global $SOBE,$BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS;
15:
16: $theOutput.=$this->pObj->doc->spacer(5);
17: $theOutput.=$this->pObj->doc->section($LANG->getLL("title"),"Dummy content here...",0,1);
18:
19: $menu=array();
20: $menu[]=t3lib_BEfunc::getFuncCheck($this->pObj->id,"SET[tx_temp_modfunc1_check]",$this->pObj->MOD_SETTINGS["tx_temp_modfunc1_check"]).$LANG->getLL("checklabel");
21: $theOutput.=$this->pObj->doc->spacer(5);
22: $theOutput.=$this->pObj->doc->section("Menu",implode(" - ",$menu),0,1);
23:
24: return $theOutput;
25: }
26: }
27:
28:
29:
30: if (defined("TYPO3_MODE") && $TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["ext/temp/modfunc1/class.tx_temp_modfunc1.php"]) {
31: include_once($TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["ext/temp/modfunc1/class.tx_temp_modfunc1.php"]);
32: }
From the code you might be able to figure out that the host backend module is available as the object reference $this->pObj. In this code listing it is used to access the document template object for rendering the output.
If you want to create a new backend main- or sub-module, create a new CSM item or a Function Menu module the best way to start yourself up is to use the Kickstarter. In a few clicks you have configured the basic framework and you get all the tedious and error prone work done for you automatically. Immediately you can begin to concentrate on the coding of your backend application.
In the Kickstarter, the menu items for backend scripts are found here:
For details on actual extension programming (which will also cover backend module programming), please refer to some of the extension programming tutorials around.
Most scripts in TYPO3 expect to be executed from a web browser. However you might need to create a PHP script which is executed in a Unix shell as a cronjob. In itself PHP is capable of that as long as PHP was also compiled as a binary (typically “/usr/bin/php”) but you need to do some tricks in order to initialize TYPO3s backend environment.
The greatest challenge is to make the script recognize its own path. This is necessary for all includes afterwards. It seems that the path of the script is available as the variable $_ENV['_'] in most cases. However it changes value depending on how you call the script. In order to make life easy for our programming we decide that the script must always be executed by its absolute path. So “./myphpshellscript.phpsh” will not work, but “/abs/path/to/typo3conf/ext/myext/ myphpshellscript.phpsh” will.
Note about FreeBSD: It has been reported (by Rainer Kuhn, punkt.de – thanks) that on FreeBSD the path is not available in $_ENV['_'] but can be extracted from $_SERVER['argv'][0]. Generally there are not enough experience and knowledge about this issue to state something final, but for now we suggest a fall back solution as seen below where $_ENV['_'] is tested and if not found, falls back to $_SERVER['argv'][0]
To set up a PHP shell script that initializes the TYPO3 you create a file with the framework here:
1: #! /usr/bin/php -q
2: <?php
3:
4: // *****************************************
5: // Standard initialization of a CLI module:
6: // *****************************************
7:
8: // Defining circumstances for CLI mode:
9: define('TYPO3_cliMode', TRUE);
10:
11: // Defining PATH_thisScript here: Must be the ABSOLUTE path of this script in the right context:
12: // This will work as long as the script is called by it's absolute path!
13: define("PATH_thisScript", $_ENV['_'] ? $_ENV['_'] : $_SERVER['_']);
14:
15: // Include configuration file:
16: require(dirname(PATH_thisScript).'/conf.php');
17:
18: // Include init file:
19: require(dirname(PATH_thisScript).'/'.$BACK_PATH.'init.php');
20:
21:
22:
23: # HERE you run your application!
24:
25: ?>
Line 1 will call the PHP binary to parse the script (just like a bash-script).
Line 9 defines “CLI” mode for TYPO3. When this is set browser checks are disabled and you can initialize a backend user with the name corresponding to the module name you set up in the conf.php file. See later.So you MUST set the CLI mode, otherwise you will get nowhere.
Line 13 defines the absolute path to this script! If for some reason the environment where the script is run does not offer this value in $HTTP_ENV_VARS['_'] you will have to find it elsewhere and manuall insert it. There seems to be no general solution for this problem.
Line 16 includes a configuration file build exactly like conf.php files for backend modules in extensions. (In fact this script must be registered as a backend module)
Line 19 includes the backend “init.php” file.
After these lines you have a backend environment set up. The browser check was bypassed and a backend user named like $MCONF['name'] was initialized. If something failed init.php will exit with an error message. You can also execute the script with the “status” command (eg. “/abs/path/to/typo3conf/ext/myext/ myphpshellscript.phpsh status”) to see which user was initialized, which database found and which path the script runs from. This indicates the success of the initialization.
In the conf.php for the shell script you enter TYPO3_MOD_PATH and backend as usual.
The $MCONF variable is also set with the module name. This must be prefixed “_CLI_” and then a unique module name, eg. based on the extension key. The value of $MCONF['name'] in lowercase will be the backend username that is initialized automatically in init.php for your sessions. This is hardcoded.
An example conf.php file looks like this:
0: // DO NOT REMOVE OR CHANGE THESE 3 LINES:
1: define('TYPO3_MOD_PATH', '../typo3conf/ext/user_fi_io/cronmod/');
2: $BACK_PATH = '../../../../typo3/';
3: $MCONF['name'] = '_CLI_userfiio';
The backend user is then named “_cli_userfiio”:
Notice: You must make sure to enter the path of the “shell script module” in the ext_emconf.php scripts array (key “module”). If you do this, the extension manager will automatically fix the paths in the conf.php file when the extension with your script is installed in either global / local scopes. This is no different from ordinary backend modules which need the same attension!
Any script configured like this can be run with the “status” argument and you will see whether the initialization went well:
agentk@rock:~$
agentk@rock:~$ /var/www/typo3/dev/3dsplm_live/typo3conf/ext/user_fi_io/cronmod/index.phpsh status
Status of TYPO3 CLI script:
Username [uid]: _cli_userfiio [17]
Database: t3_3dsplm_live
PATH_site: /var/www/typo3/dev/3dsplm_live/
agentk@rock:~$
Since you are not running the script from a web browser all backend operations that work on URLs or browser information will not produce correct output. There simply is no URL to get if you ask “t3lib_div::getIndpEnv()” for “TYPO3_SITE_URL” or so!
You cannot expect to save session data for the authenticated backend user since there is no session running with cookies either. You should also remember that all operations done in the script is done with the permissions of the “_cli_*” user that was authenticated. So make sure to configure the user correctly. The “_cli_” user is not allowed to be “admin” for security reasons.