a06a9cf0711e64910b6f86cc1e58305f3a70206c
[TYPO3CMS/Extensions/contagged.git] / pi1 / class.tx_contagged_pi1.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2007 Jochen Rau <j.rau@web.de>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 require_once (PATH_tslib . 'class.tslib_pibase.php');
26 require_once (t3lib_extMgm::extPath('contagged') . 'model/class.tx_contagged_model_terms.php');
27 require_once (t3lib_extMgm::extPath('contagged') . 'model/class.tx_contagged_model_mapper.php');
28
29 /**
30 * contagged list plugin
31 *
32 * @author Jochen Rau <j.rau@web.de>
33 * @package TYPO3
34 * @subpackage tx_contagged_pi1
35 */
36 class tx_contagged_pi1 extends tslib_pibase {
37 var $prefixId = 'tx_contagged_pi1'; // same as class name
38 var $scriptRelPath = 'pi1/class.tx_contagged_pi1.php'; // path to this script relative to the extension dir
39 var $extKey = 'contagged'; // the extension key
40 var $templateFile = 'EXT:contagged/pi1/contagged.tmpl';
41 var $conf; // the TypoScript configuration array
42 var $templateCode; // template file
43 var $local_cObj;
44 var $typolinkConf;
45 var $backPid; // pid of the last visited page (from piVars)
46 var $indexChar; // char of the given index the user has clicked on (from piVars)
47
48
49 /**
50 * main method of the contagged list plugin
51 *
52 * @param string $content: The content of the cObj
53 * @param array $conf: The configuration
54 * @return string a single or list view of terms
55 */
56 function main($content) {
57 $this->local_cObj = t3lib_div::makeInstance('tslib_cObj');
58 $this->local_cObj->setCurrentVal($GLOBALS['TSFE']->id);
59 $this->pi_loadLL();
60 $this->conf = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_contagged.'];
61 $this->templateCode = $this->cObj->fileResource($this->conf['templateFile']?$this->conf['templateFile']:$this->templateFile);
62 $this->typolinkConf = $this->conf['typolink.'];
63 $this->typolinkConf['parameter.']['current'] = 1;
64 $this->typolinkConf['additionalParams'] = $this->cObj->stdWrap($typolinkConf['additionalParams'], $typolinkConf['additionalParams.']);
65 unset($this->typolinkConf['additionalParams.']);
66 $this->backPid = $this->piVars['backPid'] ? intval($this->piVars['backPid']) : NULL;
67 $this->indexChar = $this->piVars['index'] ? urldecode($this->piVars['index']) : NULL;
68 if ( !is_null($this->piVars['key']) ) {
69 $termKey = (int)$this->piVars['key'];
70 }
71 $sword = $this->piVars['sword'] ? urldecode($this->piVars['sword']) : NULL;
72
73 // get an array of all type configurations
74 $this->typesArray = $this->conf['types.'];
75
76 $this->mapper = new tx_contagged_model_mapper($this);
77
78 // get the model (an associated array of terms)
79 $this->model = new tx_contagged_model_terms($this);
80 $this->termsArray = $this->model->findAllTerms();
81
82 if ( is_null($termKey) && is_null($sword) ) {
83 $content .= $this->renderList();
84 } elseif ( is_null($termKey) && !is_null($sword) ) {
85 $content .= $this->renderListBySword($sword);
86 } elseif ( !is_null($termKey) ) {
87 $content .= $this->renderSingleItemByKey($termKey);
88 }
89
90 // TODO hook "newRenderFunctionName"
91
92 $content = $this->removeUnfilledMarker($content);
93
94 return $this->pi_wrapInBaseClass($content);
95 }
96
97 /**
98 * Renders the list of terms
99 *
100 * @return $string The list as HTML
101 */
102 function renderList() {
103 $subparts = $this->getSubparts('LIST');
104 $this->renderLinks($markerArray,$wrappedSubpartArray);
105 $this->renderIndex($markerArray);
106 foreach ( $this->termsArray as $termKey => $termArray ) {
107 if ( $termArray['exclude']!=1 && $this->conf['types.'][$termArray['term_type'].'.']['dontListTerms']!=1 && in_array($GLOBALS['TSFE']->id,$termArray['listPages']) ) {
108 if ( $this->indexChar==NULL || $termArray['indexChar']==$this->indexChar ) {
109 $this->renderSingleItem($termKey,$markerArray,$wrappedSubpartArray);
110 $subpartArray['###LIST###'] .= $this->cObj->substituteMarkerArrayCached($subparts['item'],$markerArray,$subpartArray,$wrappedSubpartArray);
111 }
112 }
113 }
114 $content = $this->cObj->substituteMarkerArrayCached($subparts['template_list'],$markerArray,$subpartArray,$wrappedSubpartArray);
115
116 return $content;
117 }
118
119 function renderListBySword($sword) {
120 $subparts = $this->getSubparts('LIST');
121 $this->renderLinks($markerArray,$wrappedSubpartArray);
122 $this->renderIndex($markerArray);
123 foreach ( $this->termsArray as $termKey => $termArray ) {
124 if ( $termArray['exclude']!=1 && $this->conf['types.'][$termArray['term_type'].'.']['dontListTerms']!=1 ) {
125 if ( $this->indexChar==NULL || $termArray['indexChar']==$this->indexChar ) {
126 $fieldsToSearch = t3lib_div::trimExplode(',',$this->conf['fieldsToSearch'] );
127 foreach ($fieldsToSearch as $field) {
128 // TODO make arrays searchable
129 $swordMatched = preg_match('/'.preg_quote($sword,'/').'/Uui',$termArray[$field]) ? TRUE : FALSE;
130 }
131 if ( $swordMatched ) {
132 $this->renderSingleItem($termKey,$markerArray,$wrappedSubpartArray);
133 $subpartArray['###LIST###'] .= $this->cObj->substituteMarkerArrayCached($subparts['item'],$markerArray,$subpartArray,$wrappedSubpartArray);
134 }
135 }
136 }
137 }
138 // TODO Display warning if result is empty
139 // if (!$content) {
140 // $subpartArray['###LIST###'] = "No items.";
141 // }
142 $content = $this->cObj->substituteMarkerArrayCached($subparts['template_list'],$markerArray,$subpartArray,$wrappedSubpartArray);
143
144 return $content;
145 }
146
147 function renderSingleItemByKey($termKey) {
148 $subparts = $this->getSubparts('SINGLE');
149 $this->renderLinks($markerArray,$wrappedSubpartArray);
150 $this->renderIndex($markerArray);
151 $this->renderSingleItem($termKey,$markerArray,$wrappedSubpartArray);
152 $subpartArray['###LIST###'] = $this->cObj->substituteMarkerArrayCached($subparts['item'],$markerArray,$subpartArray,$wrappedSubpartArray);
153 $content = $this->cObj->substituteMarkerArrayCached($subparts['template_list'],$markerArray,$subpartArray,$wrappedSubpartArray);
154
155 return $content;
156 }
157
158 // TODO hook "newRenderFunction"
159
160 function getSubparts($templateName='LIST') {
161 $subparts['template_list'] = $this->cObj->getSubpart($this->templateCode,'###TEMPLATE_' . $templateName . '###');
162 $subparts['item'] = $this->cObj->getSubpart($subparts['template_list'],'###ITEM###');
163
164 return $subparts;
165 }
166
167 function renderLinks(&$markerArray,&$wrappedSubpartArray) {
168 // make "back to..." link
169 if ($this->backPid) {
170 if($this->conf['addBackLinkDescription']>0) {
171 $backPage = $this->pi_getRecord('pages', $this->backPid);
172 $markerArray['###BACK_TO###'] = $this->pi_getLL('backToPage') . " \"" . $backPage['title'] . "\"";
173 } else {
174 $markerArray['###BACK_TO###'] = $this->pi_getLL('back');
175 }
176 } else {
177 $markerArray['###BACK_TO###'] = '';
178 }
179 unset($typolinkConf);
180 $typolinkConf['parameter'] = $this->backPid;
181 $wrappedSubpartArray['###LINK_BACK_TO###'] = $this->local_cObj->typolinkWrap($typolinkConf);
182
183 // make "link to all entries"
184 $markerArray['###INDEX_ALL###'] = $this->pi_linkTP($this->pi_getLL('all'));
185
186 // make "to list ..." link
187 unset($typolinkConf);
188 $markerArray['###TO_LIST###'] = $this->pi_getLL('toList');
189 $typolinkConf = $this->typolinkConf;
190 $typolinkConf['parameter.']['wrap'] = "|,".$GLOBALS['TSFE']->type;
191 $wrappedSubpartArray['###LINK_TO_LIST###'] = $this->local_cObj->typolinkWrap($typolinkConf);
192 }
193
194 /**
195 * [Describe function...]
196 *
197 * @param [type] $termKey: ...
198 * @param [type] $markerArray: ...
199 * @param [type] $wrappedSubpartArray: ...
200 * @return [type] ...
201 */
202 function renderSingleItem ($termKey,&$markerArray,&$wrappedSubpartArray) {
203 $termArray = $this->termsArray[$termKey];
204 $typeConfigArray = $this->conf['types.'][$termArray['term_type'] . '.'];
205
206 // TODO Add a search box
207 // $markerArray['###SEARCHBOX###'] = $this->pi_list_searchBox();
208 $markerArray['###SEARCHBOX###'] = '';
209
210 $markerArray['###TERM_TYPE###'] = $typeConfigArray['label'];
211 $markerArray['###TERM###'] = $this->cObj->editIcons($termArray['term'],'tx_contagged_terms:term_main,term_alt,term_type,term_lang,term_replace,desc_short,desc_long,link,exclude',$editIconsConf,'tx_contagged_terms:'.$termArray['uid']);
212 $markerArray['###TERM_MAIN###'] = $termArray['term_main'];
213 $markerArray['###TERM_ALT###'] = $termArray['term_alt']?implode(', ',$termArray['term_alt']):$this->pi_getLL('na');
214 $markerArray['###TERM_REPLACE###'] = $termArray['term_replace']?$termArray['term_replace']:$this->pi_getLL('na');
215 $markerArray['###DESC_SHORT###'] = $termArray['desc_short']?$termArray['desc_short']:$this->pi_getLL('na');
216 $markerArray['###DESC_LONG###'] = $termArray['desc_long']?$termArray['desc_long']:$this->pi_getLL('na');
217 $markerArray['###IMAGES###'] = $this->getImages($termArray);
218 $markerArray['###RELATED###'] = $this->getRelated($termArray);
219 $markerArray['###TERM_LANG###'] = $this->pi_getLL('lang.'.$termArray['term_lang'])?$this->pi_getLL('lang.'.$termArray['term_lang']):$this->pi_getLL('na');
220
221 $labelWrap['noTrimWrap'] = $typeConfigArray['labelWrap1']?$typeConfigArray['labelWrap1']:$this->conf['labelWrap1'];
222 $markerArray['###TERM_TYPE_LABEL###'] = $markerArray['###TERM_TYPE###']?$this->local_cObj->stdWrap($this->pi_getLL('term_type'),$labelWrap):'';
223 $markerArray['###TERM_LABEL###'] = $this->local_cObj->stdWrap($this->pi_getLL('term'),$labelWrap);
224 $markerArray['###TERM_MAIN_LABEL###'] = $this->local_cObj->stdWrap($this->pi_getLL('term_main'),$labelWrap);
225 $markerArray['###TERM_ALT_LABEL###'] = $markerArray['###TERM_ALT###']?$this->local_cObj->stdWrap($this->pi_getLL('term_alt'),$labelWrap):'';
226 $markerArray['###TERM_REPLACE_LABEL###'] = $markerArray['###TERM_REPLACE###']?$this->local_cObj->stdWrap($this->pi_getLL('term_replace'),$labelWrap):'';
227 $markerArray['###DESC_SHORT_LABEL###'] = $markerArray['###DESC_SHORT###']?$this->local_cObj->stdWrap($this->pi_getLL('desc_short'),$labelWrap):'';
228 $markerArray['###DESC_LONG_LABEL###'] = $markerArray['###DESC_LONG###']?$this->local_cObj->stdWrap($this->pi_getLL('desc_long'),$labelWrap):'';
229 $markerArray['###RELATED_LABEL###'] = $markerArray['###RELATED###']?$this->local_cObj->stdWrap($this->pi_getLL('related'),$labelWrap):'';
230 $markerArray['###IMAGES_LABEL###'] = $markerArray['###IMAGES###']?$this->local_cObj->stdWrap($this->pi_getLL('images'),$labelWrap):'';
231 $markerArray['###TERM_LANG_LABEL###'] = $markerArray['###TERM_LANG###']?$this->local_cObj->stdWrap($this->pi_getLL('term_lang'),$labelWrap):'';
232
233 // make "more..." link
234 $markerArray['###DETAILS###'] = $this->pi_getLL('details');
235 unset($typolinkConf);
236 $typolinkConf = $this->typolinkConf;
237 $typolinkConf['additionalParams'] .= '&' . $this->prefixId . '[key]=' . $termKey;
238 $typolinkConf['parameter.']['wrap'] = "|,".$GLOBALS['TSFE']->type;
239 $wrappedSubpartArray['###LINK_DETAILS###'] = $this->local_cObj->typolinkWrap($typolinkConf);
240 }
241
242 function getRelated($term) {
243 $relatedCode = '';
244 if (is_array($term['related'])) {
245 foreach ($term['related'] as $termReference) {
246 $result = $this->model->findTermByUid($termReference['sourceName'], $termReference['uid']);
247 $key = key($result);
248 $relatedTerm = current($result);
249 $typolinkConf = $this->typolinkConf;
250 $typolinkConf['additionalParams'] .= '&' . $this->prefixId . '[key]=' . $key;
251 $typolinkConf['parameter.']['wrap'] = "|,".$GLOBALS['TSFE']->type;
252 $relatedCode .= '<div>' . $this->local_cObj->typoLink($relatedTerm['term'], $typolinkConf) . '</div>';
253 }
254 }
255 // debug($relatedTerms);
256 return $this->local_cObj->wrap(trim($relatedCode), $this->conf['related.']['wrapIfAny']);
257 }
258
259 function getImages($termArray) {
260 $imagesConf = $this->conf['images.']['single.'];
261 $images = t3lib_div::trimExplode(',', $termArray['image'], 1);
262 $imagesCaption = t3lib_div::trimExplode(chr(10), $termArray['imagecaption']);
263 $imagesAltText = t3lib_div::trimExplode(chr(10), $termArray['imagealt']);
264 $imagesTitleText = t3lib_div::trimExplode(chr(10), $termArray['imagetitle']);
265 $imagesCode = '';
266 foreach ($images as $key => $image) {
267 $imagesConf['image.']['altText'] = $imagesAltText[$key];
268 $imagesConf['image.']['titleText'] = $imagesTitleText[$key];
269 $imagesConf['image.']['file'] = 'uploads/pics/' . $image;
270 $imagesCode .= $this->local_cObj->IMAGE($imagesConf['image.']) . $this->local_cObj->stdWrap($imagesCaption[$key], $this->conf['images.']['caption.']['stdWrap.']);
271 }
272 return $this->local_cObj->wrap(trim($imagesCode), $this->conf['images.']['wrapIfAny']);
273 }
274
275 function renderIndex (&$markerArray) {
276 $subparts = array();
277 $subparts['template_index'] = $this->cObj->getSubpart($this->templateCode,'###TEMPLATE_INDEX###');
278 $subparts['item'] = $this->cObj->getSubpart($subparts['template_index'],'###ITEM###');
279
280 $indexArray = $this->getIndexArray();
281
282 // wrap index chars and add a class attribute if there is a selected index char.
283 foreach ($indexArray as $indexChar => $link) {
284 $cssClass = '';
285 if ($this->piVars['index']==$indexChar) {
286 $cssClass = " class='tx-contagged-act'";
287 }
288 if ($link) {
289 $markerArray['###SINGLE_CHAR###'] = '<span' . $cssClass . '>' . $link . '</span>';
290 } elseif ($this->conf['showOnlyMatchedIndexChars']==0) {
291 $markerArray['###SINGLE_CHAR###'] = '<span' . $cssClass . '>' . $indexChar . '</span>';
292 } else {
293 $markerArray['###SINGLE_CHAR###'] = '';
294 }
295 $subpartArray['###INDEX_CONTENT###'] .= $this->cObj->substituteMarkerArrayCached($subparts['item'], $markerArray);
296 }
297
298 // // make "link to all entries"
299 // unset($typolinkConf);
300 // $typolinkConf = $this->typolinkConf;
301 // $allLink = $this->local_cObj->typolink($this->pi_getLL('all'), $typolinkConf);
302 // $markerArray['###INDEX_ALL###'] = $allLink;
303
304 $markerArray['###INDEX###'] = $this->cObj->substituteMarkerArrayCached($subparts['template_index'], $markerArray, $subpartArray);
305 }
306
307 function getIndexArray() {
308 // Get localized index chars.
309 foreach (t3lib_div::trimExplode(',', $this->pi_getLL('indexChars')) as $key => $value) {
310 $subCharArray = t3lib_div::trimExplode('|', $value);
311 $indexArray[$subCharArray[0]] = NULL;
312 foreach($subCharArray as $subChar) {
313 $reverseIndexArray[$subChar] = $subCharArray[0];
314 }
315 }
316
317 // The configuered subchars like Ö will be linked as O (see documentation and file "locallang.xml").
318 unset($typolinkConf);
319 $typolinkConf = $this->typolinkConf;
320 foreach ($this->termsArray as $termKey => $termArray) {
321 if ( $termArray['exclude']!=1 && $this->conf['types.'][$termArray['term_type'].'.']['dontListTerms']!=1 && in_array($GLOBALS['TSFE']->id,$termArray['listPages']) ) {
322 $sortField = $this->model->getSortField($termArray);
323 // debug($sortField);
324 foreach ($reverseIndexArray as $subChar => $indexChar) {
325 // debug(preg_quote($subChar),$termArray['term']);
326 // debug(preg_match('/^'.preg_quote($subChar).'/ui',$termArray['term']));
327 if ( preg_match('/^'.preg_quote($subChar).'/' . $this->conf['modifier'],$termArray[$sortField])>0 ) {
328 $typolinkConf['additionalParams'] = '&' . $this->prefixId . '[index]=' . $indexChar;
329 $indexArray[$indexChar] = $this->local_cObj->typolink($indexChar, $typolinkConf);
330 $this->termsArray[$termKey]['indexChar'] = $indexChar;
331 }
332 }
333 // If the term matches no given index char, crate one if desired and add it to the index
334 if ( $this->termsArray[$termKey]['indexChar']=='' && $this->conf['autoAddIndexChars']==1 ) {
335 // get the first char of the term (UTF8)
336 // TODO: Make the RegEx configurable to make ZIP-Codes possible
337 preg_match('/^./' . $this->conf['modifier'],$termArray[$sortField],$match);
338 $newIndexChar = $match[0];
339 $indexArray[$newIndexChar] = NULL;
340 $typolinkConf['additionalParams'] .= '&' . $this->prefixId . '[index]=' . urlencode($newIndexChar);
341 $indexArray[$newIndexChar] = $this->local_cObj->typolink($newIndexChar, $typolinkConf);
342 $this->termsArray[$termKey]['indexChar'] = $newIndexChar;
343 }
344 }
345 }
346
347 // TODO Sorting of the index (UTF8)
348 ksort($indexArray,SORT_LOCALE_STRING);
349
350 return $indexArray;
351 }
352
353 protected function removeUnfilledMarker($content) {
354 return preg_replace('/###.*?###/', '', $content);
355 }
356
357 }
358
359
360 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/contagged/pi1/class.tx_contagged_pi1.php']) {
361 include_once ($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/contagged/pi1/class.tx_contagged_pi1.php']);
362 }
363 ?>