TYPO3 CMS  TYPO3_6-2
AbstractPlugin.php
Go to the documentation of this file.
1 <?php
3 
18 
28 
29  // Reserved variables:
36  public $cObj;
37 
38  // Should be same as classname of the plugin, used for CSS classes, variables
42  public $prefixId;
43 
44  // Path to the plugin class script relative to extension directory, eg. 'pi1/class.tx_newfaq_pi1.php'
49 
50  // Extension key.
54  public $extKey;
55 
56  // This is the incoming array by name $this->prefixId merged between POST and GET, POST taking precedence.
57  // Eg. if the class name is 'tx_myext'
58  // then the content of this array will be whatever comes into &tx_myext[...]=...
62  public $piVars = array(
63  'pointer' => '',
64  // Used as a pointer for lists
65  'mode' => '',
66  // List mode
67  'sword' => '',
68  // Search word
69  'sort' => ''
70  );
71 
75  public $internal = array('res_count' => 0, 'results_at_a_time' => 20, 'maxPages' => 10, 'currentRow' => array(), 'currentTable' => '');
76 
77  // Local Language content
81  public $LOCAL_LANG = array();
82 
91  protected $LOCAL_LANG_UNSET = array();
92 
93  // Local Language content charset for individual labels (overriding)
97  public $LOCAL_LANG_charset = array();
98 
99  // Flag that tells if the locallang file has been fetch (or tried to be fetched) already.
103  public $LOCAL_LANG_loaded = 0;
104 
105  // Pointer to the language to use.
109  public $LLkey = 'default';
110 
111  // Pointer to alternative fall-back language to use.
115  public $altLLkey = '';
116 
117  // You can set this during development to some value that makes it easy for you to spot all labels that ARe delivered by the getLL function.
121  public $LLtestPrefix = '';
122 
123  // Save as LLtestPrefix, but additional prefix for the alternative value in getLL() function calls
127  public $LLtestPrefixAlt = '';
128 
132  public $pi_isOnlyFields = 'mode,pointer';
133 
137  public $pi_alwaysPrev = 0;
138 
142  public $pi_lowerThan = 5;
143 
147  public $pi_moreParams = '';
148 
152  public $pi_listFields = '*';
153 
157  public $pi_autoCacheFields = array();
158 
162  public $pi_autoCacheEn = 0;
163 
164  // If set, then links are 1) not using cHash and 2) not allowing pages to be cached. (Set this for all USER_INT plugins!)
168  public $pi_USER_INT_obj = FALSE;
169 
170  // If set, then caching is disabled if piVars are incoming while no cHash was set (Set this for all USER plugins!)
174  public $pi_checkCHash = FALSE;
175 
184  public $conf = array();
185 
186  // internal, don't mess with...
191 
195  public $pi_tmpPageId = 0;
196 
197  /***************************
198  *
199  * Init functions
200  *
201  **************************/
209  public function __construct() {
210  // Setting piVars:
211  if ($this->prefixId) {
212  $this->piVars = GeneralUtility::_GPmerged($this->prefixId);
213  // cHash mode check
214  // IMPORTANT FOR CACHED PLUGINS (USER cObject): As soon as you generate cached plugin output which depends on parameters (eg. seeing the details of a news item) you MUST check if a cHash value is set.
215  // Background: The function call will check if a cHash parameter was sent with the URL because only if it was the page may be cached. If no cHash was found the function will simply disable caching to avoid unpredictable caching behaviour. In any case your plugin can generate the expected output and the only risk is that the content may not be cached. A missing cHash value is considered a mistake in the URL resulting from either URL manipulation, "realurl" "grayzones" etc. The problem is rare (more frequent with "realurl") but when it occurs it is very puzzling!
216  if ($this->pi_checkCHash && count($this->piVars)) {
217  $GLOBALS['TSFE']->reqCHash();
218  }
219  }
220  if (!empty($GLOBALS['TSFE']->config['config']['language'])) {
221  $this->LLkey = $GLOBALS['TSFE']->config['config']['language'];
222  if (empty($GLOBALS['TSFE']->config['config']['language_alt'])) {
224  $locales = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Localization\\Locales');
225  if (in_array($this->LLkey, $locales->getLocales())) {
226  $this->altLLkey = '';
227  foreach ($locales->getLocaleDependencies($this->LLkey) as $language) {
228  $this->altLLkey .= $language . ',';
229  }
230  $this->altLLkey = rtrim($this->altLLkey, ',');
231  }
232  } else {
233  $this->altLLkey = $GLOBALS['TSFE']->config['config']['language_alt'];
234  }
235  }
236  }
237 
245  protected function applyStdWrapRecursive(array $conf, $level = 0) {
246  foreach ($conf as $key => $confNextLevel) {
247  if (strpos($key, '.') !== FALSE) {
248  $key = substr($key, 0, -1);
249 
250  // descend into all non-stdWrap-subelements first
251  foreach ($confNextLevel as $subKey => $subConfNextLevel) {
252  if (is_array($subConfNextLevel) && strpos($subKey, '.') !== FALSE && $subKey !== 'stdWrap.') {
253  $subKey = substr($subKey, 0, -1);
254  $conf[$key . '.'] = $this->applyStdWrapRecursive($confNextLevel, $level + 1);
255  }
256  }
257 
258  // now for stdWrap
259  foreach ($confNextLevel as $subKey => $subConfNextLevel) {
260  if (is_array($subConfNextLevel) && $subKey === 'stdWrap.') {
261  $conf[$key] = $this->cObj->stdWrap($conf[$key], $conf[$key . '.']['stdWrap.']);
262  unset($conf[$key . '.']['stdWrap.']);
263  if (!count($conf[$key . '.'])) {
264  unset($conf[$key . '.']);
265  }
266  }
267  }
268  }
269  }
270  return $conf;
271  }
272 
278  public function pi_setPiVarDefaults() {
279  if (isset($this->conf['_DEFAULT_PI_VARS.']) && is_array($this->conf['_DEFAULT_PI_VARS.'])) {
280  $this->conf['_DEFAULT_PI_VARS.'] = $this->applyStdWrapRecursive($this->conf['_DEFAULT_PI_VARS.']);
281  $tmp = $this->conf['_DEFAULT_PI_VARS.'];
282  \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($tmp, is_array($this->piVars) ? $this->piVars : array());
283  $this->piVars = $tmp;
284  }
285  }
286 
287  /***************************
288  *
289  * Link functions
290  *
291  **************************/
307  public function pi_getPageLink($id, $target = '', $urlParameters = array()) {
308  return $this->cObj->getTypoLink_URL($id, $urlParameters, $target);
309  }
310 
324  public function pi_linkToPage($str, $id, $target = '', $urlParameters = array()) {
325  return $this->cObj->getTypoLink($str, $id, $urlParameters, $target);
326  }
327 
340  public function pi_linkTP($str, $urlParameters = array(), $cache = 0, $altPageId = 0) {
341  $conf = array();
342  $conf['useCacheHash'] = $this->pi_USER_INT_obj ? 0 : $cache;
343  $conf['no_cache'] = $this->pi_USER_INT_obj ? 0 : !$cache;
344  $conf['parameter'] = $altPageId ? $altPageId : ($this->pi_tmpPageId ? $this->pi_tmpPageId : $GLOBALS['TSFE']->id);
345  $conf['additionalParams'] = $this->conf['parent.']['addParams'] . GeneralUtility::implodeArrayForUrl('', $urlParameters, '', TRUE) . $this->pi_moreParams;
346  return $this->cObj->typoLink($str, $conf);
347  }
348 
363  public function pi_linkTP_keepPIvars($str, $overrulePIvars = array(), $cache = 0, $clearAnyway = 0, $altPageId = 0) {
364  if (is_array($this->piVars) && is_array($overrulePIvars) && !$clearAnyway) {
366  unset($piVars['DATA']);
368  $overrulePIvars = $piVars;
369  if ($this->pi_autoCacheEn) {
370  $cache = $this->pi_autoCache($overrulePIvars);
371  }
372  }
373  $res = $this->pi_linkTP($str, array($this->prefixId => $overrulePIvars), $cache, $altPageId);
374  return $res;
375  }
376 
389  public function pi_linkTP_keepPIvars_url($overrulePIvars = array(), $cache = 0, $clearAnyway = 0, $altPageId = 0) {
390  $this->pi_linkTP_keepPIvars('|', $overrulePIvars, $cache, $clearAnyway, $altPageId);
391  return $this->cObj->lastTypoLinkUrl;
392  }
393 
408  public function pi_list_linkSingle($str, $uid, $cache = FALSE, $mergeArr = array(), $urlOnly = FALSE, $altPageId = 0) {
409  if ($this->prefixId) {
410  if ($cache) {
411  $overrulePIvars = $uid ? array('showUid' => $uid) : array();
412  $overrulePIvars = array_merge($overrulePIvars, (array) $mergeArr);
413  $str = $this->pi_linkTP($str, array($this->prefixId => $overrulePIvars), $cache, $altPageId);
414  } else {
415  $overrulePIvars = array('showUid' => $uid ?: '');
416  $overrulePIvars = array_merge($overrulePIvars, (array) $mergeArr);
417  $str = $this->pi_linkTP_keepPIvars($str, $overrulePIvars, $cache, 0, $altPageId);
418  }
419  // If urlOnly flag, return only URL as it has recently be generated.
420  if ($urlOnly) {
421  $str = $this->cObj->lastTypoLinkUrl;
422  }
423  }
424  return $str;
425  }
426 
436  public function pi_openAtagHrefInJSwindow($str, $winName = '', $winParams = 'width=670,height=500,status=0,menubar=0,scrollbars=1,resizable=1') {
437  if (preg_match('/(.*)(<a[^>]*>)(.*)/i', $str, $match)) {
438  $aTagContent = GeneralUtility::get_tag_attributes($match[2]);
439  $match[2] = '<a href="#" onclick="' . htmlspecialchars(('vHWin=window.open(\'' . $GLOBALS['TSFE']->baseUrlWrap($aTagContent['href']) . '\',\'' . ($winName ? $winName : md5($aTagContent['href'])) . '\',\'' . $winParams . '\');vHWin.focus();return false;')) . '">';
440  $str = $match[1] . $match[2] . $match[3];
441  }
442  return $str;
443  }
444 
445  /***************************
446  *
447  * Functions for listing, browsing, searching etc.
448  *
449  **************************/
475  public function pi_list_browseresults($showResultCount = 1, $tableParams = '', $wrapArr = array(), $pointerName = 'pointer', $hscText = TRUE, $forceOutput = FALSE) {
476  // example $wrapArr-array how it could be traversed from an extension
477  /* $wrapArr = array(
478  'browseBoxWrap' => '<div class="browseBoxWrap">|</div>',
479  'showResultsWrap' => '<div class="showResultsWrap">|</div>',
480  'browseLinksWrap' => '<div class="browseLinksWrap">|</div>',
481  'showResultsNumbersWrap' => '<span class="showResultsNumbersWrap">|</span>',
482  'disabledLinkWrap' => '<span class="disabledLinkWrap">|</span>',
483  'inactiveLinkWrap' => '<span class="inactiveLinkWrap">|</span>',
484  'activeLinkWrap' => '<span class="activeLinkWrap">|</span>'
485  );*/
486  // Initializing variables:
487  $pointer = (int)$this->piVars[$pointerName];
488  $count = (int)$this->internal['res_count'];
489  $results_at_a_time = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->internal['results_at_a_time'], 1, 1000);
490  $totalPages = ceil($count / $results_at_a_time);
491  $maxPages = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->internal['maxPages'], 1, 100);
492  $pi_isOnlyFields = $this->pi_isOnlyFields($this->pi_isOnlyFields);
493  if (!$forceOutput && $count <= $results_at_a_time) {
494  return '';
495  }
496  // $showResultCount determines how the results of the pagerowser will be shown.
497  // If set to 0: only the result-browser will be shown
498  // 1: (default) the text "Displaying results..." and the result-browser will be shown.
499  // 2: only the text "Displaying results..." will be shown
500  $showResultCount = (int)$showResultCount;
501  // If this is set, two links named "<< First" and "LAST >>" will be shown and point to the very first or last page.
502  $showFirstLast = $this->internal['showFirstLast'];
503  // If this has a value the "previous" button is always visible (will be forced if "showFirstLast" is set)
504  $alwaysPrev = $showFirstLast ? 1 : $this->pi_alwaysPrev;
505  if (isset($this->internal['pagefloat'])) {
506  if (strtoupper($this->internal['pagefloat']) == 'CENTER') {
507  $pagefloat = ceil(($maxPages - 1) / 2);
508  } else {
509  // pagefloat set as integer. 0 = left, value >= $this->internal['maxPages'] = right
510  $pagefloat = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->internal['pagefloat'], -1, $maxPages - 1);
511  }
512  } else {
513  // pagefloat disabled
514  $pagefloat = -1;
515  }
516  // Default values for "traditional" wrapping with a table. Can be overwritten by vars from $wrapArr
517  $wrapper['disabledLinkWrap'] = '<td nowrap="nowrap"><p>|</p></td>';
518  $wrapper['inactiveLinkWrap'] = '<td nowrap="nowrap"><p>|</p></td>';
519  $wrapper['activeLinkWrap'] = '<td' . $this->pi_classParam('browsebox-SCell') . ' nowrap="nowrap"><p>|</p></td>';
520  $wrapper['browseLinksWrap'] = trim(('<table ' . $tableParams)) . '><tr>|</tr></table>';
521  $wrapper['showResultsWrap'] = '<p>|</p>';
522  $wrapper['browseBoxWrap'] = '
523  <!--
524  List browsing box:
525  -->
526  <div ' . $this->pi_classParam('browsebox') . '>
527  |
528  </div>';
529  // Now overwrite all entries in $wrapper which are also in $wrapArr
530  $wrapper = array_merge($wrapper, $wrapArr);
531  // Show pagebrowser
532  if ($showResultCount != 2) {
533  if ($pagefloat > -1) {
534  $lastPage = min($totalPages, max($pointer + 1 + $pagefloat, $maxPages));
535  $firstPage = max(0, $lastPage - $maxPages);
536  } else {
537  $firstPage = 0;
538  $lastPage = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($totalPages, 1, $maxPages);
539  }
540  $links = array();
541  // Make browse-table/links:
542  // Link to first page
543  if ($showFirstLast) {
544  if ($pointer > 0) {
545  $links[] = $this->cObj->wrap($this->pi_linkTP_keepPIvars($this->pi_getLL('pi_list_browseresults_first', '<< First', $hscText), array($pointerName => NULL), $pi_isOnlyFields), $wrapper['inactiveLinkWrap']);
546  } else {
547  $links[] = $this->cObj->wrap($this->pi_getLL('pi_list_browseresults_first', '<< First', $hscText), $wrapper['disabledLinkWrap']);
548  }
549  }
550  // Link to previous page
551  if ($alwaysPrev >= 0) {
552  if ($pointer > 0) {
553  $links[] = $this->cObj->wrap($this->pi_linkTP_keepPIvars($this->pi_getLL('pi_list_browseresults_prev', '< Previous', $hscText), array($pointerName => ($pointer - 1) ?: ''), $pi_isOnlyFields), $wrapper['inactiveLinkWrap']);
554  } elseif ($alwaysPrev) {
555  $links[] = $this->cObj->wrap($this->pi_getLL('pi_list_browseresults_prev', '< Previous', $hscText), $wrapper['disabledLinkWrap']);
556  }
557  }
558  // Links to pages
559  for ($a = $firstPage; $a < $lastPage; $a++) {
560  if ($this->internal['showRange']) {
561  $pageText = ($a * $results_at_a_time + 1) . '-' . min($count, ($a + 1) * $results_at_a_time);
562  } else {
563  $pageText = trim($this->pi_getLL('pi_list_browseresults_page', 'Page', $hscText) . ' ' . ($a + 1));
564  }
565  // Current page
566  if ($pointer == $a) {
567  if ($this->internal['dontLinkActivePage']) {
568  $links[] = $this->cObj->wrap($pageText, $wrapper['activeLinkWrap']);
569  } else {
570  $links[] = $this->cObj->wrap($this->pi_linkTP_keepPIvars($pageText, array($pointerName => $a ?: ''), $pi_isOnlyFields), $wrapper['activeLinkWrap']);
571  }
572  } else {
573  $links[] = $this->cObj->wrap($this->pi_linkTP_keepPIvars($pageText, array($pointerName => $a ?: ''), $pi_isOnlyFields), $wrapper['inactiveLinkWrap']);
574  }
575  }
576  if ($pointer < $totalPages - 1 || $showFirstLast) {
577  // Link to next page
578  if ($pointer >= $totalPages - 1) {
579  $links[] = $this->cObj->wrap($this->pi_getLL('pi_list_browseresults_next', 'Next >', $hscText), $wrapper['disabledLinkWrap']);
580  } else {
581  $links[] = $this->cObj->wrap($this->pi_linkTP_keepPIvars($this->pi_getLL('pi_list_browseresults_next', 'Next >', $hscText), array($pointerName => $pointer + 1), $pi_isOnlyFields), $wrapper['inactiveLinkWrap']);
582  }
583  }
584  // Link to last page
585  if ($showFirstLast) {
586  if ($pointer < $totalPages - 1) {
587  $links[] = $this->cObj->wrap($this->pi_linkTP_keepPIvars($this->pi_getLL('pi_list_browseresults_last', 'Last >>', $hscText), array($pointerName => $totalPages - 1), $pi_isOnlyFields), $wrapper['inactiveLinkWrap']);
588  } else {
589  $links[] = $this->cObj->wrap($this->pi_getLL('pi_list_browseresults_last', 'Last >>', $hscText), $wrapper['disabledLinkWrap']);
590  }
591  }
592  $theLinks = $this->cObj->wrap(implode(LF, $links), $wrapper['browseLinksWrap']);
593  } else {
594  $theLinks = '';
595  }
596  $pR1 = $pointer * $results_at_a_time + 1;
597  $pR2 = $pointer * $results_at_a_time + $results_at_a_time;
598  if ($showResultCount) {
599  if ($wrapper['showResultsNumbersWrap']) {
600  // This will render the resultcount in a more flexible way using markers (new in TYPO3 3.8.0).
601  // The formatting string is expected to hold template markers (see function header). Example: 'Displaying results ###FROM### to ###TO### out of ###OUT_OF###'
602  $markerArray['###FROM###'] = $this->cObj->wrap($this->internal['res_count'] > 0 ? $pR1 : 0, $wrapper['showResultsNumbersWrap']);
603  $markerArray['###TO###'] = $this->cObj->wrap(min($this->internal['res_count'], $pR2), $wrapper['showResultsNumbersWrap']);
604  $markerArray['###OUT_OF###'] = $this->cObj->wrap($this->internal['res_count'], $wrapper['showResultsNumbersWrap']);
605  $markerArray['###FROM_TO###'] = $this->cObj->wrap(($this->internal['res_count'] > 0 ? $pR1 : 0) . ' ' . $this->pi_getLL('pi_list_browseresults_to', 'to') . ' ' . min($this->internal['res_count'], $pR2), $wrapper['showResultsNumbersWrap']);
606  $markerArray['###CURRENT_PAGE###'] = $this->cObj->wrap($pointer + 1, $wrapper['showResultsNumbersWrap']);
607  $markerArray['###TOTAL_PAGES###'] = $this->cObj->wrap($totalPages, $wrapper['showResultsNumbersWrap']);
608  // Substitute markers
609  $resultCountMsg = $this->cObj->substituteMarkerArray($this->pi_getLL('pi_list_browseresults_displays', 'Displaying results ###FROM### to ###TO### out of ###OUT_OF###'), $markerArray);
610  } else {
611  // Render the resultcount in the "traditional" way using sprintf
612  $resultCountMsg = sprintf(str_replace('###SPAN_BEGIN###', '<span' . $this->pi_classParam('browsebox-strong') . '>', $this->pi_getLL('pi_list_browseresults_displays', 'Displaying results ###SPAN_BEGIN###%s to %s</span> out of ###SPAN_BEGIN###%s</span>')), $count > 0 ? $pR1 : 0, min($count, $pR2), $count);
613  }
614  $resultCountMsg = $this->cObj->wrap($resultCountMsg, $wrapper['showResultsWrap']);
615  } else {
616  $resultCountMsg = '';
617  }
618  $sTables = $this->cObj->wrap($resultCountMsg . $theLinks, $wrapper['browseBoxWrap']);
619  return $sTables;
620  }
621 
630  public function pi_list_searchBox($tableParams = '') {
631  // Search box design:
632  $sTables = '
633 
634  <!--
635  List search box:
636  -->
637  <div' . $this->pi_classParam('searchbox') . '>
638  <form action="' . htmlspecialchars(GeneralUtility::getIndpEnv('REQUEST_URI')) . '" method="post" style="margin: 0 0 0 0;">
639  <' . trim(('table ' . $tableParams)) . '>
640  <tr>
641  <td><input type="text" name="' . $this->prefixId . '[sword]" value="' . htmlspecialchars($this->piVars['sword']) . '"' . $this->pi_classParam('searchbox-sword') . ' /></td>
642  <td><input type="submit" value="' . $this->pi_getLL('pi_list_searchBox_search', 'Search', TRUE) . '"' . $this->pi_classParam('searchbox-button') . ' />' . '<input type="hidden" name="no_cache" value="1" />' . '<input type="hidden" name="' . $this->prefixId . '[pointer]" value="" />' . '</td>
643  </tr>
644  </table>
645  </form>
646  </div>';
647  return $sTables;
648  }
649 
658  public function pi_list_modeSelector($items = array(), $tableParams = '') {
659  $cells = array();
660  foreach ($items as $k => $v) {
661  $cells[] = '
662  <td' . ($this->piVars['mode'] == $k ? $this->pi_classParam('modeSelector-SCell') : '') . '><p>' . $this->pi_linkTP_keepPIvars(htmlspecialchars($v), array('mode' => $k), $this->pi_isOnlyFields($this->pi_isOnlyFields)) . '</p></td>';
663  }
664  $sTables = '
665 
666  <!--
667  Mode selector (menu for list):
668  -->
669  <div' . $this->pi_classParam('modeSelector') . '>
670  <' . trim(('table ' . $tableParams)) . '>
671  <tr>
672  ' . implode('', $cells) . '
673  </tr>
674  </table>
675  </div>';
676  return $sTables;
677  }
678 
692  public function pi_list_makelist($res, $tableParams = '') {
693  // Make list table header:
694  $tRows = array();
695  $this->internal['currentRow'] = '';
696  $tRows[] = $this->pi_list_header();
697  // Make list table rows
698  $c = 0;
699  while ($this->internal['currentRow'] = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
700  $tRows[] = $this->pi_list_row($c);
701  $c++;
702  }
703  $out = '
704 
705  <!--
706  Record list:
707  -->
708  <div' . $this->pi_classParam('listrow') . '>
709  <' . trim(('table ' . $tableParams)) . '>
710  ' . implode('', $tRows) . '
711  </table>
712  </div>';
713  return $out;
714  }
715 
725  public function pi_list_row($c) {
726  // Dummy
727  return '<tr' . ($c % 2 ? $this->pi_classParam('listrow-odd') : '') . '><td><p>[dummy row]</p></td></tr>';
728  }
729 
738  public function pi_list_header() {
739  return '<tr' . $this->pi_classParam('listrow-header') . '><td><p>[dummy header row]</p></td></tr>';
740  }
741 
742  /***************************
743  *
744  * Stylesheet, CSS
745  *
746  **************************/
754  public function pi_getClassName($class) {
755  return str_replace('_', '-', $this->prefixId) . ($this->prefixId ? '-' : '') . $class;
756  }
757 
768  public function pi_classParam($class, $addClasses = '') {
769  $output = '';
770  foreach (GeneralUtility::trimExplode(',', $class) as $v) {
771  $output .= ' ' . $this->pi_getClassName($v);
772  }
773  foreach (GeneralUtility::trimExplode(',', $addClasses) as $v) {
774  $output .= ' ' . $v;
775  }
776  return ' class="' . trim($output) . '"';
777  }
778 
787  public function pi_wrapInBaseClass($str) {
788  $content = '<div class="' . str_replace('_', '-', $this->prefixId) . '">
789  ' . $str . '
790  </div>
791  ';
792  if (!$GLOBALS['TSFE']->config['config']['disablePrefixComment']) {
793  $content = '
794 
795 
796  <!--
797 
798  BEGIN: Content of extension "' . $this->extKey . '", plugin "' . $this->prefixId . '"
799 
800  -->
801  ' . $content . '
802  <!-- END: Content of extension "' . $this->extKey . '", plugin "' . $this->prefixId . '" -->
803 
804  ';
805  }
806  return $content;
807  }
808 
809  /***************************
810  *
811  * Frontend editing: Edit panel, edit icons
812  *
813  **************************/
825  public function pi_getEditPanel($row = '', $tablename = '', $label = '', $conf = array()) {
826  $panel = '';
827  if (!$row || !$tablename) {
828  $row = $this->internal['currentRow'];
829  $tablename = $this->internal['currentTable'];
830  }
831  if ($GLOBALS['TSFE']->beUserLogin) {
832  // Create local cObj if not set:
833  if (!is_object($this->pi_EPtemp_cObj)) {
834  $this->pi_EPtemp_cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
835  $this->pi_EPtemp_cObj->setParent($this->cObj->data, $this->cObj->currentRecord);
836  }
837  // Initialize the cObj object with current row
838  $this->pi_EPtemp_cObj->start($row, $tablename);
839  // Setting TypoScript values in the $conf array. See documentation in TSref for the EDITPANEL cObject.
840  $conf['allow'] = 'edit,new,delete,move,hide';
841  $panel = $this->pi_EPtemp_cObj->cObjGetSingle('EDITPANEL', $conf, 'editpanel');
842  }
843  if ($panel) {
844  if ($label) {
845  return '<!-- BEGIN: EDIT PANEL --><table border="0" cellpadding="0" cellspacing="0" width="100%"><tr><td valign="top">' . $label . '</td><td valign="top" align="right">' . $panel . '</td></tr></table><!-- END: EDIT PANEL -->';
846  } else {
847  return '<!-- BEGIN: EDIT PANEL -->' . $panel . '<!-- END: EDIT PANEL -->';
848  }
849  } else {
850  return $label;
851  }
852  }
853 
868  public function pi_getEditIcon($content, $fields, $title = '', $row = '', $tablename = '', $oConf = array()) {
869  if ($GLOBALS['TSFE']->beUserLogin) {
870  if (!$row || !$tablename) {
871  $row = $this->internal['currentRow'];
872  $tablename = $this->internal['currentTable'];
873  }
874  $conf = array_merge(array(
875  'beforeLastTag' => 1,
876  'iconTitle' => $title
877  ), $oConf);
878  $content = $this->cObj->editIcons($content, $tablename . ':' . $fields, $conf, $tablename . ':' . $row['uid'], $row, '&viewUrl=' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI')));
879  }
880  return $content;
881  }
882 
883  /***************************
884  *
885  * Localization, locallang functions
886  *
887  **************************/
897  public function pi_getLL($key, $alternativeLabel = '', $hsc = FALSE) {
898  $word = NULL;
899  if (!empty($this->LOCAL_LANG[$this->LLkey][$key][0]['target'])
900  || isset($this->LOCAL_LANG_UNSET[$this->LLkey][$key])
901  ) {
902  // The "from" charset of csConv() is only set for strings from TypoScript via _LOCAL_LANG
903  if (isset($this->LOCAL_LANG_charset[$this->LLkey][$key])) {
904  $word = $GLOBALS['TSFE']->csConv($this->LOCAL_LANG[$this->LLkey][$key][0]['target'], $this->LOCAL_LANG_charset[$this->LLkey][$key]);
905  } else {
906  $word = $this->LOCAL_LANG[$this->LLkey][$key][0]['target'];
907  }
908  } elseif ($this->altLLkey) {
909  $alternativeLanguageKeys = GeneralUtility::trimExplode(',', $this->altLLkey, TRUE);
910  $alternativeLanguageKeys = array_reverse($alternativeLanguageKeys);
911  foreach ($alternativeLanguageKeys as $languageKey) {
912  if (!empty($this->LOCAL_LANG[$languageKey][$key][0]['target'])
913  || isset($this->LOCAL_LANG_UNSET[$languageKey][$key])
914  ) {
915  // Alternative language translation for key exists
916  $word = $this->LOCAL_LANG[$languageKey][$key][0]['target'];
917  // The "from" charset of csConv() is only set for strings from TypoScript via _LOCAL_LANG
918  if (isset($this->LOCAL_LANG_charset[$languageKey][$key])) {
919  $word = $GLOBALS['TSFE']->csConv(
920  $word,
921  $this->LOCAL_LANG_charset[$this->altLLkey][$key]
922  );
923  }
924  break;
925  }
926  }
927  }
928  if ($word === NULL) {
929  if (!empty($this->LOCAL_LANG['default'][$key][0]['target'])
930  || isset($this->LOCAL_LANG_UNSET['default'][$key])
931  ) {
932  // Get default translation (without charset conversion, english)
933  $word = $this->LOCAL_LANG['default'][$key][0]['target'];
934  } else {
935  // Return alternative string or empty
936  $word = isset($this->LLtestPrefixAlt) ? $this->LLtestPrefixAlt . $alternativeLabel : $alternativeLabel;
937  }
938  }
939  $output = isset($this->LLtestPrefix) ? $this->LLtestPrefix . $word : $word;
940  if ($hsc) {
941  $output = htmlspecialchars($output);
942  }
943  return $output;
944  }
945 
955  public function pi_loadLL() {
956  if (!$this->LOCAL_LANG_loaded && $this->scriptRelPath) {
957  $basePath = 'EXT:' . $this->extKey . '/' . dirname($this->scriptRelPath) . '/locallang.xml';
958  // Read the strings in the required charset (since TYPO3 4.2)
959  $this->LOCAL_LANG = GeneralUtility::readLLfile($basePath, $this->LLkey, $GLOBALS['TSFE']->renderCharset);
960  $alternativeLanguageKeys = GeneralUtility::trimExplode(',', $this->altLLkey, TRUE);
961  foreach ($alternativeLanguageKeys as $languageKey) {
962  $tempLL = GeneralUtility::readLLfile($basePath, $languageKey);
963  if ($this->LLkey !== 'default' && isset($tempLL[$languageKey])) {
964  $this->LOCAL_LANG[$languageKey] = $tempLL[$languageKey];
965  }
966  }
967  // Overlaying labels from TypoScript (including fictitious language keys for non-system languages!):
968  if (isset($this->conf['_LOCAL_LANG.'])) {
969  // Clear the "unset memory"
970  $this->LOCAL_LANG_UNSET = array();
971  foreach ($this->conf['_LOCAL_LANG.'] as $languageKey => $languageArray) {
972  // Remove the dot after the language key
973  $languageKey = substr($languageKey, 0, -1);
974  // Don't process label if the language is not loaded
975  if (is_array($languageArray) && isset($this->LOCAL_LANG[$languageKey])) {
976  foreach ($languageArray as $labelKey => $labelValue) {
977  if (!is_array($labelValue)) {
978  $this->LOCAL_LANG[$languageKey][$labelKey][0]['target'] = $labelValue;
979  if ($labelValue === '') {
980  $this->LOCAL_LANG_UNSET[$languageKey][$labelKey] = '';
981  }
982  $this->LOCAL_LANG_charset[$languageKey][$labelKey] = 'utf-8';
983  }
984  }
985  }
986  }
987  }
988  }
989  $this->LOCAL_LANG_loaded = 1;
990  }
991 
992  /***************************
993  *
994  * Database, queries
995  *
996  **************************/
1012  public function pi_exec_query($table, $count = 0, $addWhere = '', $mm_cat = '', $groupBy = '', $orderBy = '', $query = '') {
1013  // Begin Query:
1014  if (!$query) {
1015  // Fetches the list of PIDs to select from.
1016  // TypoScript property .pidList is a comma list of pids. If blank, current page id is used.
1017  // TypoScript property .recursive is a int+ which determines how many levels down from the pids in the pid-list subpages should be included in the select.
1018  $pidList = $this->pi_getPidList($this->conf['pidList'], $this->conf['recursive']);
1019  if (is_array($mm_cat)) {
1020  // This adds WHERE-clauses that ensures deleted, hidden, starttime/endtime/access records are NOT
1021  // selected, if they should not! Almost ALWAYS add this to your queries!
1022  $query = 'FROM ' . $table . ',' . $mm_cat['table'] . ',' . $mm_cat['mmtable'] . LF . ' WHERE ' . $table . '.uid=' . $mm_cat['mmtable'] . '.uid_local AND ' . $mm_cat['table'] . '.uid=' . $mm_cat['mmtable'] . '.uid_foreign ' . LF . (strcmp($mm_cat['catUidList'], '') ? ' AND ' . $mm_cat['table'] . '.uid IN (' . $mm_cat['catUidList'] . ')' : '') . LF . ' AND ' . $table . '.pid IN (' . $pidList . ')' . LF . $this->cObj->enableFields($table) . LF;
1023  } else {
1024  // This adds WHERE-clauses that ensures deleted, hidden, starttime/endtime/access records are NOT
1025  // selected, if they should not! Almost ALWAYS add this to your queries!
1026  $query = 'FROM ' . $table . ' WHERE pid IN (' . $pidList . ')' . LF . $this->cObj->enableFields($table) . LF;
1027  }
1028  }
1029  // Split the "FROM ... WHERE" string so we get the WHERE part and TABLE names separated...:
1030  list($TABLENAMES, $WHERE) = preg_split('/WHERE/i', trim($query), 2);
1031  $TABLENAMES = trim(substr(trim($TABLENAMES), 5));
1032  $WHERE = trim($WHERE);
1033  // Add '$addWhere'
1034  if ($addWhere) {
1035  $WHERE .= ' ' . $addWhere . LF;
1036  }
1037  // Search word:
1038  if ($this->piVars['sword'] && $this->internal['searchFieldList']) {
1039  $WHERE .= $this->cObj->searchWhere($this->piVars['sword'], $this->internal['searchFieldList'], $table) . LF;
1040  }
1041  if ($count) {
1042  $queryParts = array(
1043  'SELECT' => 'count(*)',
1044  'FROM' => $TABLENAMES,
1045  'WHERE' => $WHERE,
1046  'GROUPBY' => '',
1047  'ORDERBY' => '',
1048  'LIMIT' => ''
1049  );
1050  } else {
1051  // Order by data:
1052  if (!$orderBy && $this->internal['orderBy']) {
1053  if (GeneralUtility::inList($this->internal['orderByList'], $this->internal['orderBy'])) {
1054  $orderBy = 'ORDER BY ' . $table . '.' . $this->internal['orderBy'] . ($this->internal['descFlag'] ? ' DESC' : '');
1055  }
1056  }
1057  // Limit data:
1058  $pointer = (int)$this->piVars['pointer'];
1059  $results_at_a_time = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->internal['results_at_a_time'], 1, 1000);
1060  $LIMIT = $pointer * $results_at_a_time . ',' . $results_at_a_time;
1061  // Add 'SELECT'
1062  $queryParts = array(
1063  'SELECT' => $this->pi_prependFieldsWithTable($table, $this->pi_listFields),
1064  'FROM' => $TABLENAMES,
1065  'WHERE' => $WHERE,
1066  'GROUPBY' => $GLOBALS['TYPO3_DB']->stripGroupBy($groupBy),
1067  'ORDERBY' => $GLOBALS['TYPO3_DB']->stripOrderBy($orderBy),
1068  'LIMIT' => $LIMIT
1069  );
1070  }
1071  return $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
1072  }
1073 
1084  public function pi_getRecord($table, $uid, $checkPage = 0) {
1085  return $GLOBALS['TSFE']->sys_page->checkRecord($table, $uid, $checkPage);
1086  }
1087 
1096  public function pi_getPidList($pid_list, $recursive = 0) {
1097  if (!strcmp($pid_list, '')) {
1098  $pid_list = $GLOBALS['TSFE']->id;
1099  }
1100  $recursive = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($recursive, 0);
1101  $pid_list_arr = array_unique(GeneralUtility::trimExplode(',', $pid_list, TRUE));
1102  $pid_list = array();
1103  foreach ($pid_list_arr as $val) {
1104  $val = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($val, 0);
1105  if ($val) {
1106  $_list = $this->cObj->getTreeList(-1 * $val, $recursive);
1107  if ($_list) {
1108  $pid_list[] = $_list;
1109  }
1110  }
1111  }
1112  return implode(',', $pid_list);
1113  }
1114 
1123  public function pi_prependFieldsWithTable($table, $fieldList) {
1124  $list = GeneralUtility::trimExplode(',', $fieldList, TRUE);
1125  $return = array();
1126  foreach ($list as $listItem) {
1127  $return[] = $table . '.' . $listItem;
1128  }
1129  return implode(',', $return);
1130  }
1131 
1144  public function pi_getCategoryTableContents($table, $pid, $whereClause = '', $groupBy = '', $orderBy = '', $limit = '') {
1145  $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $table, 'pid=' . (int)$pid . $this->cObj->enableFields($table) . ' ' . $whereClause, $groupBy, $orderBy, $limit);
1146  $outArr = array();
1147  while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
1148  $outArr[$row['uid']] = $row;
1149  }
1150  $GLOBALS['TYPO3_DB']->sql_free_result($res);
1151  return $outArr;
1152  }
1153 
1154  /***************************
1155  *
1156  * Various
1157  *
1158  **************************/
1168  public function pi_isOnlyFields($fList, $lowerThan = -1) {
1169  $lowerThan = $lowerThan == -1 ? $this->pi_lowerThan : $lowerThan;
1170  $fList = GeneralUtility::trimExplode(',', $fList, TRUE);
1171  $tempPiVars = $this->piVars;
1172  foreach ($fList as $k) {
1173  if (!\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($tempPiVars[$k]) || $tempPiVars[$k] < $lowerThan) {
1174  unset($tempPiVars[$k]);
1175  }
1176  }
1177  if (!count($tempPiVars)) {
1178  return 1;
1179  }
1180  }
1181 
1192  public function pi_autoCache($inArray) {
1193  if (is_array($inArray)) {
1194  foreach ($inArray as $fN => $fV) {
1195  if (!strcmp($inArray[$fN], '')) {
1196  unset($inArray[$fN]);
1197  } elseif (is_array($this->pi_autoCacheFields[$fN])) {
1198  if (is_array($this->pi_autoCacheFields[$fN]['range']) && (int)$inArray[$fN] >= (int)$this->pi_autoCacheFields[$fN]['range'][0] && (int)$inArray[$fN] <= (int)$this->pi_autoCacheFields[$fN]['range'][1]) {
1199  unset($inArray[$fN]);
1200  }
1201  if (is_array($this->pi_autoCacheFields[$fN]['list']) && in_array($inArray[$fN], $this->pi_autoCacheFields[$fN]['list'])) {
1202  unset($inArray[$fN]);
1203  }
1204  }
1205  }
1206  }
1207  if (!count($inArray)) {
1208  return 1;
1209  }
1210  }
1211 
1222  public function pi_RTEcssText($str) {
1223  $parseFunc = $GLOBALS['TSFE']->tmpl->setup['lib.']['parseFunc_RTE.'];
1224  if (is_array($parseFunc)) {
1225  $str = $this->cObj->parseFunc($str, $parseFunc);
1226  }
1227  return $str;
1228  }
1229 
1230  /*******************************
1231  *
1232  * FlexForms related functions
1233  *
1234  *******************************/
1242  public function pi_initPIflexForm($field = 'pi_flexform') {
1243  // Converting flexform data into array:
1244  if (!is_array($this->cObj->data[$field]) && $this->cObj->data[$field]) {
1245  $this->cObj->data[$field] = GeneralUtility::xml2array($this->cObj->data[$field]);
1246  if (!is_array($this->cObj->data[$field])) {
1247  $this->cObj->data[$field] = array();
1248  }
1249  }
1250  }
1251 
1263  public function pi_getFFvalue($T3FlexForm_array, $fieldName, $sheet = 'sDEF', $lang = 'lDEF', $value = 'vDEF') {
1264  $sheetArray = is_array($T3FlexForm_array) ? $T3FlexForm_array['data'][$sheet][$lang] : '';
1265  if (is_array($sheetArray)) {
1266  return $this->pi_getFFvalueFromSheetArray($sheetArray, explode('/', $fieldName), $value);
1267  }
1268  }
1269 
1281  public function pi_getFFvalueFromSheetArray($sheetArray, $fieldNameArr, $value) {
1282  $tempArr = $sheetArray;
1283  foreach ($fieldNameArr as $k => $v) {
1284  if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($v)) {
1285  if (is_array($tempArr)) {
1286  $c = 0;
1287  foreach ($tempArr as $values) {
1288  if ($c == $v) {
1289  $tempArr = $values;
1290  break;
1291  }
1292  $c++;
1293  }
1294  }
1295  } else {
1296  $tempArr = $tempArr[$v];
1297  }
1298  }
1299  return $tempArr[$value];
1300  }
1301 
1302 }
pi_linkTP_keepPIvars_url($overrulePIvars=array(), $cache=0, $clearAnyway=0, $altPageId=0)
static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=TRUE, $includeEmptyValues=TRUE, $enableUnsetFeature=TRUE)
pi_list_linkSingle($str, $uid, $cache=FALSE, $mergeArr=array(), $urlOnly=FALSE, $altPageId=0)
$uid
Definition: server.php:36
applyStdWrapRecursive(array $conf, $level=0)
pi_getPageLink($id, $target='', $urlParameters=array())
static implodeArrayForUrl($name, array $theArray, $str='', $skipBlank=FALSE, $rawurlencodeParamName=FALSE)
pi_linkToPage($str, $id, $target='', $urlParameters=array())
pi_linkTP($str, $urlParameters=array(), $cache=0, $altPageId=0)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
pi_linkTP_keepPIvars($str, $overrulePIvars=array(), $cache=0, $clearAnyway=0, $altPageId=0)
$locales
Definition: be_users.php:6
pi_openAtagHrefInJSwindow($str, $winName='', $winParams='width=670, height=500, status=0, menubar=0, scrollbars=1, resizable=1')