All page names need to be in English.
en da  de  fr  it  ja  km  nl  ru  zh

Sylvain:Full Website Setup/Extension Programming

From TYPO3Wiki
Jump to: navigation, search

notice - This information is outdated

While some details may still apply in specific situations, this page was written for packages of TYPO3 that are no longer current.

<<< Back to Sylvain:Full_Website_Setup
Main editor: Sylvain
Status: Draft

Goal definition

This article is related to PHP programming in the Typo3 environment. The goal is not to make a full TYPO3 plugin, but a working extension for a special purpose. This may result in an working, uploadable, plugin, but it's not the main goal here.

The principles presented here may be used in any other related documentation about extension writing.

What I want is an image upload system, so certain people can change part of their personal content on the site.

  • The editable content on the page is composed of 3 small pictures. The person to whom the images belong, is restricted to change only his pictures and not any other content part of the page.
  • This content editing restriction may be extended in the future.
  • The site administrator who is not a TYPO3 admin, must be able to find rapidly who has not updated his picture for a long time.

So we must provide 2 things:

  1. A restricted image upload and update system.
  2. A listing for the site administrator.

Restricted content access

Solution approach

  1. using a TYPO3 subpage to store only the pictures, give the user access to this page and load the picture in the final destination page.
  2. create a new type of content plugin which allows image uploads.

Testing solution 1

My objective is to use as much TYPO3 configuration as possible before coding anything.

Current Status: stoped, delayed (09:36, 7 Sep 2004 (CEST))

This solution involved too much coding to make the site available in the proposed deadline. As you can read in this article, TYPO3 doesn't support the needed level of permission / interface control and needs much more coding in its internal source code (core) before making it available. So I start studying my second solution.

But I'm very interseted in the first approach, and will come back to it later.


  • Currently I can't limit the user to be locked to only one content record. The user can still create a new content record on the page, and can also delete the image content. The last thing is very bad because the content is linked with the Insert Records content, which will no longer work in the real page if the image content is deleted.

The following screen shot shows two pictures of the TYPO3 BE. The goal is to remove unwanted BE control item, circled in red in the pictures.

  • top picture, The Columns frame, before editing the content.
  • bottom, the item currently in edit mode (already simplified by page TSconfig)

Remove red cercled item.png

Solved problems

  • The cache is not refreshed when the content is updated on the « insert content » record.
    • See the code in page TSconfig, below.

Controling BE display can not be done with permissions alone, but permissions do help a lot. For this purpose I have to study the internals of TYPO3 and walk through number of manuals. I'm going to write down the path I take to get the BE display exactly how I want it, not allowing the BE to impose on me what can or cannot be displayed. :-)

The path to the full control of the BE

Creating the 3 pictures content, group and user

  • step for creating the new content
    1. creation a new subpage of the page where the content is visible. This page is at level3 and is not accessible be the menu.
    2. creating an image content record (Type:Image)in the new subpage.
    3. uloading the 3 pictures in the content record.
    4. inserting a new content record (Type:Insert records) in the real page pointing the the new previous created record.
  • creating the user and group with limited access
    1. create the file mount
      • create new record
      • Filemount
      • LABEL: set the name you want
      • PATH: path_to/upload_folder/
      • BASE relative ../fileadmin/
      • create the appropriate folder on the web server fileadmin/path_to/upload_folder/
    2. create a new Backend usergroup
      • check Include Access Lists:
      • Modules:
        • Web
        • Web>Page
      • Tables (modify):
        • Pagecontent
      • File Mounts:
        • The file mount where users can upload their pictures.
    3. create a new Backend user
      • Group: set the group created above
      • Mount from groups: check DB Mounts and File Mounts
      • DB Mounts: set the page where we want to lock the user
      • File Mounts: leave empty, this is set in the group
      • Fileoperation permissions: check only Files: Upload,Copy,Move,Delete,Rename,New,Edit
      • TSconfig: no value yet
  • Changing page owner
    1. chose Access module mode
    2. select the subpages which contains only the 3 pictures
    3. edit the page ownership
    4. change Owner: to the new user created above

Customizing BE for restricted user

With this setup the user created can still be disturbed by [have access to?] some BE action buttons. We don't want to allow him to add any content. He must be restricted to edit only 1 content element, nothing else.

Using the following documentation: User TSConfing in TSConfig reference manual you can apply some change on the usergroup and remove part of the BE interface.

BE page rendering

Here is some PHP code exploration on the topic of BE rendering. This information is related to TYPO3 3.7.0 the development version from CVS.

The source file involved in BE rendering is the same, but the changes implied here are too internal. So I do them on the most recent source snapshot.

Page Content: Columns Frame

Source file: typo3/sysext/cms/layout/db_layout.php

