updated to TER v0.0.13; see ChangeLog
authorjocrau <jocrau@735d13b6-9817-0410-8766-e36946ffe9aa>
Mon, 8 Oct 2007 08:36:57 +0000 (08:36 +0000)
committerBastian Bringenberg <spam@bastian-bringenberg.de>
Thu, 4 Dec 2014 23:56:05 +0000 (00:56 +0100)
git-svn-id: https://svn.typo3.org/TYPO3v4/Extensions/contagged/trunk@6804 735d13b6-9817-0410-8766-e36946ffe9aa

15 files changed:
ChangeLog
README.txt
class.tx_contagged.php
ext_conf_template.txt
ext_emconf.php
ext_localconf.php
ext_tables.php
ext_tables.sql
locallang_db.xml
model/class.tx_contagged_model_mapper.php [new file with mode: 0644]
model/class.tx_contagged_model_terms.php [new file with mode: 0644]
pi1/class.tx_contagged_pi1.php [new file with mode: 0644]
pi1/contagged.tmpl [new file with mode: 0644]
pi1/locallang.xml [new file with mode: 0644]
tca.php

index aa32c57..a773d9f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,16 +1,98 @@
-2007-05-20 Jochen Rau <j.rau@web.de>
+v0.0.14 2007-10-07 Jochen Rau <j.rau@web.de>
 
-       * Tags can be selected to be excluded from parsing.
-       * New special tag <exparse></exparse> to exclude content from parsing.
+       * IMP Better support for multibyte character sets (used t3lib_cs instead of native strlen() and substr())
+       * FIX Link "back to page ..." in FE-Plugin
+       * CHG Sorting of terms
 
-2007-05-16 Jochen Rau <j.rau@web.de>
+v0.0.13 2007-10-06 Jochen Rau <j.rau@web.de>
 
-       * Changed from tt_content.text.20.parseFunc.userFunc to .postUserFunc
-       * Changed the separator of alternative terms from '|' (Pipe) to chr(10) (CR); the backend field is now multiline
-       * Added a prefix 'contagged_' to the registered values in $GLOBALS['TSFE'] to prevend name conflicts
-       * Some bugfixes in the type configuration and the css-class of dfn_inline
-       * Added option 'updateKeywords': It is now possible to auto-update page keywords based on the terms found on a page
+       * IMP Better support for joined words (with a dash)
+       * IMP Quoting of the term in the RegEx
+       * FIX Selection of a custom template file is now working
+       * FIX Handling of ambiguities (like the two meanings of the word "bus")
+       * CHG Added <dt> as a default excludeTag
+       * CHG Names of some template markers (esp. Links)
+       * IMP Enhanced performance of the FE-plugin (refactored code)
 
-2007-05-14 Jochen Rau <j.rau@web.de>
+v0.0.12 2007-09-28 Jochen Rau <j.rau@web.de>
+
+       * IMP Check if the table configured as a data source exists in the database (avoids an error message)
+
+v0.0.11 2007-09-26 Jochen Rau <j.rau@web.de>
+
+       * CHG You have to define one or more storagePids! This can be done globally (plugin.tx_contagged.storagePids), for each type (plugin.tx_contagged.types.foo.storagePids) or for each data source (plugin.tx_contagged.dataSources.bar.storagePids).
+       * IMP "fieldsToMap" and "secureFields" now made available via constants editor
+       * CHG Moved "fieldsToMap" and "secureFields" to the root of the TS Setup (plugin.tx_contagged.)
+       * ADD Every type of term can be excluded from beeing listed (new parameter "dontListTerms")
+       * ADD Every type of term can be hidden in the BE (new Parameter "hideSelection")
+       * IMP Next step towards MVC-Pattern (splitted tx_contagged_model into tx_contagged_model_terms and tx_contagged_model_mapper)
+
+v0.0.10 2007-09-22 Jochen Rau <j.rau@web.de>
+
+       * ADD type "Regular Expression" (every term is treated as RegEx and matches can be replaced)
+
+v0.0.9 2007-09-21 Jochen Rau <j.rau@web.de>
+
+       * IMP Any database table can now be configured as a data source for every single type of term (very powerful!)
+       * IMP Example configuration for tt_address
+       * ADD Keywords are now registered {register:contagged_keywords} to be inserted as "<meta>-keywords" of the page header (plugin "metatags" required)
+       * FIX Exclude individual cObjects (BE-field in tt_content)
+       * CHG Restructured code (half way to MVC-Pattern)
+
+v0.0.8 2007-09-18 Jochen Rau <j.rau@web.de>
+
+       * ADD Added experimental support for foreign tables like tt_address (configurable through TS Setup: table name, field mapping); comment out line 378 in class.tx_contagged.php to activate
+
+v0.0.7 2007-09-17 Jochen Rau <j.rau@web.de>
+
+       * ADD More than one char can be used as an index "char" (eg. names, ZIP-codes, cities)
+       * FIX Closing bracket in TS Setup
+       * FIX UTF-8-characters are now linked properly (auto generated index in FE-Plugin)
+       * IMP Cleaned up main RegEx
+       * IMP ALL database fields ar now registered in $GLOBALS['TSFE']->register['contagged_XXX'] to be used in TS Setup (for future hooks)
+
+v0.0.6 2007-09-13 Jochen Rau <j.rau@web.de>
+
+       * FIX Term is now displayed as <dt>TERM</dt> again (FE-Plugin)
+       * ADD stdWrap for the term to be searched ("termStdWrap"; usefull to search for already tagged text like <person>Steve Jobs</person>)
+       * FIX Title-attribute will not be displayed, if the short description (desc_short) is empty
+       * IMP UTF-8 handling of function to prevent attributes from beeing parsed (eg. <def title="don't parse this text">)
+       * CHG Definition of types "dfn_block" and "dfn_inline" (work in progress!)
+
+v0.0.5 2007-09-06 Jochen Rau <j.rau@web.de>
+
+       * CHG The types "dfn_block" and "dfn_inline" for pure css tool-tips are valid but still not running in IE6
+         (new parameter "stripBlockTags" for replacing <p>...</p> with <br/> in long description;
+         thanks to Markus Timtner)
+       * CHG Changed stdWrap in TS configuration to preStdWrap and added postStdWrap to make a outerWrap possible
+       * ADD Maximum amount of occurancies to be tagged can be configured for each type of term (e.g. "plugin.tx_contagged.types.dfn_block.maxOccur = 1")
+       * ADD Support for joined words (with a dash); new parameter "checkPreAndPostMatches"
+       * FIX bug in SQL-Statement (thanks to Tristan Knapp)
+
+v0.0.4 2007-08-29 Jochen Rau <j.rau@web.de>
+
+       * IMP Better support for multibyte characters (UTF8).
+
+v0.0.3 2007-08-28 Jochen Rau <j.rau@web.de>
+
+       * ADD New template based FE-list-plugin with index configurable through locallang.xml.
+       * FIX Fixed call of "userFunc".
+       * RMV The types "dfn_block" and "dfn_inline" are commented out bit still there as an example (it seems that a pure css tool-tip is not bullet proof)
+       * ADD Exclude individual cObjects (BE-field in tt_content)
+
+v0.0.2 2007-05-20 Jochen Rau <j.rau@web.de>
+
+       * ADD Tags can be selected to be excluded from parsing.
+       * ADD New special tag <exparse></exparse> to exclude content from parsing.
+
+v0.0.1 2007-05-16 Jochen Rau <j.rau@web.de>
+
+       * CHG Changed from tt_content.text.20.parseFunc.userFunc to .postUserFunc
+       * CHG Changed the separator of alternative terms from '|' (Pipe) to chr(10) (CR); the backend field is now multiline
+       * ADD Added a prefix 'contagged_' to the registered values in $GLOBALS['TSFE'] to prevent name conflicts
+       * FIX Some bugfixes in the type configuration and the css-class of dfn_inline
+       * ADD Added option 'updateKeywords': It is now possible to auto-update page keywords based on the terms found on a page
+
+v0.0.0 2007-05-14 Jochen Rau <j.rau@web.de>
 
        * Initial release
index 145c613..e19ba6a 100644 (file)
@@ -1 +1 @@
-This extension is a proof-of-concept. It enables searching, tagging and replacing terms in a content object.
\ No newline at end of file
+This extension parses your content to tag, replace and link specific terms. It is useful to auto-generate a glossary - but not only. See \'ChangeLog\' and WiKi (\'http://wiki.typo3.org/index.php/Contagged\'). Needs PHP >4.4.0 or >5.1.0.
\ No newline at end of file
index 02522b3..7c8b408 100644 (file)
        *  This copyright notice MUST APPEAR in all copies of the script!
        ***************************************************************/
 
-// TODO: change type of extension; use MVC-pattern
-// FIXIT: problem with nesting def_block elements
-// TODO: make text field of alternative terms (backend) multiline
-
 require_once (PATH_tslib . 'class.tslib_pibase.php');
 require_once (PATH_t3lib . 'class.t3lib_parsehtml.php');
+require_once (t3lib_extMgm::extPath('contagged') . 'model/class.tx_contagged_model_terms.php');
 
 /**
        * The main class to parse,tag and replace specific terms of the content.
        * 
-       * $Id$
-       * 
        * @author       Jochen Rau <j.rau@web.de>
        * @package      TYPO3
        * @subpackage   tx_contagged
        */
