Skip to end of metadata
Go to start of metadata
A chain is a registered hook in the code, which executes external callbacks with a given amount of parameters to affect the systems behaviour.

Chains in CONTENIDO are important to inject custom functionality into the system without changing the core files. This is important, because the system then will be easier to update.

Adding chains

Standard CONTENIDO chains are located at directory contenido/includes/chains. To add your own chains you have to include and initializing them at configuration files at your environment config directory. We go trough it step by step.

First create your Chain and save it to /contenido/includes/chains/:

File: include.chain.frontend.cat_businessaccess.php
<?php

defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');

function cecFrontendCategoryBusinessAccess($name)
{
    global $cfg;
    // your code stuff goes here
	$data =  "Your Name is:".$name;
    return $data;
}

Next we load the chain. Go to your config-folder (normaly at data/production). At config.chains.load.php you define all chains available in the system. For example, we add a new chain-Function with name cecFrontendCategoryBusinessAccess:

File: config.chains.load.php
<?php

defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');

cInclude('includes', 'chains/include.chain.frontend.cat_backendaccess.php');
cInclude('includes', 'chains/include.chain.frontend.cat_access.php');
cInclude('includes', 'chains/include.chain.content.createmetatags.php');
cInclude('includes', 'chains/include.chain.frontend.createbasehref.php');
cInclude('includes', 'chains/include.chain.content.indexarticle.php');
cInclude('includes', 'chains/include.chain.template.parsetemplate.php');
cInclude('includes', 'chains/include.chain.frontend.cat_businessaccess.php');   //here we include our new Chainfile

// get cec registry instance
$_cecRegistry = cApiCecRegistry::getInstance();
$_cecRegistry->addChainFunction('Contenido.Frontend.CategoryAccess', 'cecFrontendCategoryAccess');
$_cecRegistry->addChainFunction('Contenido.Frontend.CategoryAccess', 'cecFrontendCategoryAccess_Backend');
$_cecRegistry->addChainFunction('Contenido.Content.CreateMetatags', 'cecCreateMetatags');
$_cecRegistry->addChainFunction('Contenido.Frontend.BaseHrefGeneration', 'cecCreateBaseHref');
$_cecRegistry->addChainFunction('Contenido.Content.AfterStore', 'cecIndexArticle');
$_cecRegistry->addChainFunction('Contenido.Template.BeforeParse', 'cecParseTemplate');
$_cecRegistry->addChainFunction('Contenido.Frontend.BusinessAccess', 'cecFrontendCategoryBusinessAccess');    //here we add our Chain to the cecRegistry

Now our Chain is ready to use.

Here an example to be used in your module code:

$_cecIterator = cRegistry::getCecRegistry()->getIterator('Contenido.Frontend.BusinessAccess');

if ($_cecIterator->count() > 0) {
    while (false !== $chainEntry = $_cecIterator->next()) {
        $businessName = $chainEntry->execute("Fritz Box");
    }
}

When does it make sense to use chains for CONTENIDO?

The use of CECs within CONTENIDO makes sense if the base functionality of CONTENIDO could be changed in a project without rewriting code of CONTENIDO itself. If the CEC is placed at the correct location, each project can access these chains.

What are the restrictions for chains?

CECs should only be used for data manipulation. They should not be used to manipulate GUI elements, as the GUI stuff within CONTENIDO will be changed soon.

List of existing chains

You can't use any of these chains for your purpose?

If you can not use any of these chains listed below you can request a new and it is maybe implemented in the next version. Please visit the chain request thread in our forum.

CEC HookDescriptionParametersSince version
Contenido.Content.AfterStore

This chain is called after one or more content entries are stored.

It could be used as hook for indexing articles.