The entry point function is SC_db_layout::renderQuickEdit() which renders the Quick Edit mode, as its name suggests, and SC_db_layout::renderListContent() for any other view rendering.

The intersting part of the function concerns the creatation of the $toolBar ToolBar.png. The code is different in the 2 functions.

First, let's examine the toolBar generated code in renderListContent(). For the purpose of this web site we would like to limit the editor (BE author) to Columns mode.

When rendering, the toolBar is created first with all its icons and links without any admin control over which icons should be displayed to a user or a group.

Here is sample of code (near line 1039):

         // New content element
      $toolBar.='<a href="'.htmlspecialchars('db_new_content_el.php?id='.
'width="16" height="12"').' vspace="2" hspace="1" align="top" title="'.
$LANG->getLL('newContentElement',1).'" alt="" />'.
   // Move page:
      $toolBar.='<a href="'.htmlspecialchars($BACK_PATH.
'width="11" height="12"').' vspace="2" hspace="2" align="top" title="'.
$LANG->getLL('move_page',1).'" alt="" />'.

The genereted output looks like (in one full line, truncated for this document):

<a href="db_new_content_el.php?id=28&sys_language_uid=0&
<img src="../../../gfx/new_record.gif" width="16" height="12" vspace="2" hspace="1"
 align="top" title="Create new content element" alt="" /></a>
<a href="../../../move_el.php?table=pages&uid=28&
<img src="../../../gfx/move_page.gif" width="11" height="12" vspace="2" 
hspace="2" align="top" title="Move page" alt="" /></a>	

We have no ability to control the display of the toolBar, it is inserted in the page output without conditional testing.

I propose the following simple solution (brute force regexp solution for hacker).

I'm going to insert a Hook in the code just before the toolBar is sent to the page output. Here the hook will allow the developper to take control of the generated toolBar.

Could be great to consider putting toolBar creation logic/rights in a table and then fill the toolBar in an eval loop ?

Let's go back to the insertion on the Hook entry point.

First create the hook Array in the whole class, because we have 2 functions, at least, involved.

Modified code from SC_db_layout::init() (start at line 254)

         // First prepare user defined objects (if any) for hooks which extend
         // this class to control BE output.
         // Currently: hook a for the method renderListContent()
      $this->hookObjectsArr = array();