-/**
-       * [CLASS/FUNCTION INDEX of SCRIPT]
-       */
 class tx_contagged extends tslib_pibase {
-       var $prefixId = 'tx_contagged'; // same as class name
-       var $scriptRelPath = 'pi1/class.tx_contagged.php'; // path to this script relative to the extension dir
+       var $prefixId = 'tx_contagged';
+       var $scriptRelPath = 'class.tx_contagged.php'; // path to this script relative to the extension dir
        var $extKey = 'contagged'; // the extension key
        var $pi_checkCHash = true;
-       var $dataTable = 'tx_contagged_terms';
        var $conf; // the TypoScript configuration array
        var $termsFoundArray = array(); // an array of main terms for each term found in the cObj
-       var $specialExcludeTag = 'exparse'; // content tagged by this term will not be parsed
+       var $specialExcludeTag = 'exparse'; // content tagged by <exparse>|</exparse> will not be parsed
 
        /**
                * The method for parsing, tagging and linking the terms in a cObj
                *
                * @param        string          $content: The content of the cObj
-               * @param        array           $conf: The configuration
                * @return       The parsed and tagged content that is displayed on the website
                */
-       function main($content, $conf) {
+       function main($content,$conf) {
                $this->conf = $GLOBALS['TSFE']->tmpl->setup['plugin.'][$this->prefixId.'.'];
-               
-               // exit if the page should be skipped
-               if ($this->isPageToSkip()) {
+
+               // exit if the content should be skipped
+               if ($this->isContentToSkip()) {
                        return $content;
                        exit;
                }
 
-               // get an array of all data rows in the table "tx_contagged_terms"
-               $this->termsArray = $this->getTermsArray();
-
-               // build a list of tags used in the type definitions
-               // these tags will be omitted while parsing the text
-               foreach ($this->conf['types.'] as $key => $type) {
-                       if (isset($type['tag']) && !in_array($type['tag'],$tagArray)) {
-                               $tagArray[] = $type['tag'];
-                       }
-                       $tagList = implode(',',$tagArray);
-               }
-               if ($this->conf['excludeTags']) {
-                       $tagList .= ',' . $this->conf['excludeTags'];
-               }
-               $tagList .= ',' . $this->specialExcludeTag;
+               // get an array of all type configurations
+               $typesArray = $this->conf['types.'];
+               
+               // get the model (an associated array of terms)
+               $model = new tx_contagged_model_terms($this);
+               $termsArray = $model->getAllTerms();
+               
+               // get a comma separated list of all tags which should be omitted
+               $tagsToOmitt = $this->getTagsToOmitt();
+               // debug($termsArray); return $content; exit;
 
                // iterate through all terms
-               foreach ($this->termsArray as $termArray) {
+               foreach ($termsArray as $termArray) {
+
+                       unset($typeConfigArray);
+                       $typeConfigArray = $typesArray[$termArray['term_type'] . '.'];
 
-                       unset($typeConfigArray);  // this should prevend a wrong configuration if no config is available 
-                       $typeConfigArray = $this->getTypeConfigArray($termArray);
+                       $this->registerFields($typeConfigArray,$termArray);
 
                        // build the tag enclosing the term
-                       if ( isset($typeConfigArray['tag']) ) {
+                       if ( !empty($typeConfigArray['tag']) ) {
                                // get the attributes
                                $langAttribute = $this->getLangAttribute($typeConfigArray,$termArray);
                                $titleAttribute = $this->getTitleAttribute($typeConfigArray,$termArray);
@@ -100,75 +87,101 @@ class tx_contagged extends tslib_pibase {
                                $after = '</' . $typeConfigArray['tag'] . '>';
                        }
 
-                       // Set the maximum amount of replaced terms to a standard
-                       // $maxOccur = $typeConfigArray['maxOccur'];
-                       $maxOccur ? $maxOccur : $maxOccur = 9999;
-                       // reset the occurancies of the actual term
-                       // $occuranciesOfTerm = 0;
-
-                       foreach ( $termArray['terms'] as $term ) {
+                       // get the maximum amount of replaced terms
+                       $maxOccur = $typeConfigArray['maxOccur'] ? (int)$typeConfigArray['maxOccur'] : 9999;
+                       
+                       $terms = array();
+                       $terms = $termArray['term_alt'];
+                       $terms[] = $termArray['term_main'];
+                       foreach ( $terms as $term ) {
+                               $termsFound = 0; // reset the amount of terms found in a cObj
+                               
+                               // build main RegEx
+                               // stdWrap for the term to search for; usefull to realize custom tags like <person>|</person>
+                               $term = $this->cObj->stdWrap($term,$typeConfigArray['termStdWrap.']);
+                               if ( $this->checkLocalGlobal($typeConfigArray,'termIsRegEx')>0 ) {
+                                       $regEx = $termArray['term_main'];
+                               } else {
+                                       $regEx = '/(?<=\P{L}|^)' . preg_quote($term,'/') . '(?=\P{L}|$)/';
+                               }
 
-                               // $occuranciesOfTerm = $occuranciesOfTerm + $termsfound;
-                               // $termsFound = 0; // reset the amount of terms found in a cObj
+                               // TODO split recursively
                                $parseObj = t3lib_div::makeInstance('t3lib_parsehtml');
-                               $content = $parseObj->splitIntoBlock($tagList,$content);
+                               $content = $parseObj->splitIntoBlock($tagsToOmitt,$content);
+                               // debug($content);
                                foreach($content as $intKey => $HTMLvalue) {
                                        if (!($intKey%2)) {
-                                               // the following code was inspired from the class.tslib_content.php, line 4265ff
+                                               // split the content in two pieces separated by the matched term
+                                               // this was inspired by class.tslib_content.php, line 4265ff
                                                $newstring = '';
                                                do {
-                                                       // split the content in two pieces separated by the term, but don't do that if we are inside a tag to prevent nested tags
-                                                       // RegEx explained: (Match the term if it is NOT followed by a closing tag) OR, if no occurency was found
-                                                       // (Match the term that is followed by a closing tag with an opening tag inbetween). UFF!
-                                                       // TODO Unit testing for the Regex in preg_split; because this is the most critical operation
-                                                       // TODO modifier i: makes RegEx case insensitive; this should be configurable through TS
-                                                       $pieces = preg_split('#(?<=\W|\A)' . preg_quote($term) . '(?=\W|\Z)(?!.*</(' . $tagList . ')>)|(?<=\W|\A)' . preg_quote($term) . '(?=\W|\Z)(?=.*<(' . $tagList . ')(?=.*</\2))#Ui', $content[$intKey], 2);
-                                                       $newstring .= $pieces[0];
-
-                                                       // flag: $inTag=true if we are inside a tag < here we are >
-                                                       if ( strrpos($pieces[0],'<') > strrpos($pieces[0],'>') ) {
+                                                       // split the content in two pieces separated by the term
+                                                       $pieces = preg_split( $regEx . $this->conf['modifier'], $content[$intKey], 2 );
+
+                                                       // Flag: $inTag=true if we are inside a tag < here we are > or if we are inside an entity (eg. &nbsp;)
+                                                       // first RegEx see "Friedl, Jeffrey: Reguläre Audrücke. p.204"
+                                                       if ( preg_match('/<("[^"]*"|\'[^\']*\'|[^\'">])*$/u',$pieces[0])>0 && preg_match('/^("[^"]*"|\'[^\']*\'|[^\'"<])*>/u',$pieces[1])>0 ) {
+                                                               $inTag = true;
+                                                       } elseif (preg_match('/&.{0,5}$/u',$pieces[0])>0 && preg_match('/^.{0,5};/u',$pieces[1])>0) {
                                                                $inTag = true;
                                                        } else {
                                                                $inTag = false;
                                                        }
 
-                                                       // the  term is handled as $matchedTerm, so it doesn't conflict with case (in)sensitivity of the RegEx
-                                                       $matchLength = strlen($content[$intKey]) - (strlen($pieces[0]) + strlen($pieces[1]));
-                                                       $matchedTerm = substr($content[$intKey], strlen($pieces[0]), $matchLength);
-                                                       $GLOBALS['TSFE']->register['contagged_matchedTerm'] = $matchedTerm;
-                                                       if ( trim($matchedTerm) && ($inTag === false) && ($occuranciesOfTerm < $maxOccur) ) {
-                                                               // Build an array of terms found in the content.
-                                                               // This will be used to store them as keywords of the page.
-                                                               // The term used will be the replaced term. If there is no replacement the main term will be used.
-                                                               $this->termsFoundArray[] = $termArray['term_replace']?$termArray['term_replace']:$termArray['term_main'];
-                                                               
+                                                       // support for joined words (with a dash)
+                                                       $preMatch = '';
+                                                       $postMatch = '';
+                                                       if ($this->checkLocalGlobal($typeConfigArray,'checkPreAndPostMatches')>0) {
+                                                               preg_match('/(?<=\P{L})[\p{L}\p{Pd}]*\p{Pd}$/Uuis', $pieces[0], $preMatch);
+                                                               preg_match('/^\p{Pd}[\p{L}\p{Pd}]*(?=\P{L})/Uuis', $pieces[1], $postMatch);                                                             
+                                                       }
+
+                                                       // add the first string ($pieces[0]) to the new string without the pre matched part
+                                                       $newstring .= $GLOBALS['TSFE']->csConvObj->substr('utf-8',$pieces[0],0,$GLOBALS['TSFE']->csConvObj->strlen('utf-8',$pieces[0])-$GLOBALS['TSFE']->csConvObj->strlen('utf-8',$preMatch[0]));
+
+                                                       // the term is handled as $matchedTerm, so it doesn't conflict with case (in)sensitivity of the RegEx
+                                                       $matchLength = $GLOBALS['TSFE']->csConvObj->strlen('utf-8',$content[$intKey]) - ($GLOBALS['TSFE']->csConvObj->strlen('utf-8',$pieces[0]) + $GLOBALS['TSFE']->csConvObj->strlen('utf-8',$pieces[1])) + $GLOBALS['TSFE']->csConvObj->strlen('utf-8',$preMatch[0]) + $GLOBALS['TSFE']->csConvObj->strlen('utf-8',$postMatch[0]);
+                                                       $matchedTerm = $GLOBALS['TSFE']->csConvObj->substr('utf-8',$content[$intKey], $GLOBALS['TSFE']->csConvObj->strlen('utf-8',$pieces[0])-$GLOBALS['TSFE']->csConvObj->strlen('utf-8',$preMatch[0]), $matchLength);
+                                                       // do something with the matched term (replace, stdWrap, link, tag)
+                                                       if ( trim($matchedTerm) && $inTag==false && ($termsFound<$maxOccur) ) {
                                                                $this->replaceMatchedTerm(&$matchedTerm,$typeConfigArray,$termArray);
-                                                               $this->linkMatchedTerm(&$matchedTerm,$typeConfigArray,$termArray);
+                                                               $GLOBALS['TSFE']->register['contagged_matchedTerm'] = $matchedTerm;
 
-                                                               // call stdWrap to handle the matched term via TS
-                                                               // TODO: wrapping inside AND outside the a-tag should be enabled
-                                                               if ($typeConfigArray['stdWrap.']) {
-                                                                       $matchedTerm = $this->cObj->stdWrap($matchedTerm,$typeConfigArray['stdWrap.']);
+                                                               // call stdWrap to handle the matched term via TS BEFORE it is wraped with a-tags
+                                                               if ($typeConfigArray['preStdWrap.']) {
+                                                                       $matchedTerm = $this->cObj->stdWrap($matchedTerm,$typeConfigArray['preStdWrap.']);
                                                                }
 
-                                                               $matchedTerm = $before . $matchedTerm . $after;
+                                                               $this->linkMatchedTerm(&$matchedTerm,$typeConfigArray,$termArray);
 
-                                                               // $termsFound++;
+                                                               // call stdWrap to handle the matched term via TS AFTER it was wrapped with a-tags
+                                                               if ($typeConfigArray['postStdWrap.'] or $typeConfigArray['stdWrap.']) {
+                                                                       $matchedTerm = $this->cObj->stdWrap($matchedTerm,$typeConfigArray['postStdWrap.']);
+                                                                       $matchedTerm = $this->cObj->stdWrap($matchedTerm,$typeConfigArray['stdWrap.']); // for compatibility with < v0.0.5
+                                                               }
 
+                                                               if ( !empty($typeConfigArray['tag']) ) {
+                                                                       $matchedTerm = $before . $matchedTerm . $after;
+                                                               }
+
+                                                               // TODO updated keywords are only taken from the last cObj that has been parsed
+                                                               // Build an array of terms found in the contentObject.
+                                                               // This will be used to store them as keywords of the page.
+                                                               $this->termsFoundArray[] = $termArray['term'];
+                                                               $termsFound++;
                                                        }
                                                        // concatenate the term again
                                                        $newstring .= $matchedTerm;
-                                                       $content[$intKey] = $pieces[1];
+                                                       $content[$intKey] = $GLOBALS['TSFE']->csConvObj->substr('utf-8',$pieces[1],$GLOBALS['TSFE']->csConvObj->strlen('utf-8',$postMatch[0]));
                                                } while ($pieces[1]);
                                                $content[$intKey] = $newstring;
                                        }
                                }
-                               
-                       $content = implode('',$content);        
-                       
+                               $content = implode('',$content);
                        }
                }
-               
+
+               // update the keywords (field "tx_contagged_keywords" in table "page")
                if ($this->conf['updateKeywords'] > 0) {
                        $this->insertKeywords();
                }
@@ -177,67 +190,96 @@ class tx_contagged extends tslib_pibase {
 
        }
 
+       function getTagsToOmitt() {
+               // build a list of tags used in the type definitions
+               // these tags will be omitted while parsing the text
+               $tagArray = array();
+               // if configured: build a list of tags used by the term definitions
+               if ($this->conf['autoExcludeTags']>0) {;
+                       foreach ($this->conf['types.'] as $key => $type) {
+                               if (!empty($type['tag']) && !in_array($type['tag'],$tagArray)) {
+                                       $tagArray[] = $type['tag'];
+                               }
+                       }
+               }
+               // if there are tags to exclude: add them to the list
+               if ($this->conf['excludeTags']) {
+                       $tagArray[] = $this->conf['excludeTags'];
+               }
+               // add the special exclude tag <exparse> to the list
+               $tagArray[] = $this->specialExcludeTag;
+               $tagList = implode(',',$tagArray);
+               
+               return $tagList;
+       }
+
        function insertKeywords() {
                // make a list of unique terms found in the content
                $this->termsFoundArray = array_unique($this->termsFoundArray);
                $termsFoundList = implode(',',$this->termsFoundArray);
-               // build an array passed to the UPDATE query
+               $GLOBALS['TSFE']->register['contagged_keywords'];
+               // build an array to be passed to the UPDATE query
                $updateArray = array($this->prefixId . '_keywords' => $termsFoundList);
-//             $updateArray = array('keywords' => $termsFoundList);
-//             debug($updateArray);
                // execute sql-query
-               $res = $GLOBALS['TYPO3_DB']->exec_UPDATEquery('pages', // TABLE ...
+               $res = $GLOBALS['TYPO3_DB']->exec_UPDATEquery(
+                       'pages', // TABLE ...
                        'uid=' . $GLOBALS['TSFE']->id, // WHERE ...
                        $updateArray
-               );
+                       );
        }
 
-       function getTypeConfigArray($termArray) {
-               // shortcut to the TS configuration array of the current type of term
-               $typeConfigArray = $this->conf['types.'][$termArray['term_type'] . '.'];
-
-               // load several fields into the register to be handled by the TS setup
-               $GLOBALS['TSFE']->register['contagged_uid'] = $termArray['uid'];
-               $GLOBALS['TSFE']->register['contagged_desc_short'] = $termArray['desc_short'];
-               $GLOBALS['TSFE']->register['contagged_desc_long'] = $termArray['desc_long'];
-               $GLOBALS['TSFE']->register['contagged_term_main'] = $termArray['term_main'];
-               $GLOBALS['TSFE']->register['contagged_term_replace'] = $termArray['term_replace'];
-               $GLOBALS['TSFE']->register['contagged_link'] = $termArray['link'];
-
-               return $typeConfigArray;
+       function registerFields($typeConfigArray,$termArray) {
+               // Replace <p></p> with <br/>; Idea from Markus Timtner. Thank you!
+               // TODO: strip or replace all block-tags
+               if ($typeConfigArray['stripBlockTags']>0) {
+                       $termArray['desc_long'] = preg_replace('/<p[^<>]*>(.*?)<\/p\s*>/ui','$1<br />',$termArray['desc_long']);                        
+               }
 
+               // register all fields to be handled by the TS Setup
+               foreach ($termArray as $key => $value) {
+                       $GLOBALS['TSFE']->register['contagged_'.$key] = $termArray[$key];                       
+               }
        }
 
        function linkMatchedTerm(&$matchedTerm,$typeConfigArray,$termArray) {
                // check conditions if the term should be linked to a list page
                $makeLink = $this->checkLocalGlobal($typeConfigArray,'linkToListPage');
-               if ( ($termArray['desc_long'] == '') || ($termArray['exclude'] > 0) ) {
+               if ( ($termArray['desc_long'] == '') || ($termArray['exclude']>0) ) {
                        $makeLink = false;
                }
+               if ($termArray['link']) {
+                       $makeLink = true;
+               }
 
                // link the matched term to the front-end list page
                if ($makeLink) {
-                       unset($typolinkConf); // TODO Is it necessary to unset the $typoLinkConf?
-                       $listPage = ($typeConfigArray['listPage']?$typeConfigArray['listPage']:$this->conf['listPage']);
-                       $GLOBALS['TSFE']->register['contagged_list_page'] = $termArray['uid'];
-                       $typolinkConf['parameter'] = (int) $listPage;
-                       $typolinkConf['useCacheHash'] = 1;
+                       unset($typolinkConf);
+                       if ($termArray['link']) {
+                               $parameter = $termArray['link'];
+                       } else {
+                               $parameter = $typeConfigArray['listPage']?$typeConfigArray['listPage']:$this->conf['listPage'];
+                       }
+                       
+                       $GLOBALS['TSFE']->register['contagged_list_page'] = $parameter;
+                       $typolinkConf['parameter'] = $parameter;
+                       // $typolinkConf['useCacheHash'] = 1; // TODO cHash
+                       // $typolinkConf['ATagParams'] = "rel='moodalbox'";
                        $typolinkConf['additionalParams'] =
-                               '&' . $this->prefixId . '[back]=' . $GLOBALS['TSFE']->id .
-                               '&' . $this->prefixId . '[uid]=' . $termArray['uid'] .
-                               '&' . $this->prefixId . '[type]=' . $termArray['term_type'];
+                               '&' . $this->prefixId . '_pi1' . '[backPid]=' . $GLOBALS['TSFE']->id .
+                               '&' . $this->prefixId . '_pi1' . '[uid]=' . $termArray['uid'];
+                               //. '&' . $this->prefixId . '_pi1' . '[term_type]=' . $termArray['term_type'];
                        $matchedTerm = $this->cObj->typolink($matchedTerm, $typolinkConf);
                }
        }
 
        function replaceMatchedTerm(&$matchedTerm,$typeConfigArray,$termArray) {
-               // replace the term
-               // TODO improve upper/lower case handling (UTF8)
-               if ( $termArray['term_replace'] && $typeConfigArray['replaceTerm'] == 1 ) {
+               $replaceTerm = $this->checkLocalGlobal($typeConfigArray,'replaceTerm');
+               if ( $replaceTerm && $termArray['term_replace'] ) {
                        // if the first letter of the matched term is upper case
                        // make the first letter of the replacing term also upper case
-                       if ( preg_match('#[A-ZÄÖÜ]#', substr($matchedTerm,0,1) ) != 0 ) {
-                               $matchedTerm = ucfirst($termArray['term_replace']);
+                       // (\p{Lu} stands for "unicode letter uppercase")
+                       if ( preg_match('/^\p{Lu}?/u',$matchedTerm)>0 ) {
+                               $matchedTerm = ucfirst($termArray['term_replace']); // TODO ucfirst is not UTF8 safe; it depends on the locale settings (they could be ASCII) 
                        } else {
                                $matchedTerm = $termArray['term_replace'];
                        }
@@ -246,11 +288,11 @@ class tx_contagged extends tslib_pibase {
 
        function checkLocalGlobal($typeConfigArray,$attributeName) {
                if ( isset($typeConfigArray[$attributeName]) ) {
-                       $addAttribute = ($typeConfigArray[$attributeName] > 0) ? true : false;
+                       $addAttribute = ($typeConfigArray[$attributeName]>0) ? true : false;
                } else {
-                       $addAttribute = ($this->conf[$attributeName] > 0) ? true : false;
+                       $addAttribute = ($this->conf[$attributeName]>0) ? true : false;
                }
-               
+
                return $addAttribute;
        }
 
@@ -279,10 +321,10 @@ class tx_contagged extends tslib_pibase {
        }
 
        function getTitleAttribute($typeConfigArray,$termArray) {
-               if ($this->checkLocalGlobal($typeConfigArray,'addTitleAttribute') && isset($termArray['desc_short'])) {
+               if ($this->checkLocalGlobal($typeConfigArray,'addTitleAttribute') && !empty($termArray['desc_short'])) {
                        $titleAttribute = ' title="' . $termArray['desc_short'] . '"';
                }
-               
+
                return $titleAttribute;
        }
 
@@ -303,9 +345,10 @@ class tx_contagged extends tslib_pibase {
                *
                * @return       True, if the page should be skipped
                */
-       function isPageToSkip() {
+       function isContentToSkip() {
                $result = true; // true, if the page should be skipped
                $currentPageUid = $GLOBALS['TSFE']->id;
+
                // get rootline of the current page
                $rootline = $GLOBALS['TSFE']->sys_page->getRootline($currentPageUid);
                // build an array of uids of pages the rootline
@@ -313,12 +356,12 @@ class tx_contagged extends tslib_pibase {
                        $pageUidsInRootline[] = $rootline["$i"]['uid'];
                }
                // check if the root page is in the rootline of the current page
-               $includeRootPagesUids = t3lib_div :: trimExplode(',', $this->conf['includeRootPages'], 1);
+               $includeRootPagesUids = t3lib_div::trimExplode(',', $this->conf['includeRootPages'], 1);
                foreach ($includeRootPagesUids as $includeRootPageUid) {
                        if (t3lib_div :: inArray($pageUidsInRootline, $includeRootPageUid))
                                $result = false;
                }
-               $excludeRootPagesUids = t3lib_div :: trimExplode(',', $this->conf['excludeRootPages'], 1);
+               $excludeRootPagesUids = t3lib_div::trimExplode(',', $this->conf['excludeRootPages'], 1);
                foreach ($excludeRootPagesUids as $excludeRootPageUid) {
                        if (t3lib_div :: inArray($pageUidsInRootline, $excludeRootPageUid))
                                $result = true;
@@ -329,53 +372,15 @@ class tx_contagged extends tslib_pibase {
                if (t3lib_div::inList($this->conf['excludePages'], $currentPageUid)) {
                        $result = true;                 
                }
-
-               return $result;
-       }
-
-       /**
-               * Build an array of the entries in the table "tx_contagged_terms"
-               *
-               * @return       An array with the data of the table "tx_contagged_terms"
-               */
-       function getTermsArray() {
-               // execute sql-query
-               $result = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', // SELECT ...
-               $this->dataTable, // FROM ...
-               '1=1' . tslib_cObj :: enableFields($this->dataTable) // WHERE...
-               );
-
-
-               // build an array of entries in the table "tx_contagged_terms"
-               $dataArray = array ();
-               $terms = array ();
-               foreach ($result as $row) {
-                       // build an array of alternative shortcurts (term_alt) and add the main term (term_main)
-                       $terms = t3lib_div :: trimExplode(chr(10), htmlspecialchars($row['term_alt']), $onlyNonEmptyValues = 1);
-                       $terms[] = trim(htmlspecialchars($row['term_main']));
-                       // TODO sort the array by descending length of value string; in combination with the htmlparser this will prevend nesting
-                       $desc_long = $this->cObj->parseFunc($row['desc_long'],$conf='',$ref='< lib.parseFunc_RTE');
-                       // $desc_long = preg_replace('/(\015\012)|(\015)|(\012)/','<br />',$row['desc_long']);
-                       // $desc_long = trim(htmlspecialchars($desc_long));
-                       // put it all together
-                       $dataArray[] = array (
-                               'uid' => $row['uid'],
-                               'term_main' => trim(htmlspecialchars($row['term_main'])),
-                               'terms' => $terms,
-                               'term_type' => $row['term_type'],
-                               'term_lang' => $row['term_lang'],
-                               'term_replace' => trim(htmlspecialchars($row['term_replace'])),
-                               'desc_short' => trim(htmlspecialchars($row['desc_short'])),
-                               'desc_long' => $desc_long,
-                               'link' => $row['link'],
-                               'exclude' => $row['exclude']
-                               );
+               if ( $GLOBALS['TSFE']->page['tx_contagged_dont_parse'] == 1) {
+                       $result = true;
+               }
+               if ( $this->cObj->getFieldVal('tx_contagged_dont_parse') == 1) {
+                       $result = true;
                }
 
-               return $dataArray;
-
+               return $result;
        }
-
 }
 
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/contagged/class.tx_contagged.php']) {
index 8b3aecd..2fce6ad 100644 (file)
@@ -1,3 +1,3 @@
 
-  # cat=basic//10; type=int; label= Page UID where the main configuration template is stored.
-mainConfigStorageUid = 0
+       # cat=basic//10; type=int; label= Page-ID where the main template is stored.
+       mainConfigStoragePid = 0
index 6db5756..f990100 100644 (file)
@@ -3,7 +3,7 @@
 ########################################################################
 # Extension Manager/Repository config file for ext: "contagged"
 #
-# Auto generated 14-05-2007 12:46
+# Auto generated 06-10-2007 00:53
 #
 # Manual updates:
 # Only the data in the array - anything else is removed by next write.
 
 $EM_CONF[$_EXTKEY] = array(
        'title' => 'Content parser and tagger',
-       'description' => 'The extension parses your content to tag, replace and link specific terms. It is useful to auto-generate a glossary - but not only. And it is configurable through TS.',
+       'description' => 'This extension parses your content to tag, replace and link specific terms. It is useful to auto-generate a glossary - but not only. See \'ChangeLog\' and WiKi (\'http://wiki.typo3.org/index.php/Contagged\'). Needs at least PHP 4.4.0',
        'category' => 'fe',
-       'author' => 'Jochen Rau',
-       'author_email' => 'j.rau@web.de',
-       'shy' => '',
+       'shy' => 0,
+       'version' => '0.0.13',
        'dependencies' => '',
        'conflicts' => '',
        'priority' => '',
+       'loadOrder' => '',
        'module' => '',
        'state' => 'alpha',
-       'internal' => '',
        'uploadfolder' => 1,
        'createDirs' => 'uploads/tx_contagged/rte/',
        'modify_tables' => '',
-       'clearCacheOnLoad' => 1,
+       'clearcacheonload' => 0,
        'lockType' => '',
+       'author' => 'Jochen Rau',
+       'author_email' => 'j.rau@web.de',
        'author_company' => '',
-       'version' => '0.0.1',
+       'CGLcompliance' => '',
+       'CGLcompliance_note' => '',
        'constraints' => array(
                'depends' => array(
                ),
@@ -38,7 +40,7 @@ $EM_CONF[$_EXTKEY] = array(
                'suggests' => array(
                ),
        ),
-       '_md5_values_when_last_written' => 'a:17:{s:9:"ChangeLog";s:4:"8fe4";s:10:"README.txt";s:4:"9ef0";s:22:"class.tx_contagged.php";s:4:"1d3c";s:21:"ext_conf_template.txt";s:4:"98a6";s:12:"ext_icon.gif";s:4:"50a3";s:17:"ext_localconf.php";s:4:"9c47";s:14:"ext_tables.php";s:4:"ca26";s:14:"ext_tables.sql";s:4:"ae2b";s:27:"icon_tx_contagged_terms.gif";s:4:"50a3";s:16:"locallang_db.xml";s:4:"beb7";s:7:"tca.php";s:4:"53af";s:14:"doc/manual.sxw";s:4:"c9fc";s:19:"doc/wizard_form.dat";s:4:"8bf3";s:20:"doc/wizard_form.html";s:4:"c95f";s:20:"static/constants.txt";s:4:"2bbc";s:16:"static/setup.txt";s:4:"80b4";s:20:"static/css/setup.txt";s:4:"77f5";}',
+       '_md5_values_when_last_written' => 'a:29:{s:9:"ChangeLog";s:4:"c780";s:10:"README.txt";s:4:"821e";s:22:"class.tx_contagged.php";s:4:"c03f";s:21:"ext_conf_template.txt";s:4:"f53f";s:12:"ext_icon.gif";s:4:"50a3";s:17:"ext_localconf.php";s:4:"a6a7";s:14:"ext_tables.php";s:4:"3a59";s:14:"ext_tables.sql";s:4:"3600";s:27:"icon_tx_contagged_terms.gif";s:4:"50a3";s:16:"locallang_db.xml";s:4:"9602";s:7:"tca.php";s:4:"dffd";s:27:"configuration/css/setup.txt";s:4:"f0f0";s:30:"configuration/ts/constants.txt";s:4:"9507";s:26:"configuration/ts/setup.txt";s:4:"a67c";s:49:"controller/class.tx_contagged_controller_list.php";s:4:"e29c";s:24:"controller/locallang.xml";s:4:"eab9";s:14:"doc/manual.sxw";s:4:"676c";s:19:"doc/wizard_form.dat";s:4:"8bf3";s:20:"doc/wizard_form.html";s:4:"c95f";s:41:"model/class.tx_contagged_model_mapper.php";s:4:"5534";s:40:"model/class.tx_contagged_model_terms.php";s:4:"60ef";s:30:"pi1/class.tx_contagged_pi1.php";s:4:"8f28";s:18:"pi1/contagged.tmpl";s:4:"a534";s:17:"pi1/locallang.xml";s:4:"4a6d";s:20:"static/constants.txt";s:4:"3696";s:16:"static/setup.txt";s:4:"5ff0";s:20:"static/css/setup.txt";s:4:"f0f0";s:37:"view/class.tx_contagged_view_list.php";s:4:"d51a";s:19:"view/contagged.tmpl";s:4:"f38e";}',
        'suggests' => array(
        ),
 );
index 72b88f2..c9a1002 100644 (file)
@@ -1,8 +1,25 @@
 <?php
 if (!defined ('TYPO3_MODE'))   die ('Access denied.');
 
+// TODO RTE configuration
+// t3lib_extMgm::addPageTSConfig('
+//     RTE.config.tx_contagged_terms.desc_long {
+//             proc.exitHTMLparser_db=1
+//             proc.exitHTMLparser_db {
+//                     keepNonMatchedTags=1
+//             }
+//     }
+// ');
+
+// TODO Remove lines below; just for testing
+// t3lib_extMgm::addPageTSConfig('
+//     TCEFORM.tx_contagged_terms.term_type.itemsProcFunc.test = 1
+// ');
+
 t3lib_extMgm::addUserTSConfig('
        options.saveDocNew.tx_contagged_terms=1
 ');
 
+// $TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-all']['tx_contagged'] = 'EXT:contagged/class.tx_contagged.php:&tx_contagged->main';
+
 ?>
\ No newline at end of file
index ab2d604..b3c84ad 100644 (file)
@@ -4,10 +4,9 @@ if (!defined ('TYPO3_MODE')) die ('Access denied.');
 t3lib_extMgm::allowTableOnStandardPages('tx_contagged_terms');
 t3lib_extMgm::addToInsertRecords('tx_contagged_terms');
 
-// t3lib_extMgm::addPItoST43($_EXTKEY,'class.tx_contagged.php','','includeLib',1);
-
 // add contagged to the "insert plugin" content element
-t3lib_extMgm::addPlugin(Array('LLL:EXT:contagged/locallang_db.php:tx_contagged_terms.plugin','contagged'));
+t3lib_extMgm::addPlugin(array('LLL:EXT:contagged/locallang_db.php:tx_contagged_terms.plugin', $_EXTKEY.'_pi1'),'list_type');
+t3lib_extMgm::addPItoST43($_EXTKEY,'pi1/class.tx_contagged_pi1.php','_pi1','list_type',1);
 
 // initialize static extension templates
 t3lib_extMgm::addStaticFile($_EXTKEY,'static/', 'Content parser');
@@ -44,7 +43,7 @@ $TCA["tx_contagged_terms"] = array (
        )
 );
 
-// Add a field  "exclude this page from parsing" to the table "pages"
+// Add a field  "exclude this page from parsing" to the table "pages" and "tt_content"
 $tempColumns = Array (
     "tx_contagged_dont_parse" => Array (
         "exclude" => 1,
@@ -59,4 +58,8 @@ t3lib_div::loadTCA("pages");
 t3lib_extMgm::addTCAcolumns("pages",$tempColumns,1);
 t3lib_extMgm::addToAllTCAtypes("pages","tx_contagged_dont_parse;;;;1-1-1");
 
+t3lib_div::loadTCA("tt_content");
+t3lib_extMgm::addTCAcolumns("tt_content",$tempColumns,1);
+t3lib_extMgm::addToAllTCAtypes("tt_content","tx_contagged_dont_parse;;;;1-1-1");
+
 ?>
\ No newline at end of file
index 17b3cb6..727b82a 100644 (file)
@@ -40,7 +40,6 @@ CREATE TABLE tx_contagged_terms (
        KEY t3ver_oid (t3ver_oid,t3ver_wsid)
 );
 
-
 #
 # Table structure for table 'pages'
 #
@@ -48,3 +47,10 @@ CREATE TABLE pages (
        tx_contagged_dont_parse tinyint(3) DEFAULT '0' NOT NULL,
        tx_contagged_keywords text NOT NULL,
 );
+
+#
+# Table structure for table 'tt_content'
+#
+CREATE TABLE tt_content (
+       tx_contagged_dont_parse tinyint(3) DEFAULT '0' NOT NULL,
+);
\ No newline at end of file
index dbe99b6..4ff5989 100644 (file)
                        <label index="tx_contagged_terms.term_lang.I.4">Italienisch</label>
                        <label index="tx_contagged_terms.term_lang.I.5">Spanisch</label>
                        <label index="tx_contagged_terms.term_lang">Sprache des Ausdrucks</label>
-                       <label index="tx_contagged_terms.term_replace">Ausdruck, der anstelle des Begriffs eingesetzt wird</label>
+                       <label index="tx_contagged_terms.term_replace">Ersatz</label>
                        <label index="tx_contagged_terms.desc_short">Kurzbeschreibung (z. B. Tool-Tip-Text)</label>
                        <label index="tx_contagged_terms.desc_long">Ausführliche Beschreibung</label>
                        <label index="tx_contagged_terms.link">Verweis</label>
                        <label index="tx_contagged_terms.exclude">Von Frontend-Listen ausschließen</label>
-                       <label index="pages.tx_contagged_dont_parse">Text der Seite nicht parsen</label>
+                       <label index="pages.tx_contagged_dont_parse">Text nicht parsen</label>
                </languageKey>
        </data>
 </T3locallang>
diff --git a/model/class.tx_contagged_model_mapper.php b/model/class.tx_contagged_model_mapper.php
new file mode 100644 (file)
index 0000000..bc00385
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+/***************************************************************
+       *  Copyright notice
+       *
+       *  (c) 2007 Jochen Rau <j.rau@web.de>
+       *  All rights reserved
+       *
+       *  This script is part of the TYPO3 project. The TYPO3 project is
+       *  free software; you can redistribute it and/or modify
+       *  it under the terms of the GNU General Public License as published by
+       *  the Free Software Foundation; either version 2 of the License, or
+       *  (at your option) any later version.
+       *
+       *  The GNU General Public License can be found at
+       *  http://www.gnu.org/copyleft/gpl.html.
+       *
+       *  This script is distributed in the hope that it will be useful,
+       *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+       *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       *  GNU General Public License for more details.
+       *
+       *  This copyright notice MUST APPEAR in all copies of the script!
+       ***************************************************************/
+
+/**
+       * The model of contagged.
+       * 
+       * @author       Jochen Rau <j.rau@web.de>
+       * @package      TYPO3
+       * @subpackage   tx_contagged_model_mapper
+       */
+class tx_contagged_model_mapper {
+       var $conf; // the TypoScript configuration array
+       var $cObj;
+       var $controller;
+       
+       function tx_contagged_model_mapper($controller) {
+               $this->controller = $controller;
+               $this->conf = $controller->conf;
+               $this->cObj = $controller->cObj;
+       }
+
+       /**
+               * Build an array of the entries in the table "tx_contagged_terms"
+               *
+               * @return       An array with the data of the table "tx_contagged_terms"
+               */
+       function getDataArray($result,$dataSource) {
+               $dataArray = array();
+               $terms = array();
+
+               $dataSourceConfigArray = $this->conf['dataSources.'][$dataSource . '.'];
+               $sourceName = $dataSourceConfigArray['sourceName'];
+
+               // add additional fields configured in the mapping configuration of the data source
+               $fieldsToMapfromTS = t3lib_div::trimExplode(',', $this->conf['fieldsToMap'], 1);
+               foreach ($dataSourceConfigArray['mapping.'] as $fieldToMap => $value) {
+                               $fieldsToMapArray[] = substr($fieldToMap,0,-1);
+               }
+               foreach ($fieldsToMapfromTS as $key => $fieldToMap) {
+                       if ( !t3lib_div::inArray($fieldsToMapArray,$fieldToMap) ) {
+                               $fieldsToMapArray[] = $fieldToMap;
+                       }
+               }
+               
+               // iterate through all data from the datasource
+               foreach ($result as $row) {
+                       $secureFields = $this->conf['types.'][$row['term_type'].'.']['termIsRegEx']>0 ? $this->conf['types.'][$row['term_type'].'.']['secureFields'] : $this->conf['secureFields'];
+                       if ($dataSourceConfigArray['mapping.']['uid.']['field']) {
+                               $termUid = $row[$dataSourceConfigArray['mapping.']['uid.']['field']];                           
+                       }
+                       $termMain = $dataSourceConfigArray['mapping.']['term_main.']['field'] ? $dataSourceConfigArray['mapping.']['term_main.']['field'] : '';
+                       $termReplace = $dataSourceConfigArray['mapping.']['term_replace.']['field'] ? $dataSourceConfigArray['mapping.']['term_replace.']['field'] : '';
+                       $term = $row[$termReplace] ? $row[$termReplace] : $row[$termMain];
+                       $dataArray[$termUid] = array();
+                       $dataArray[$termUid]['term'] = $term;
+                       foreach ( $fieldsToMapArray as $field) {
+                               $value = $dataSourceConfigArray['mapping.'][$field.'.'];
+                               if ( $value['value'] ) {
+                                       $dataArray[$termUid][$field] = $value['value'];
+                               } elseif ( $value['field'] ) {
+                                       $dataArray[$termUid][$field] = t3lib_div::inList($secureFields,$field) ? htmlspecialchars($row[$value['field']]) : $row[$value['field']];
+                               } else {
+                                       $dataArray[$termUid][$field] = NULL;
+                               }
+                               if ( $value['stdWrap.'] ) {
+                                       $dataArray[$termUid][$field] = $this->cObj->stdWrap($dataArray[$termUid][$field],$value['stdWrap.']);
+                               }
+                               $GLOBALS['TSFE']->register['contagged_'.$field] = $dataArray[$termUid][$field];                                 
+                               if ( !t3lib_div::inArray($fieldsToMapArray,$field) ) {
+                                       unset( $dataArray[$termUid][$field]);
+                               }
+                       }
+                       // TODO sort the array by descending length of value string; in combination with the htmlparser this will prevend nesting
+                       // TODO $desc_long = preg_replace('/(\015\012)|(\015)|(\012)/ui','<br />',$row['desc_long']);
+                       
+                       // post processing
+                       $dataArray[$termUid]['term_alt'] = t3lib_div::trimExplode(chr(10),$row['term_alt'],$onlyNonEmptyValues=1);
+                       $dataArray[$termUid]['desc_long'] = $this->cObj->parseFunc($dataArray[$termUid]['desc_long'],$conf='',$ref='< lib.parseFunc_RTE');
+                       // TODO: hook "mappingPostProcessing"
+               }
+
+               return $dataArray;
+       }
+
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/contagged/model/class.tx_contagged_model_mapper.php']) {
+       include_once ($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/contagged/model/class.tx_contagged_model_mapper.php']);
+}
+?>
\ No newline at end of file
diff --git a/model/class.tx_contagged_model_terms.php b/model/class.tx_contagged_model_terms.php
new file mode 100644 (file)
index 0000000..e2f30ff
--- /dev/null
@@ -0,0 +1,157 @@
+<?php
+/***************************************************************
+       *  Copyright notice
+       *
+       *  (c) 2007 Jochen Rau <j.rau@web.de>
+       *  All rights reserved
+       *
+       *  This script is part of the TYPO3 project. The TYPO3 project is
+       *  free software; you can redistribute it and/or modify
+       *  it under the terms of the GNU General Public License as published by
+       *  the Free Software Foundation; either version 2 of the License, or
+       *  (at your option) any later version.
+       *
+       *  The GNU General Public License can be found at
+       *  http://www.gnu.org/copyleft/gpl.html.
+       *
+       *  This script is distributed in the hope that it will be useful,
+       *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+       *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       *  GNU General Public License for more details.
+       *
+       *  This copyright notice MUST APPEAR in all copies of the script!
+       ***************************************************************/
+require_once (t3lib_extMgm::extPath('contagged') . 'model/class.tx_contagged_model_mapper.php');
+
+/**
+       * The model of contagged.
+       * 
+       * @author       Jochen Rau <j.rau@web.de>
+       * @package      TYPO3
+       * @subpackage   tx_contagged_model_terms
+       */
+class tx_contagged_model_terms {
+       var $conf; // the TypoScript configuration array
+       var $cObj;
+       var $controller;
+       var $tablesArray; // array of all tables in the database
+       
+       function tx_contagged_model_terms($controller) {
+               $this->controller = $controller;
+               $this->conf = $controller->conf;
+               $this->cObj = $controller->cObj;
+               
+               // build an array of tables in the database
+               $tablesArray = array();
+               $tablesResult = mysql_list_tables(TYPO3_db);
+               if (!mysql_error()) {
+                       while($table = mysql_fetch_assoc($tablesResult)) {
+                               $this->tablesArray[] = current($table);
+                       }
+               }
+       }
+
+       function getAllTerms() {
+               $typesArray = $this->conf['types.'];
+               $termsArray = array();
+               foreach ($typesArray as $type => $typeConfigArray) {
+
+                       // get the storage pids
+                       if ( $typeConfigArray['storagePids'] ) {
+                               $storagePids = $typeConfigArray['storagePids'];
+                       } elseif ( $this->conf['dataSources.'][$typeConfigArray['dataSource'].'.']['storagePids'] ) {
+                               $storagePids = $this->conf['dataSources.'][$typeConfigArray['dataSource'].'.']['storagePids'];
+                       } elseif ( $this->conf['storagePids'] ) {
+                               $storagePids = $this->conf['storagePids'];
+                       } else {
+                               $storagePids = '';
+                       }
+
+                       $dataSource = $typeConfigArray['dataSource'] ? $typeConfigArray['dataSource'] : 'default';
+
+                       // get an array of all data rows in the configured tables
+                       if ( $storagePids!='' ) {
+                               $termsArray = t3lib_div::array_merge($termsArray,$this->getTermsArray($dataSource,$storagePids));
+                       }
+               }
+               
+               uasort($termsArray,array($this,"sortByTermAscending"));
+               
+               return $termsArray;
+       }
+       
+       function sortByTermAscending($termArrayA,$termArrayB) {
+               // TODO: improve sorting (UTF8, configurable, localized->hook)
+               // strcasecmp() internally converts the two strings it is comparing to lowercase, based on the server locale settings. As such, it
+               // cannot be relied upon to be able to convert appropriate multibyte characters in UTF-8 to lowercase and, depending on the actual
+               // locale, may have internally corrupted the UTF-8 strings it is comparing, having falsely matched byte sequences. It won’t actually
+               // damage the UTF-8 string but the result of the comparison cannot be trusted. (Ref. http://www.phpwact.org/php/i18n/utf-8)
+               // TODO remove; just a hack
+               $termsArray = array($termArrayA['term'],$termArrayB['term']);
+               // $GLOBALS['TSFE']->csConvObj->convArray($termsArray,'utf-8','iso-8859-1');
+               $termsArrayBefore = $termsArray;
+               sort($termsArray,SORT_LOCALE_STRING);
+               $termsArrayAfterwards = $termsArray;
+               // debug($termsArrayBefore,'before');debug($termsArrayAfterwards,'after');
+               if ($termsArrayBefore[0]==$termsArrayAfterwards[0]) {
+                       $result = -1;
+               } else {
+                       $result = 1;
+               }
+
+               return $result;
+       }
+
+       /**
+               * Build an array of the entries in the tables
+               *
+               * @return       An array with the terms an their configuration
+               */
+       function getTermsArray($dataSource,$storagePids='') {
+               $dataArray = array();
+               $terms = array();
+
+               $dataSourceConfigArray = $this->conf['dataSources.'][$dataSource . '.'];
+               $sourceName = $dataSourceConfigArray['sourceName'];
+               
+               // check if the table exists in the database
+               if (t3lib_div::inArray($this->tablesArray,$sourceName) ) {
+                       // Build WHERE-clause
+                       $whereClause = '1=1';
+                       $whereClause .= $storagePids ? ' AND pid IN ('.$storagePids.')' : '';
+                       $whereClause .= $dataSourceConfigArray['hasSysLanguageUid'] ? ' AND (sys_language_uid='.intval($GLOBALS['TSFE']->sys_language_uid) . ' OR sys_language_uid=-1)' : '';
+                       $whereClause .= tslib_cObj::enableFields($sourceName);
+
+                       // execute SQL-query
+                       $result = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+                               '*', // SELECT ...
+                               $sourceName, // FROM ...
+                               $whereClause // WHERE ..
+                               );
+
+                       // map the fields
+                       $mapper = new tx_contagged_model_mapper($this->controller);
+                       $dataArray = $mapper->getDataArray($result,$dataSource);
+               }
+
+               // TODO piVars as a data source
+               //              $result = array(
+               //                      array(
+               //                              'uid' => 5,
+               //                              'pid' => 94,
+               //                              'term' => 'nullam',
+               //                              'term_type' => 'definition',
+               //                              'desc_short' => 'Test'                  
+               //                              )
+               //                      );
+               // krumo($result);
+
+               return $dataArray;
+       }
+
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/contagged/model/class.tx_contagged_model_terms.php']) {
+       include_once ($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/contagged/model/class.tx_contagged_model_terms.php']);
+}
+?>
\ No newline at end of file
diff --git a/pi1/class.tx_contagged_pi1.php b/pi1/class.tx_contagged_pi1.php
new file mode 100644 (file)
index 0000000..05eac6f
--- /dev/null
@@ -0,0 +1,266 @@
+<?php
+/***************************************************************
+       *  Copyright notice
+       *
+       *  (c) 2007 Jochen Rau <j.rau@web.de>
+       *  All rights reserved
+       *
+       *  This script is part of the TYPO3 project. The TYPO3 project is
+       *  free software; you can redistribute it and/or modify
+       *  it under the terms of the GNU General Public License as published by
+       *  the Free Software Foundation; either version 2 of the License, or
+       *  (at your option) any later version.
+       *
+       *  The GNU General Public License can be found at
+       *  http://www.gnu.org/copyleft/gpl.html.
+       *
+       *  This script is distributed in the hope that it will be useful,
+       *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+       *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       *  GNU General Public License for more details.
+       *
+       *  This copyright notice MUST APPEAR in all copies of the script!
+       ***************************************************************/
+
+require_once (PATH_tslib . 'class.tslib_pibase.php');
+require_once (t3lib_extMgm::extPath('contagged') . 'model/class.tx_contagged_model_terms.php');
+
+/**
+       * contagged list plugin
+       * 
+       * @author       Jochen Rau <j.rau@web.de>
+       * @package      TYPO3
+       * @subpackage   tx_contagged_pi1
+       */
+class tx_contagged_pi1 extends tslib_pibase {
+       var $prefixId = 'tx_contagged_pi1'; // same as class name
+       var $scriptRelPath = 'pi1/class.tx_contagged_pi1.php'; // path to this script relative to the extension dir
+       var $extKey = 'contagged'; // the extension key
+       var $templateFile = 'EXT:contagged/pi1/contagged.tmpl';
+       var $conf; // the TypoScript configuration array
+       var $templateCode; // template file
+       var $local_cObj;
+       var $typolinkConf;
+       var $backPid; // pid of the last visited page (from piVars)
+       var $indexChar; // char of the given index the user has clicked on (from piVars)
+       var $termUid;
+
+       /**
+               * main method of the contagged list plugin
+               *
+               * @param        string          $content: The content of the cObj
+               * @param        array           $conf: The configuration
+               * @return       a single or list view of terms
+               */
+       function main($content) {
+               $this->local_cObj = t3lib_div::makeInstance('tslib_cObj');
+               $this->local_cObj->setCurrentVal($GLOBALS['TSFE']->id);
+               $this->pi_loadLL();
+               $this->conf = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_contagged.'];
+               $this->templateCode = $this->cObj->fileResource($this->conf['templateFile']?$this->conf['templateFile']:$this->templateFile);
+               $this->typolinkConf = $this->conf['typolink.'];
+               $this->typolinkConf['parameter.']['current'] = 1;
+               $this->typolinkConf['additionalParams'] = $this->cObj->stdWrap($typolinkConf['additionalParams'], $typolinkConf['additionalParams.']);
+               unset($this->typolinkConf['additionalParams.']);
+               $this->backPid = (int)$this->piVars['backPid'] ? (int)$this->piVars['backPid'] : NULL;
+               $this->indexChar = $this->piVars['index'] ? urldecode($this->piVars['index']) : NULL;
+               $this->termUid = (int)$this->piVars['uid'] ? (int)$this->piVars['uid'] : NULL;
+
+               $model = new tx_contagged_model_terms($this);
+               $this->termsArray = $model->getAllTerms();
+
+               if ( $this->termUid==NULL ) {
+                       $renderFunction = 'renderList';                 
+               } elseif ( $this->termUid!=NULL ) {
+                       $renderFunction = 'renderSingleItemByUid';                                                                      
+               }
+
+               // TODO hook "newRenderFunctionName"
+               
+               if(method_exists($this, $renderFunction)) {
+                       $content .= $this->$renderFunction();
+               }
+
+               return $this->pi_wrapInBaseClass($content);     
+       }
+
+       function renderList() {
+               $subparts = $this->getSubparts('LIST');
+               $this->renderLinks($markerArray,$wrappedSubpartArray);
+               $this->renderIndex($markerArray);
+               foreach ( $this->termsArray as $termUid => $termArray ) {
+                       if ( $termArray['exclude']!=1 && $this->conf['types.'][$termArray['term_type'].'.']['dontListTerms']!=1 ) {
+                               if ( $this->indexChar==NULL || $termArray['indexChar']==$this->indexChar ) {
+                                       $this->renderSingleItem($termUid,$markerArray,$wrappedSubpartArray);
+                                       $subpartArray['###LIST###'] .= $this->cObj->substituteMarkerArrayCached($subparts['item'],$markerArray,$subpartArray,$wrappedSubpartArray);
+                               }
+                       }
+               }
+               $content = $this->cObj->substituteMarkerArrayCached($subparts['template_list'],$markerArray,$subpartArray,$wrappedSubpartArray);
+               
+               return $content;
+       }
+       
+       function renderSingleItemByUid() {
+               $subparts = $this->getSubparts('SINGLE');
+               $this->renderLinks($markerArray,$wrappedSubpartArray);          
+               $this->renderIndex($markerArray);
+               $this->renderSingleItem($this->termUid,$markerArray,$wrappedSubpartArray);
+               $subpartArray['###LIST###'] = $this->cObj->substituteMarkerArrayCached($subparts['item'],$markerArray,$subpartArray,$wrappedSubpartArray);              
+               $content = $this->cObj->substituteMarkerArrayCached($subparts['template_list'],$markerArray,$subpartArray,$wrappedSubpartArray);
+               
+               return $content;
+       }
+       
+       // TODO hook "newRenderFunction"
+       
+       function getSubparts($templateName='LIST') {
+               $subparts['template_list'] = $this->cObj->getSubpart($this->templateCode,'###TEMPLATE_' . $templateName . '###');
+               $subparts['item'] = $this->cObj->getSubpart($subparts['template_list'],'###ITEM###');
+               
+               return $subparts;
+       }
+       
+       function renderLinks(&$markerArray,&$wrappedSubpartArray) {
+               // make "back to..." link
+               if ($this->backPid) {
+                       if($this->conf['addBackLinkDescription']>0) {
+                               $backPage = $this->pi_getRecord('pages', $this->backPid);
+                               $markerArray['###BACK_TO###'] = $this->pi_getLL('backToPage') . " \"" . $backPage['title'] . "\"";
+                       } else {
+                               $markerArray['###BACK_TO###'] = $this->pi_getLL('back');
+                       }
+               } else {
+                       $markerArray['###BACK_TO###'] = '';
+               }
+               unset($typolinkConf);
+               $typolinkConf['parameter'] = $this->backPid;
+               $wrappedSubpartArray['###LINK_BACK_TO###'] = $this->local_cObj->typolinkWrap($typolinkConf);    
+
+               // make "link to all entries"
+               unset($typolinkConf);
+               $typolinkConf = $this->typolinkConf;
+               $allLink = $this->local_cObj->typolink($this->pi_getLL('all'), $typolinkConf);
+               $markerArray['###INDEX_ALL###'] = $allLink;
+
+               // make "to list ..." link
+               unset($typolinkConf);
+               $markerArray['###TO_LIST###'] = $this->pi_getLL('toList');
+               $typolinkConf = $this->typolinkConf;
+               $typolinkConf['parameter.']['wrap'] = "|,".$GLOBALS['TSFE']->type;
+               $wrappedSubpartArray['###LINK_TO_LIST###'] = $this->local_cObj->typolinkWrap($typolinkConf);
+       }
+
+       function renderSingleItem ($termUid,&$markerArray,&$wrappedSubpartArray) {              
+               $termArray = $this->termsArray[$termUid];
+               $typeConfigArray = $this->conf['types.'][$termArray['term_type'] . '.'];
+
+               $markerArray['###TERM_TYPE###'] = $typeConfigArray['label'];
+               $markerArray['###TERM###'] = $termArray['term'];
+               $markerArray['###TERM_MAIN###'] = $termArray['term_main'];
+               $markerArray['###TERM_ALT###'] = $termArray['term_alt']?implode(', ',$termArray['term_alt']):$this->pi_getLL('na');
+               $markerArray['###TERM_REPLACE###'] = $termArray['term_replace']?$termArray['term_replace']:$this->pi_getLL('na');
+               $markerArray['###DESC_SHORT###'] = $termArray['desc_short']?$termArray['desc_short']:$this->pi_getLL('na');
+               $markerArray['###DESC_LONG###'] = $termArray['desc_long']?$termArray['desc_long']:$this->pi_getLL('na');
+               $markerArray['###TERM_LANG###'] = $this->pi_getLL('lang.'.$termArray['term_lang'])?$this->pi_getLL('lang.'.$termArray['term_lang']):$this->pi_getLL('na');
+
+               $labelWrap['noTrimWrap'] = $typeConfigArray['labelWrap1']?$typeConfigArray['labelWrap1']:$this->conf['labelWrap1'];
+               $markerArray['###TERM_TYPE_LABEL###'] = $markerArray['###TERM_TYPE###']?$this->local_cObj->stdWrap($this->pi_getLL('term_type'),$labelWrap):'';
+               $markerArray['###TERM_LABEL###'] = $this->local_cObj->stdWrap($this->pi_getLL('term'),$labelWrap);
+               $markerArray['###TERM_MAIN_LABEL###'] = $this->local_cObj->stdWrap($this->pi_getLL('term_main'),$labelWrap);
+               $markerArray['###TERM_ALT_LABEL###'] = $markerArray['###TERM_ALT###']?$this->local_cObj->stdWrap($this->pi_getLL('term_alt'),$labelWrap):'';
+               $markerArray['###TERM_REPLACE_LABEL###'] = $markerArray['###TERM_REPLACE###']?$this->local_cObj->stdWrap($this->pi_getLL('term_replace'),$labelWrap):'';
+               $markerArray['###DESC_SHORT_LABEL###'] = $markerArray['###DESC_SHORT###']?$this->local_cObj->stdWrap($this->pi_getLL('desc_short'),$labelWrap):'';
+               $markerArray['###DESC_LONG_LABEL###'] = $markerArray['###DESC_LONG###']?$this->local_cObj->stdWrap($this->pi_getLL('desc_long'),$labelWrap):'';
+               $markerArray['###TERM_LANG_LABEL###'] = $markerArray['###TERM_LANG###']?$this->local_cObj->stdWrap($this->pi_getLL('term_lang'),$labelWrap):'';
+
+               // make "more..." link
+               $markerArray['###DETAILS###'] = $this->pi_getLL('details');
+               unset($typolinkConf);
+               $typolinkConf = $this->typolinkConf;
+               $typolinkConf['additionalParams'] .= '&' . $this->prefixId . '[uid]=' . $termUid;
+               $typolinkConf['parameter.']['wrap'] = "|,".$GLOBALS['TSFE']->type;
+               $wrappedSubpartArray['###LINK_DETAILS###'] = $this->local_cObj->typolinkWrap($typolinkConf);
+       }
+
+       function renderIndex (&$markerArray) {
+               $subparts = array();
+               $subparts['template_index'] = $this->cObj->getSubpart($this->templateCode,'###TEMPLATE_INDEX###');
+               $subparts['item'] = $this->cObj->getSubpart($subparts['template_index'],'###ITEM###');          
+
+               $indexArray = $this->getIndexArray();
+
+               // wrap index chars and add a class attribute if there is a selected index char.
+               foreach ($indexArray as $indexChar => $link) {
+                       $cssClass = '';
+                       if ($this->piVars['index']==$indexChar) {
+                               $cssClass = " class='tx-contagged-act'";
+                       }
+                       if ($link) {
+                               $markerArray['###SINGLE_CHAR###'] = '<span' . $cssClass . '>' . $link . '</span>';
+                       } elseif ($this->conf['showOnlyMatchedIndexChars']==0) {
+                               $markerArray['###SINGLE_CHAR###'] = '<span' . $cssClass . '>' . $indexChar . '</span>';
+                       } else {
+                               $markerArray['###SINGLE_CHAR###'] = '';
+                       }
+                       $subpartArray['###INDEX_CONTENT###'] .= $this->cObj->substituteMarkerArrayCached($subparts['item'], $markerArray);
+               }
+
+               // // make "link to all entries"
+               // unset($typolinkConf);
+               // $typolinkConf = $this->typolinkConf;
+               // $allLink = $this->local_cObj->typolink($this->pi_getLL('all'), $typolinkConf);
+               // $markerArray['###INDEX_ALL###'] = $allLink;
+
+               $markerArray['###INDEX###'] = $this->cObj->substituteMarkerArrayCached($subparts['template_index'], $markerArray, $subpartArray);
+       }
+
+       function getIndexArray() {
+               // Get localized index chars.
+               foreach (t3lib_div::trimExplode(',', $this->pi_getLL('indexChars')) as $key => $value) {
+                       $subCharArray = t3lib_div::trimExplode('|', $value);
+                       $indexArray[$subCharArray[0]] = NULL;
+               foreach($subCharArray as $subChar) {
+                   $reverseIndexArray[$subChar] = $subCharArray[0];
+               }
+               }
+
+               // The configuered subchars like Ö will be linked as O (see documentation and file "locallang.xml").
+               unset($typolinkConf);
+               $typolinkConf = $this->typolinkConf;
+               foreach ($this->termsArray as $termUid => $termArray) {
+                       if ( $termArray['exclude']!=1 && $this->conf['types.'][$termArray['term_type'].'.']['dontListTerms']!=1 ) {
+                               foreach ($reverseIndexArray as $subChar => $indexChar) {
+                                       // debug(preg_quote($subChar),$termArray['term']);
+                                       // debug(preg_match('/^'.preg_quote($subChar).'/ui',$termArray['term']));
+                                       if ( preg_match('/^'.preg_quote($subChar).'/ui',$termArray['term'])>0 ) {
+                                               $typolinkConf['additionalParams'] = '&' . $this->prefixId . '[index]=' . $indexChar;
+                                               $indexArray[$indexChar] = $this->local_cObj->typolink($indexChar, $typolinkConf);
+                                               $this->termsArray[$termUid]['indexChar'] = $indexChar;
+                                       }
+                               }
+                               // If the term matches no given index char, crate one if desired and add it to the index
+                               if ( $this->termsArray[$termUid]['indexChar']=='' && $this->conf['autoAddIndexChars']==1 ) {
+                                       // get the first char of the term (UTF8)
+                                       // TODO: Make the RegEx configurable to make ZIP-Codes possible
+                                       preg_match('/^./u',$termArray['term'],$match);
+                                       $newIndexChar = $match[0];
+                                       $indexArray[$newIndexChar] = NULL;
+                                       $typolinkConf['additionalParams'] = '&' . $this->prefixId . '[index]=' . urlencode($newIndexChar);
+                                       $indexArray[$newIndexChar] = $this->local_cObj->typolink($newIndexChar, $typolinkConf);
+                                       $this->termsArray[$termUid]['indexChar'] = $newIndexChar;
+                               }
+                       }
+               }
+
+               // TODO Sorting of the index (UTF8)
+               ksort($indexArray,SORT_LOCALE_STRING);
+               
+               return $indexArray;
+       }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/contagged/pi1/class.tx_contagged_pi1.php']) {
+       include_once ($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/contagged/pi1/class.tx_contagged_pi1.php']);
+}      
+?>
\ No newline at end of file
diff --git a/pi1/contagged.tmpl b/pi1/contagged.tmpl
new file mode 100644 (file)
index 0000000..2814d30
--- /dev/null
@@ -0,0 +1,89 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+       <!--
+               IMPORTANT: The stylesheet link below is only for testing the template file directly in a browser while editing it.
+               On the website the css styles for contagged have to be include with the static TS template "default CSS style (contagged)" or
+               with an external file (see contagged/static/css/setup.css) which you include via TypoSript in the "page" object.
+
+       -->
+       <title>contagged example template</title>
+       <link href="../static/css/setup.css" rel="stylesheet" type="text/css" />
+</head>
+
+<body>
+       <h1>CONTAGGED TEMPLATES</h1>
+
+       <h2>Markers</h2>
+       <pre>
+               ###TERM_LABEL### ###TERM###
+               ###TERM_TYPE_LABEL######TERM_TYPE###
+               ###TERM_MAIN_LABEL######TERM_MAIN###
+               ###TERM_ALT_LABEL######TERM_ALT###
+               ###TERM_REPLACE_LABEL######TERM_REPLACE###
+               ###DESC_SHORT_LABEL######DESC_SHORT###
+               ###DESC_LONG_LABEL######DESC_LONG###
+               ###TERM_LANG_LABEL######TERM_LANG###
+       </pre>
+
+
+       <h2>TEMPLATE_INDEX</h2>
+
+       <!-- ###TEMPLATE_INDEX### begin -->
+       <div class="tx-contagged-index">
+               ###INDEX_ALL### 
+               <!-- ###INDEX_CONTENT###-->
+                       <!-- ###ITEM###-->              
+                               ###SINGLE_CHAR###
+                       <!-- ###ITEM### begin -->
+               <!-- ###INDEX_CONTENT###-->
+       </div>
+       <!-- ###TEMPLATE_INDEX### end -->
+
+
+
+       <h2>TEMPLATE_LIST</h2>
+
+       <!-- ###TEMPLATE_LIST### begin
+               This is the template to display a list of terms
+       -->
+       ###INDEX###
+       <dl class="tx-contagged-list">
+               <!-- ###LIST###-->
+                       <!-- ###ITEM###-->              
+                               <dt>###TERM###</dt>
+                               <dd>###TERM_ALT_LABEL######TERM_ALT###</dd>
+                               <dd>###DESC_SHORT###</dd>
+                               <dd class="tx-contagged-navlink"><!--###LINK_DETAILS###-->###DETAILS###<!--###LINK_DETAILS###--></dd>
+                       <!-- ###ITEM###-->
+               <!-- ###LIST###-->
+       </dl>
+       ###INDEX###
+       <!-- ###TEMPLATE_LIST### end -->
+
+       <h2>TEMPLATE_SINGLE</h2>
+
+       <!-- ###TEMPLATE_SINGLE### begin
+               This is the template to display a single term
+       -->
+       <div class="tx-contagged-navlink"><!--###LINK_TO_LIST###-->###TO_LIST###<!--###LINK_TO_LIST###--></div>
+       <div class="tx-contagged-navlink"><!--###LINK_BACK_TO###-->###BACK_TO###<!--###LINK_BACK_TO###--></div>
+       <dl class="tx-contagged-single">
+               <!-- ###ITEM### begin-->                
+               <dt>###TERM###</dt>
+               <dd>###TERM_TYPE_LABEL######TERM_TYPE###</dd>
+               <dd>###TERM_MAIN_LABEL######TERM_MAIN###</dd>
+               <dd>###TERM_ALT_LABEL######TERM_ALT###</dd>
+               <dd>###TERM_REPLACE_LABEL######TERM_REPLACE###</dd>
+               <dd>###DESC_SHORT_LABEL######DESC_SHORT###</dd>
+               <dd>###DESC_LONG_LABEL######DESC_LONG###</dd>
+               <dd>###TERM_LANG_LABEL######TERM_LANG###</dd>
+               <!-- ###ITEM### end-->
+       </dl>
+       <div class="tx-contagged-navlink"><!--###LINK_TO_LIST###-->###TO_LIST###<!--###LINK_TO_LIST###--></div>
+       <div class="tx-contagged-navlink"><!--###LINK_BACK_TO###-->###BACK_TO###<!--###LINK_BACK_TO###--></div>
+       <!-- ###TEMPLATE_SINGLE### end -->
+
+</body>
+</html>
diff --git a/pi1/locallang.xml b/pi1/locallang.xml
new file mode 100644 (file)
index 0000000..067d79d
--- /dev/null
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<T3locallang>
+       <meta type="array">
+               <description>language labels for contagged FE plugin</description>
+               <type>database</type>
+               <fileId>EXT:contagged/pi1/locallang.xml</fileId>
+       </meta>
+       <data type="array">
+               <languageKey index="default" type="array">
+                       <label index="header">Glossary</label>
+                       <label index="indexChars">A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z</label>
+                       <label index="na">-</label>
+                       <label index="details">more details</label>
+                       <label index="all">all items</label>
+                       <label index="toList">all items</label>
+                       <label index="back">back</label>
+                       <label index="backToPage">back to page</label>
+                       <label index="term_type">Type of term</label>
+                       <label index="term">Term</label>
+                       <label index="term_main">Term</label>
+                       <label index="term_alt">Alternative Terms</label>
+                       <label index="term_replace">Replaced with</label>
+                       <label index="term_lang">Term Language</label>
+                       <label index="desc_short">Short Description</label>
+                       <label index="desc_long">Long Description</label>
+                       <label index="lang.en">en.</label>
+                       <label index="lang.fr">fr.</label>
+                       <label index="lang.de">ger.</label>
+                       <label index="lang.it">it.</label>
+                       <label index="lang.es">span.</label>
+               </languageKey>
+               <languageKey index="de" type="array">
+                       <label index="header">Glossar</label>
+                       <label index="indexChars">A|Ä|AE,B,C,D,E,F,G,H,I,J,K,L,M,N,O|Ö|OE,P,Q,R,S,T,U|Ü|UE,V,W,X,Y,Z</label>
+                       <label index="na">-</label>
+                       <label index="details">mehr Details</label>
+                       <label index="all">alle Einträge</label>
+                       <label index="toList">alle Einträge</label>
+                       <label index="back">zurück</label>
+                       <label index="backToPage">zurück zur Seite</label>
+                       <label index="term_type">Art des Ausdrucks</label>
+                       <label index="term">Ausdruck</label>
+                       <label index="term_main">Ausdruck</label>
+                       <label index="term_alt">Alternativen</label>
+                       <label index="term_replace">Ersetzt durch</label>
+                       <label index="term_lang">Sprache</label>
+                       <label index="desc_short">Kurzbeschreibung</label>
+                       <label index="desc_long">Ausführliche Beschreibung</label>
+                       <label index="lang.en">engl.</label>
+                       <label index="lang.fr">franz.</label>
+                       <label index="lang.de">dt.</label>
+                       <label index="lang.it">ital.</label>
+                       <label index="lang.es">span.</label>
+               </languageKey>
+       </data>
+</T3locallang>
\ No newline at end of file
diff --git a/tca.php b/tca.php
index 7ca36c4..a32eaff 100644 (file)
--- a/tca.php
+++ b/tca.php
@@ -121,9 +121,10 @@ $TCA["tx_contagged_terms"] = array (
                                "label" => "LLL:EXT:contagged/locallang_db.xml:tx_contagged_terms.term_type",
                                "config" => Array (
                                        "type" => "select",
-                                       "itemsProcFunc" => "user_addItemsToTCA",
+                                       "itemsProcFunc" => "user_addTermTypes",
                                        "size" => 1,
                                        "maxitems" => 1,
+                                       "disableNoMatchingValueElement" => 1,
                                )
                        ),
                        "term_lang" => Array (          
@@ -131,6 +132,7 @@ $TCA["tx_contagged_terms"] = array (
                                "label" => "LLL:EXT:contagged/locallang_db.xml:tx_contagged_terms.term_lang",           
                                "config" => Array (
                                        "type" => "select",
+// TODO Make selectable languages configurable. 
                                        "items" => Array (
                                                Array("LLL:EXT:contagged/locallang_db.xml:tx_contagged_terms.term_lang.I.0", ""),
                                                Array("LLL:EXT:contagged/locallang_db.xml:tx_contagged_terms.term_lang.I.1", "en"),
@@ -215,38 +217,46 @@ $TCA["tx_contagged_terms"] = array (
                        "1" => array("showitem" => "starttime, endtime, fe_group")
                )
        );
-       
 require_once (PATH_t3lib.'class.t3lib_page.php');
 require_once (PATH_t3lib.'class.t3lib_tstemplate.php');
 require_once (PATH_t3lib.'class.t3lib_tsparser_ext.php');
-
-function user_addItemsToTCA(&$params,&$pObj) {
-
+require_once (PATH_typo3.'sysext/lang/lang.php');
+       
+function user_addTermTypes(&$params,&$pObj) {
        // get extension configuration
        $extConfArray = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['contagged']);
-       if ( intval($extConfArray['mainConfigStorageUid']) > 0 ) {
-               $mainConfigStorageUid = intval($extConfArray['mainConfigStorageUid']);
+       if ( (int)$extConfArray['mainConfigStoragePid']>0 ) {
+               $mainConfigStoragePid = intval($extConfArray['mainConfigStoragePid']);
        } else {
                // TODO parse static setup
        }
-
-               
-       $sysPageObj = t3lib_div::makeInstance('t3lib_pageSelect');
-       // FIXME: pageUid is static; make it configurable
-       $rootLine = $sysPageObj->getRootLine($mainConfigStorageUid);
+       
+       $rootLine = t3lib_BEfunc::BEgetRootLine($mainConfigStoragePid);
        $TSObj = t3lib_div::makeInstance('t3lib_tsparser_ext');
        $TSObj->tt_track = 0;
        $TSObj->init();
        $TSObj->runThroughTemplates($rootLine);
        $TSObj->generateConfig();
        $conf = $TSObj->setup['plugin.']['tx_contagged.'];
-       
-       // 
-       if ($conf['types.']) {
+
+       // make localized labels        
+       $LANG = t3lib_div::makeInstance('language');
+//     $LANG->init($BE_USER->uc['lang']); // FIXIT This doesn't work because no BE-User is configured at this time of execution. Any suggestions?
+       $LANG->init($conf['backendLanguage']); // a quick solution
+       $LOCAL_LANG_ARRAY = array();
+       if (!empty($conf['types.'])) {
                foreach ($conf['types.'] as $typeName => $typeConfigArray ) {
-                       $params['items'][]= Array( $typeConfigArray['label'], substr($typeName,0,-1) );
+                       unset($label);
+                       if ( !$typeConfigArray['hideSelection']>0 ) {
+                               $label['default'] = $typeConfigArray['label.']['default'];
+                               $label['default'] = $typeConfigArray['label'];
+                               foreach ($label as $langKey => $labelText) {
+                                       $LOCAL_LANG_ARRAY[$langKey] = array('label'=>$labelText);
+                               }
+                               $label = array_merge($label,$typeConfigArray['label.']);
+                               $params['items'][]= Array( $LANG->getLLL('label',$LOCAL_LANG_ARRAY,1), substr($typeName,0,-1) );
+                       }
                }
        }
-
 }
 ?>
\ No newline at end of file