Array $articleIds with keys idclient, idlang, idcat, idart, idcatlang, idartlang.4.9.0
Contenido.Content.conGenerateCodeThis chain is called in function conGenerateCode after code is created. 4.9.0
Contenido.Content.CopyArticleThis chain is called everytime when an article is duplicated.Integer with articleId of original article, integer with articleId of duplicated article4.9.0
Contenido.Content.CreateArticleLinkThis chain is called when a frontend link to an article will be created.Integer idart, integer idcat4.9.0
Contenido.Content.CreateCategoryLinkThis chain is called when a frontend link to a category will be created.Integer idcat4.9.0
Contenido.Content.CreateMetatags

This chain is used to build up an user defined metatag array.

Adds, modifies or removes meta tags of an article

Array with all meta tags

4.9.0
Contenido.Content.CreateTitletagThis chain is used to build a user defined title element. 4.9.0
Contenido.Content.DeleteArticleThis chain is called when article is deleted.String idart4.9.0
Contenido.Content.IndexArticle

This chain is called search index generation.

Since CONTENIDO 4.9.5 you can configure at config.misc.php configuration file ($cfg['search_index']['excluded_content_types']) all content types that you want to be excluded from indexing.

Array with all article ids ($articleIds)4.9.0
Contenido.Content.SaveContentEntry

This chain is called before a single content entry is saved.

It allows to modify the given content to be saved which will then be returned by this function.

Integer $idartlang, integer $type, integer $typeid, string $value4.9.0
Contenido.Upload.UploadPreprocessThis chain is called everytime a file is uploaded.String with temporary filename you have to use to process, string with new filename the uploaded file will be stored as4.9.0
Contenido.Upload.UploadPostprocessThis chain is called everytime after a file is uploaded and stored in its final position.String with full path and name of the uploaded file4.9.0
Contenido.ArticleCollector.ArticlesThis chain is called when article collector loads articles.Array $data, an associative array with idart of current article and loaded articles4.9.5
Contenido.Frontend.CategoryAccessThis chain is called everytime the user tries to access a protected category.Integer languageId, integer idcat, string userId4.9.0
Contenido.ArticleCategoryList.ListItemsThis chain is called when the category list in Content -> Articles will be build.  
Contenido.ArticleList.ColumnsThis chain is used to process the columns of the article list.Array in the format $key => $description 
Contenido.ArticleList.ActionsThis chain is used to process the actions for articles.Array in the format $key => $description 
Contenido.ArticleList.RenderColumnThis chain is used to render a single column for a specific article.Integer idcat, integer idart, integer idartlang, string with column key to render 
Contenido.ArticleList.RenderActionThis chain is used to render a single action for a specific article.Integer idcat, integer idart, integer idartlang, string with action key to render 
Contenido.CategoryList.ColumnsThis chain is used to process the columns of the category list.Array in the format $key => $description 
Contenido.CategoryList.RenderColumnThis chain is used to render a single column for a specific category.Integer idcat, string with column key to render 
Contenido.Frontend.AllowEdit

This chain is used when an article is about to be edited.

It can be used to prevent users to edit certain articles, e.g. for workflows or for special types of articles.

Integer with languageId, integer idcat, integer idart, string with authentification of the user4.9.0
Contenido.Permissions.User.AreasThis chain returns all areas which will appear in the user rights management.  
Contenido.Permissions.User.GetAreaNameThis chain returns the localized area name for a technical area name.String with technical area name 
Contenido.Permissions.User.GetAreaEditFilenameThis chain returns the filename required for the permission editor.String with technical area name 
Contenido.Permissions.FrontendUser.AfterDeletionThis chain function is called after a frontend user has been deleted from the database.Integer with id of deleted frontend user 
Contenido.Permissions.FrontendUser.BeforeStore

This chain function is called before storing a frontend user.

It allows for easier data manipulation for extended frontend users with interdependend attributes.