$TYPO3_CONF_VARS['SC_OPTIONS']['typo3/sysext/cms/layout/db_layout.php']['renderListContent'])) {
         foreach (
 as $classRef) {
            $this->hookObjectsArr[] = &t3lib_div::getUserObj($classRef);

Next we create the hook entry point in the code itself, in the function renderListContent() at line 1060)

        // Hook: renderListContent:toolBarRenderPreProc
        // What about order in hook call ? If a hook procedure would like to
        // totaly disable the toolBar by emptying it.
     $_params = array('toolBar' => &$toolBar, 'parentObj' => &$this);
     foreach($this->hookObjectsArr as $hookObj) {
        if (method_exists($hookObj, 'toolBarRenderPreProc')) {

Just before the HTML is sent to the output string, by the following code:

         // Wrap the toolbar into a table:
         <table border="0" cellpadding="0" cellspacing="0" class="bgColor4">

Page content element rendering

garbage icon ! sysext/cms/layout/class.tx_cms_layout.php:1567

  • getTable_tt_content()
    • tt_content_drawColHeader()
    • tt_content_drawHeader()


               // Delete
            $out.='<a href="'.htmlspecialchars(
'" onclick="'.htmlspecialchars('return confirm('.
'width="11" height="12"').
' title="'.$GLOBALS['LANG']->getLL('deleteItem',1).'" alt="" />'.'</a>';

localconf.php and $TYPO3_CONF_VARS

Editing content

Source file: typo3/alt_doc.php?returnUrl=URL_HERE&edit[tt_content][23,]=edit

User TSconfig used in the group

# ref:

# 0 QuickEdit
# 1 Columns
# 2 Languages
# 3 Page information {
  # disabling 0 = 0, QuickEdit (QE) doesn't work
  0 = 0
  2 = 0
  3 = 0

# This fixes the problem described above = 0

# display only normal column
mod.SHARED.colPos_list = 0

# hide some element
mod.web_layout  {
  # Does not hide all create record buttons, why ?
  noCreateRecordsLink = 1
  disableSearchBox = 1
  disableAdvanced = 1
  editFieldsAtATime = 1
  disableNewContentElementWizard = 1

mod.web_list {
  noCreateRecordsLink = 1

# from:
options {
  # partialy disable the delete, Ok in columns, but still 
  # here in QuickEdit
  disableDelete = 1
  disableDelete.tt_content = 1
  # remove the popup menu in the middle frame
  pageTree.disableIconLinkToContextmenu = 1
  saveDocNew = 0
  # Doesn't hide anything, the history icon is still here (Columns + QE)
  showHistory = 0
  showHistory.pages = 0
  showHistory.tt_content = 0

Page TSconfig

# disable editing of Content Title, changing Content Type, and image orientation.

# force clear cache of the related page
TCEMAIN.clearCache_pageSiblingChildren = 1

Testing solution 2

This solution involves the programming of the frontend mechanism to allow the restricted content editing. User doesn't have any acces to the BE.

This starts simply with the standard login form provided by TYPO3.

  • Create a new page in which the login and the editing will happen.
  • This page should not be visible in the menu, but can be accessed by the small edit icon on the photograph page.
  • When the user clicks the edit icon, he is forwarded to the update page.
  • Here we have a login form and the script element which manages the upload process.
  • The script element is access restricted and will not be shown if the FE user as no permission to see it.

For our purposes we doesn't need to start and extension right now. So let's go right in to the code. We will wrap it in an extension later if needed.

Setup the update page in the BE

  • create a sysFolder which will hide the page from the menu. name = «Update Area»
  • create a new page, name = Update your photo
  • create the contents:
    • Text, Access: Hide at login, The message which invites the user to log in.
    • Login, the login form
    • Script, the script entry point, CODE:

We now need write the TypoScript in the template to link the script content record with its php code for rendering.

Edit the template Setup and add the following code:

Some documenation:

Script PHP programming

So we start coding. A good place to put our code right now is in the fileadmin/ folder. We create a subfolder script/ for our code. As described in Templates, TypoScript & beyond in the section «HELLO WORLD - from our own PHP-class»

So we have :

|-- _temp_
|-- photographes
|   `-- photos
|-- script       <-- here
|-- template
|   |-- css
|   |-- images
|   `-- script
`-- user_upload
   `-- _temp_

Some extension reference

  • Check Upload Folder - (ge_checkupload) Delete all files with no references in the upload folder.
  • MOC Fileshare manager - (moc_filemanager) A collection of frontend plugins for filesharing based of typo3 group permissions.

Some references about BE cutsomization

Admin content displayer

Using the Kickstarter we want to create a BE user module which shows the image content used by other user [ed:created by another user?].

You can learn the Kickstarter basics with the video episode 3 of Extension Manager & Kickstarter

Using the Kickstarter

The Kickstarter is a TYPO3 extension which will help to dump the code base of any type of extension.


  1. Ext Manager
    • install the Kickstarter wizard if needed
  2. Make new extension
  3. Click the + General info
    • Title: = Admin content lister
    • Description: = List the content belonging to other user in the BE
    • Category: = Backend Modules
    • State = Alpha (very initial development)
    • Dependencies (comma list of extkeys): [empty]
  4. Right Update button, the left one should do the same thing
  5. Click the + Backend Modules
    • Enter a title for the module: = User Changes
    • Enter a description: = Allow the supervisor to follow user change on their content
    • Enter a tab label (shorter description): = See user changes on their content
      • will be displayed when you left your mouse over the name in the BE left frame
    • Sub- or main module? Sub in User-Module
    • Position in module menu? Bottom (default)
  6. Click Update button
  7. Click the + Setup languages if you have any language which you can already support. Mine supports French too.
  8. Enter extension key: = ose_content_lister, See here about extension key
  9. Click Update button
  10. Click View Result

I got:

Filename:               Size:    
ext_icon.gif            124      
ext_tables.php          192      View 
doc/wizard_form.dat     1.6 K    
doc/wizard_form.html    23 K     
mod1/clear.gif          46       
mod1/conf.php           384      View 
mod1/index.php          6.3 K    View 
mod1/locallang.php      1.1 K    View 
mod1/locallang_mod.php  1.3 K    View 
mod1/moduleicon.gif     82    

Next step, write it to the webserver:

  1. Write to location: Chose the local location
  2. Click Write button

Then your extension should be writen into the folder typo3conf/ext/ose_content_lister/. ose_content_lister is the extension key chosen. The folder contains the folling files:

|-- doc
|   |-- wizard_form.dat
|   `-- wizard_form.html
|-- ext_emconf.php
|-- ext_icon.gif
|-- ext_tables.php
`-- mod1
    |-- clear.gif
    |-- conf.php
    |-- index.php
    |-- locallang.php
    |-- locallang_mod.php
    `-- moduleicon.gif

And it should do pretty much nothing. Even more, the extension is not yet installed. So install your extension with the extension manager. It should be available in the « Available extension to install».

Then refresh all your navigator frames if needed (needed for mozilla 1.7). The extension should apprear in the left frame at the bottom of the User modules section.

Hitting the User Changes link being a BE TYPO3 admin, you'd see:

Ex BE module empty.png

Jump into the PHP code

To do something real with an extension some TYPO3 basic programming (API knowledge) is needed.

We can find some usefull information in these documents: