TYPO3 CMS  TYPO3_7-6
PageTreeView.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Backend\View;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
22 
27 {
31  public $ext_showPageId = false;
32 
37 
42 
48  public $ajaxStatus = false;
49 
53  public function __construct()
54  {
55  parent::__construct();
56  $this->init();
57  }
58 
66  public function wrapIcon($thePageIcon, $row)
67  {
69  $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
70  // If the record is locked, present a warning sign.
71  if ($lockInfo = BackendUtility::isRecordLocked('pages', $row['uid'])) {
72  $aOnClick = 'alert(' . GeneralUtility::quoteJSvalue($lockInfo['msg']) . ');return false;';
73  $lockIcon = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">'
74  . '<span title="' . htmlspecialchars($lockInfo['msg']) . '">' . $iconFactory->getIcon('status-warning-in-use', Icon::SIZE_SMALL)->render() . '</span></a>';
75  } else {
76  $lockIcon = '';
77  }
78  // Wrap icon in click-menu link.
79  if (!$this->ext_IconMode) {
80  $thePageIcon = BackendUtility::wrapClickMenuOnIcon($thePageIcon, 'pages', $row['uid'], 0, '&bank=' . $this->bank);
81  } elseif ($this->ext_IconMode === 'titlelink') {
82  $aOnClick = 'return jumpTo(' . GeneralUtility::quoteJSvalue($this->getJumpToParam($row)) . ',this,' . GeneralUtility::quoteJSvalue($this->treeName) . ');';
83  $thePageIcon = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . $thePageIcon . '</a>';
84  }
85  // Wrap icon in a drag/drop span.
86  $dragDropIcon = '<span class="list-tree-icon dragIcon" id="dragIconID_' . $row['uid'] . '">' . $thePageIcon . '</span> ';
87  // Add Page ID:
88  $pageIdStr = '';
89  if ($this->ext_showPageId) {
90  $pageIdStr = '<span class="dragId">[' . $row['uid'] . ']</span> ';
91  }
92  // Call stats information hook
93  $stat = '';
94  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'])) {
95  $_params = ['pages', $row['uid']];
96  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef) {
97  $stat .= GeneralUtility::callUserFunction($_funcRef, $_params, $this);
98  }
99  }
100  return $dragDropIcon . $lockIcon . $pageIdStr . $stat;
101  }
102 
112  public function wrapTitle($title, $row, $bank = 0)
113  {
114  // Hook for overriding the page title
115  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.webpagetree.php']['pageTitleOverlay'])) {
116  $_params = ['title' => &$title, 'row' => &$row];
117  foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.webpagetree.php']['pageTitleOverlay'] as $_funcRef) {
118  GeneralUtility::callUserFunction($_funcRef, $_params, $this);
119  }
120  unset($_params);
121  }
122  $aOnClick = 'return jumpTo(' . GeneralUtility::quoteJSvalue($this->getJumpToParam($row)) . ',this,' . GeneralUtility::quoteJSvalue($this->domIdPrefix . $this->getId($row)) . ',' . $bank . ');';
123  $clickMenuParts = BackendUtility::wrapClickMenuOnIcon('', 'pages', $row['uid'], 0, ('&bank=' . $this->bank), '', true);
124 
125  $thePageTitle = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '"' . GeneralUtility::implodeAttributes($clickMenuParts) . '>' . $title . '</a>';
126  // Wrap title in a drag/drop span.
127  return '<span class="list-tree-title dragTitle" id="dragTitleID_' . $row['uid'] . '">' . $thePageTitle . '</span>';
128  }
129 
136  public function printTree($treeArr = '')
137  {
138  $titleLen = (int)$this->BE_USER->uc['titleLen'];
139  if (!is_array($treeArr)) {
140  $treeArr = $this->tree;
141  }
142  $out = '<ul class="list-tree list-tree-root">';
143  // -- evaluate AJAX request
144  // IE takes anchor as parameter
145  $PM = GeneralUtility::_GP('PM');
146  if (($PMpos = strpos($PM, '#')) !== false) {
147  $PM = substr($PM, 0, $PMpos);
148  }
149  $PM = explode('_', $PM);
150 
151  $doCollapse = false;
152  $doExpand = false;
153  $expandedPageUid = null;
154  $collapsedPageUid = null;
155  if (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_AJAX && is_array($PM) && count($PM) === 4 && $PM[2] != 0) {
156  if ($PM[1]) {
157  $expandedPageUid = $PM[2];
158  $doExpand = true;
159  } else {
160  $collapsedPageUid = $PM[2];
161  $doCollapse = true;
162  }
163  }
164  // We need to count the opened <ul>'s every time we dig into another level,
165  // so we know how many we have to close when all children are done rendering
166  $closeDepth = [];
167  $ajaxOutput = '';
168  $invertedDepthOfAjaxRequestedItem = 0;
169  foreach ($treeArr as $k => $treeItem) {
170  $classAttr = $treeItem['row']['_CSSCLASS'];
171  $uid = $treeItem['row']['uid'];
172  $idAttr = htmlspecialchars($this->domIdPrefix . $this->getId($treeItem['row']) . '_' . $treeItem['bank']);
173  $itemHTML = '';
174  // If this item is the start of a new level,
175  // then a new level <ul> is needed, but not in ajax mode
176  if ($treeItem['isFirst'] && !$doCollapse && (!$doExpand || (int)$expandedPageUid !== (int)$uid)) {
177  $itemHTML = '<ul class="list-tree">';
178  }
179 
180  // Add CSS classes to the list item
181  if ($treeItem['hasSub']) {
182  $classAttr .= ' list-tree-control-open';
183  }
184  $itemHTML .= '<li id="' . $idAttr . '" ' . ($classAttr ? ' class="' . trim($classAttr) . '"' : '')
185  . '><span class="list-tree-group">' . $treeItem['HTML']
186  . $this->wrapTitle($this->getTitleStr($treeItem['row'], $titleLen), $treeItem['row'], $treeItem['bank']) . '</span>';
187  if (!$treeItem['hasSub']) {
188  $itemHTML .= '</li>';
189  }
190 
191  // We have to remember if this is the last one
192  // on level X so the last child on level X+1 closes the <ul>-tag
193  if ($treeItem['isLast'] && !($doExpand && $expandedPageUid == $uid)) {
194  $closeDepth[$treeItem['invertedDepth']] = 1;
195  }
196  // If this is the last one and does not have subitems, we need to close
197  // the tree as long as the upper levels have last items too
198  if ($treeItem['isLast'] && !$treeItem['hasSub'] && !$doCollapse && !($doExpand && $expandedPageUid == $uid)) {
199  for ($i = $treeItem['invertedDepth']; $closeDepth[$i] == 1; $i++) {
200  $closeDepth[$i] = 0;
201  $itemHTML .= '</ul></li>';
202  }
203  }
204  // Ajax request: collapse
205  if ($doCollapse && (int)$collapsedPageUid === (int)$uid) {
206  $this->ajaxStatus = true;
207  return $itemHTML;
208  }
209  // ajax request: expand
210  if ($doExpand && (int)$expandedPageUid === (int)$uid) {
211  $ajaxOutput .= $itemHTML;
212  $invertedDepthOfAjaxRequestedItem = $treeItem['invertedDepth'];
213  } elseif ($invertedDepthOfAjaxRequestedItem) {
214  if ($treeItem['invertedDepth'] < $invertedDepthOfAjaxRequestedItem) {
215  $ajaxOutput .= $itemHTML;
216  } else {
217  $this->ajaxStatus = true;
218  return $ajaxOutput;
219  }
220  }
221  $out .= $itemHTML;
222  }
223  if ($ajaxOutput) {
224  $this->ajaxStatus = true;
225  return $ajaxOutput;
226  }
227  // Finally close the first ul
228  $out .= '</ul>';
229  return $out;
230  }
231 
244  public function PMicon($row, $a, $c, $nextCount, $exp)
245  {
246  $icon = '';
247  if ($nextCount) {
248  $cmd = $this->bank . '_' . ($exp ? '0_' : '1_') . $row['uid'] . '_' . $this->treeName;
249  $icon = $this->PMiconATagWrap($icon, $cmd, !$exp);
250  }
251  return $icon;
252  }
253 
263  public function PMiconATagWrap($icon, $cmd, $isExpand = true)
264  {
265  if ($this->thisScript) {
266  // Activate dynamic ajax-based tree
267  $js = htmlspecialchars('Tree.load(' . GeneralUtility::quoteJSvalue($cmd) . ', ' . (int)$isExpand . ', this);');
268  return '<a class="list-tree-control' . (!$isExpand ? ' list-tree-control-open' : ' list-tree-control-closed') . '" onclick="' . $js . '"><i class="fa"></i></a>';
269  } else {
270  return $icon;
271  }
272  }
273 
280  public function getBrowsableTree()
281  {
282  // Get stored tree structure AND updating it if needed according to incoming PM GET var.
283  $this->initializePositionSaving();
284  // Init done:
285  $treeArr = [];
286  // Traverse mounts:
287  $firstHtml = '';
288  foreach ($this->MOUNTS as $idx => $uid) {
289  // Set first:
290  $this->bank = $idx;
291  $isOpen = $this->stored[$idx][$uid] || $this->expandFirst || $uid === '0';
292  // Save ids while resetting everything else.
293  $curIds = $this->ids;
294  $this->reset();
295  $this->ids = $curIds;
296  // Only, if not for uid 0
297  if ($uid) {
298  // Set PM icon for root of mount:
299  $cmd = $this->bank . '_' . ($isOpen ? '0_' : '1_') . $uid . '_' . $this->treeName;
300  $firstHtml = '<a class="list-tree-control list-tree-control-' . ($isOpen ? 'open' : 'closed')
301  . '" href="' . htmlspecialchars($this->getThisScript() . 'PM=' . $cmd) . '"><i class="fa"></i></a>';
302  }
303  // Preparing rootRec for the mount
304  if ($uid) {
305  $rootRec = $this->getRecord($uid);
306  $firstHtml .= $this->getIcon($rootRec);
307  } else {
308  // Artificial record for the tree root, id=0
309  $rootRec = $this->getRootRecord();
310  $firstHtml .= $this->getRootIcon($rootRec);
311  }
312  if (is_array($rootRec)) {
313  // In case it was swapped inside getRecord due to workspaces.
314  $uid = $rootRec['uid'];
315  // Add the root of the mount to ->tree
316  $this->tree[] = ['HTML' => $firstHtml, 'row' => $rootRec, 'bank' => $this->bank, 'hasSub' => true, 'invertedDepth' => 1000];
317  // If the mount is expanded, go down:
318  if ($isOpen) {
319  // Set depth:
320  if ($this->addSelfId) {
321  $this->ids[] = $uid;
322  }
323  $this->getTree($uid);
324  }
325  // Add tree:
326  $treeArr = array_merge($treeArr, $this->tree);
327  }
328  }
329  return $this->printTree($treeArr);
330  }
331 }
if(!defined("DB_ERROR")) define("DB_ERROR"
static implodeAttributes(array $arr, $xhtmlSafe=false, $dontOmitBlankAttribs=false)
wrapTitle($title, $row, $bank=0)
init($clause='', $orderByFields='')
static callUserFunction($funcName, &$params, &$ref, $checkPrefix='', $errorMode=0)
getTree($uid, $depth=999, $depthData='')
$uid
Definition: server.php:38
PMiconATagWrap($icon, $cmd, $isExpand=true)
static wrapClickMenuOnIcon( $content, $table, $uid=0, $listFrame=true, $addParams='', $enDisItems='', $returnTagParameters=false)
PMicon($row, $a, $c, $nextCount, $exp)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']