Array 
Contenido.Permissions.Group.AreasThis chain returns all areas which will appear in the group rights management.Array with all unique technical area names which should appear in the group rights management 
Contenido.Permissions.Group.GetAreaNameThis chain returns the localized area name for a technical area name.String with technical area name 
Contenido.Permissions.Group.GetAreaEditFilenameThis chain returns the filename required for the permission editor.String with technical area name 
Contenido.Article.RegisterCustomTabThis chain registers a custom tab into the main article subnavigation (Overview/Properties/Configuration/Editor/Preview/***).  
Contenido.Article.GetCustomTabProperties

This chain is called when the properties of a custom tabs need to be aquired.

It is used to build the final URL for the editor.

String with technical area name 
Contenido.Frontend.BaseHrefGenerationThis chain is called everytime the BASE HREF tag is generated.BASE HREF URL from CONTENIDO configuration array4.9.0
Contenido.Upl_edit.DeleteThis chain function is called after each single upload file has been deleted.int $idupl, string $dirname, string $filename 
Contenido.Upl_edit.DeleteBatchThis chain function is called after one or more upload files have been deleted.array:cApiUpload $uploads 
Contenido.Upl_edit.RowsThis chain is used to process the rows of the upl-details list.Array with row-list for upl-details 
Contenido.Upl_edit.RenderRowsThis chain is used to render a single column for a specific article.Integer with uploaded fileId, string with file directory, string with filename, string with row-key to render 
Contenido.Upl_edit.SaveRowsThis chain is called everytime when upl-details is saved.Integer with uploaded fileId, string with file directory, string with filename 
Contenido.Action.str_newtree.AfterCallThis chain is called while executing code for action "str_newtree", see table con_action.

Assoziative array with several values

4.9.0
Contenido.Action.str_newcat.AfterCallThis chain is called while executing code for action "str_newcat", see table con_action.

Assoziative array with several values

4.9.0
Contenido.Action.str_renamecat.AfterCallThis chain is called while executing code for action "str_renamecat", see table con_action.

Assoziative array with several values

4.9.0
Contenido.Action.str_moveupcat.AfterCallThis chain is called while executing code for action "str_moveupcat", see table con_action.Integer idcat4.9.0
Contenido.Action.str_movedowncat.AfterCallThis chain is called while executing code for action "str_movedowncat", see table con_action.Integer idcat4.9.0
Contenido.Action.str_movesubtree.AfterCallThis chain is called while executing code for action str_movesubtree, see table con_action.

Assoziative array with several values

4.9.0
Contenido.Action.con_saveart.AfterCallThis chain is called while executing code for action con_saveart, see table con_action.array $newdata, array $oldata4.9.0
Contenido.Article.conMoveArticles_LoopThis chain is called while looping articles which will be moved for the time management function, see conMoveArticles().

Assoziative array of actual recordset

4.9.0
Contenido.Article.conCopyArtLang_AfterInsertThis chain is called after execution of the insert statement during duplication of an article, see conCopyArtLang().Assoziative array of actual recordset4.9.0
Contenido.Article.conSyncArticle_AfterInsertThis chain is called after execution of the insert statement during a article sync, see conSyncArticle().Assoziative array4.9.0
Contenido.Category.strSyncCategory_LoopThis chain is called while looping categories which will be synchronized, see strSyncCategory().Assoziative array of actual inserted con_cat_lang recordset4.9.0
Contenido.Category.strCopyCategoryThis chain is called after a old category was copied to new category.Assoziative array of several objects (oldcat, newcat, newcatlang)4.9.0
Contenido.Category.strRenameCategory Assoziative array of several objects (new/old category name and new/old category alias s)4.9.0
Contenido.Category.strRenameCategoryAlias Assoziative array of several objects (new/old category alias4.9.0
Contenido.Frontend.AfterLoadPluginsThis chain is called in front_content.php and provides a possibility to execute userdefined functions after plugins are loaded. 4.9.0
Contenido.Frontend.HTMLCodeOutputThis chain is called in front_content.php after the output of the page was buffered.string $htmlCode4.9.0
Contenido.Frontend.PreprocessUrlBuildingThis chain is called by Contenido_Url->build() method an provides a way to modifiy the parameter which will be passed to the configured Url Builder.Assoziative array of parameter beeing achieved as arguments to Contenido_Url->build()4.9.0
Contenido.Frontend.PostprocessUrlBuildingThis chain is called by Contenido_Url->build() method an provides a opportunity to modifiy a url created by configured Url Builder.String with created url by Url Builder4.9.0
Contenido.Template.BeforeParseThis chain is called before parsing a template in cTemplate.string $template, cTemplate $template4.9.3
Contenido.Article.conFlagOnOfflineThis chain is called after articles flagged on or offline.array $ids, idartlangs array4.9.11
Contenido.Content.CopyToVersionThis chain is called after article copied to version.array $idart, $idlang4.9.11
Contenido.Article.DeletecontentTypeThis chain is called after raw data deletion in article.array with values idcontent, idart, idlang, idartlang4.9.13
ContenidoPlugin.UrlShortener.BeforeEditThis chain is executed if url shortener is installed and short url changed.$shortUrlOld, $shortUrlNew4.9.11
ContenidoPlugin.UrlShortener.BeforeRemoveThis chain is executed if url shortener is installed and short url before remove.$shortUrl4.9.11
ContenidoPlugin.UrlShortener.AfterCreateThis chain is executed if url shortener is installed and short url is created.$shortUrl4.9.11
ContenidoAction.con_meta_saveart.AfterCallThis chain is called after metadata of article are saved.$idart, $newData, $oldData4.9.0
Contenido.Article.ConMakeCatOnlineThis chain is called after category set to online.array $data4.9.7
Contenido.Article.ConMakeStartThis chain is called after article set to online.array $data4.9.7
Contenido.Backend.ConMetaEditFormAdditionalRowsThis chain added additional rows to the article edit form.$idart, $idlang, $idclient, $disabled4.9.0
Contenido.AjaxMain.CustomCallThis chain is called if custom ajax mode is selected.$_REQUEST['method']4.9.11
Contenido.Permissions.FrontendUser.BeforeStoreThis chain is called before storing a frontend user.array $varArray4.9.11
Contenido.WYSIWYG.LoadConfigurationThis chain is called after the complete configuration. 4.9.7
Contenido.Article.ConMakeOnlineThis chain is called when article switch to online.$idart, $lang, $online4.9.7
Contenido.Action.con_deleteart.AfterCallThis chain is called when article is deleted.$idart4.9.13
Contenido.Backend.AfterArticleLinkThis chain is called after article link generation in article properties. 4.9.13

5 Comments

  1. Verfügbare Chains wurden früher in der Chain-Konfigurationsdatei "/contenido/includes/config.chains.php" definiert. Die Datei gibt es nicht mehr. Ein gibt einen neuen ordner /web/contenido/includes/chains. In den Chains dort stehen aber nur functionen.

    Unter /docs/techref/plugins/Contenido Extension Chainer.pdf steht noch die alte Anleitung (Updated: 2004-10-21) in der neuen Version.

     

    Die Dateien wurden als Teil der Konfiguration verschoben in den Ordner der jeweiligen Laufzeitumgebung in data/config/ und heißen config.chains.php und config.chains.load.php. Von der Logik hat sich am Chain System in der 4.9 nichts geändert.

  2. Wäre ne feine Sache, wenn die Liste alphabetisch nach Chain geordnet wäre, das erleichtert das Zurechtfinden

  3. Samuel Suther: Klick einfach mal auf den Spalenkopf, so lässt sich diese Tabelle sortieren.

  4. Die Funktion der Beispiel-Chain erwartet eine Variable. Deren Übergabe könnte man unter »Here an example to be used it in your module code:« eigentlich noch ergänzen, oder?

    1. Das wird doch bereits gezeigt:

      $chainEntry->execute("Fritz Box");