2 namespace TYPO3\CMS\Backend\Tree\View
;
4 /***************************************************************
7 * (c) 1999-2013 Kasper Skårhøj (kasperYYYY@typo3.com)
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the textfile GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
30 use TYPO3\CMS\Backend\Utility\IconUtility
;
31 use TYPO3\CMS\Core\
Resource\FolderInterface
;
32 use TYPO3\CMS\Core\Utility\GeneralUtility
;
35 * Generate a folder tree,
36 * specially made for browsing folders in the File module
38 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
39 * @coauthor René Fritz <r.fritz@colorcube.de>
41 class FolderTreeView
extends \TYPO3\CMS\Backend\Tree\View\AbstractTreeView
{
44 * The users' file Storages
46 * @var \TYPO3\CMS\Core\Resource\ResourceStorage[]
48 protected $storages = NULL;
53 protected $storageHashNumbers;
56 * Indicates, whether the AJAX call was successful,
57 * i.e. the requested page has been found
61 protected $ajaxStatus = FALSE;
64 * Constructor function of the class
66 public function __construct() {
68 $this->storages
= $GLOBALS['BE_USER']->getFileStorages();
69 $this->treeName
= 'folder';
70 // Don't apply any title
71 $this->titleAttrib
= '';
72 $this->domIdPrefix
= 'folder';
76 * Generate the plus/minus icon for the browsable tree.
78 * @param \TYPO3\CMS\Core\Resource\Folder $folderObject Entry folder object
79 * @param integer $subFolderCounter The current entry number
80 * @param integer $totalSubFolders The total number of entries. If equal to $a, a "bottom" element is returned.
81 * @param integer $nextCount The number of sub-elements to the current element.
82 * @param boolean $isExpanded The element was expanded to render subelements if this flag is set.
83 * @return string Image tag with the plus/minus icon.
85 * @see \TYPO3\CMS\Backend\Tree\View\PageTreeView::PMicon()
87 public function PMicon(\TYPO3\CMS\Core\
Resource\Folder
$folderObject, $subFolderCounter, $totalSubFolders, $nextCount, $isExpanded) {
88 $PM = $nextCount ?
($isExpanded ?
'minus' : 'plus') : 'join';
89 $BTM = $subFolderCounter == $totalSubFolders ?
'bottom' : '';
90 $icon = '<img' . IconUtility
::skinImg($this->backPath
, ('gfx/ol/' . $PM . $BTM . '.gif'), 'width="18" height="16"') . ' alt="" />';
92 $cmd = $this->generateExpandCollapseParameter($this->bank
, !$isExpanded, $folderObject);
93 $icon = $this->PMiconATagWrap($icon, $cmd, !$isExpanded);
99 * Wrap the plus/minus icon in a link
101 * @param string $icon HTML string to wrap, probably an image tag.
102 * @param string $cmd Command for 'PM' get var
103 * @param boolean $isExpand Whether to be expanded
104 * @return string Link-wrapped input string
107 public function PMiconATagWrap($icon, $cmd, $isExpand = TRUE) {
108 if ($this->thisScript
) {
109 // Activates dynamic AJAX based tree
110 $js = htmlspecialchars('Tree.load(\'' . $cmd . '\', ' . intval($isExpand) . ', this);');
111 return '<a class="pm" onclick="' . $js . '">' . $icon . '</a>';
118 * Wrapping the folder icon
120 * @param string $icon The image tag for the icon
121 * @param \TYPO3\CMS\Core\Resource\Folder $folderObject The row for the current element
122 * @return string The processed icon input value.
125 public function wrapIcon($icon, \TYPO3\CMS\Core\
Resource\Folder
$folderObject) {
126 // Add title attribute to input icon tag
127 $theFolderIcon = $this->addTagAttributes($icon, $this->titleAttrib ?
$this->titleAttrib
. '="' . $this->getTitleAttrib($folderObject) . '"' : '');
128 // Wrap icon in click-menu link.
129 if (!$this->ext_IconMode
) {
130 // Check storage access to wrap with click menu
131 if ($folderObject->getStorage()->hasFolder('/')) {
132 $theFolderIcon = $GLOBALS['TBE_TEMPLATE']->wrapClickMenuOnIcon($theFolderIcon, $folderObject->getCombinedIdentifier(), '', 0);
134 } elseif (!strcmp($this->ext_IconMode
, 'titlelink')) {
135 $aOnClick = 'return jumpTo(\'' . $this->getJumpToParam($folderObject) . '\',this,\'' . $this->domIdPrefix
. $this->getId($folderObject) . '\',' . $this->bank
. ');';
136 $theFolderIcon = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . $theFolderIcon . '</a>';
138 return $theFolderIcon;
142 * Wrapping $title in a-tags.
144 * @param string $title Title string
145 * @param \TYPO3\CMS\Core\Resource\Folder $folderObject the folder record
146 * @param integer $bank Bank pointer (which mount point number)
150 public function wrapTitle($title, \TYPO3\CMS\Core\
Resource\Folder
$folderObject, $bank = 0) {
151 // Check storage access to wrap with click menu
152 if (!$folderObject->getStorage()->hasFolder('/')) {
155 $aOnClick = 'return jumpTo(\'' . $this->getJumpToParam($folderObject) . '\', this, \'' . $this->domIdPrefix
. $this->getId($folderObject) . '\', ' . $bank . ');';
156 $CSM = ' oncontextmenu="' . htmlspecialchars($GLOBALS['TBE_TEMPLATE']->wrapClickMenuOnIcon('', $folderObject->getCombinedIdentifier(), '', 0, ('&bank=' . $this->bank
), '', TRUE)) . '"';
158 return '<a href="#" title="' . htmlspecialchars($title) . '" onclick="' . htmlspecialchars($aOnClick) . '"' . $CSM . '>' . $title . '</a>';
162 * Returns the id from the record - for folders, this is an md5 hash.
164 * @param \TYPO3\CMS\Core\Resource\Folder $folderObject The folder object
165 * @return integer The "uid" field value.
167 public function getId(\TYPO3\CMS\Core\
Resource\Folder
$folderObject) {
168 return GeneralUtility
::md5Int($folderObject->getCombinedIdentifier());
172 * Returns jump-url parameter value.
174 * @param \TYPO3\CMS\Core\Resource\Folder $folderObject The folder object
175 * @return string The jump-url parameter.
177 public function getJumpToParam(\TYPO3\CMS\Core\
Resource\Folder
$folderObject) {
178 return rawurlencode($folderObject->getCombinedIdentifier());
182 * Returns the title for the input record. If blank, a "no title" labele (localized) will be returned.
183 * '_title' is used for setting an alternative title for folders.
185 * @param array $row The input row array (where the key "_title" is used for the title)
186 * @param integer $titleLen Title length (30)
187 * @return string The title
189 public function getTitleStr($row, $titleLen = 30) {
190 return $row['_title'] ?
$row['_title'] : parent
::getTitleStr($row, $titleLen);
194 * Returns the value for the image "title" attribute
196 * @param \TYPO3\CMS\Core\Resource\Folder $folderObject The folder to be used
197 * @return string The attribute value (is htmlspecialchared() already)
198 * @todo Define visibility
200 public function getTitleAttrib(\TYPO3\CMS\Core\
Resource\Folder
$folderObject) {
201 return htmlspecialchars($folderObject->getName());
205 * Will create and return the HTML code for a browsable tree of folders.
206 * Is based on the mounts found in the internal array ->MOUNTS (set in the constructor)
208 * @return string HTML code for the browsable tree
210 public function getBrowsableTree() {
211 // Get stored tree structure AND updating it if needed according to incoming PM GET var.
212 $this->initializePositionSaving();
214 $treeItems = array();
216 foreach ($this->storages
as $storageObject) {
217 $this->getBrowseableTreeForStorage($storageObject);
219 $treeItems = array_merge($treeItems, $this->tree
);
220 // if this is an AJAX call, don't run through all mounts, only
221 // show the expansion of the current one, not the rest of the mounts
222 if (TYPO3_REQUESTTYPE
& TYPO3_REQUESTTYPE_AJAX
) {
226 return $this->printTree($treeItems);
230 * Get a tree for one storage
232 * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storageObject
235 public function getBrowseableTreeForStorage(\TYPO3\CMS\Core\
Resource\ResourceStorage
$storageObject) {
236 // If there are filemounts, show each, otherwise just the rootlevel folder
237 $fileMounts = $storageObject->getFileMounts();
238 $rootLevelFolders = array();
239 if (count($fileMounts)) {
240 foreach ($fileMounts as $fileMountInfo) {
241 $rootLevelFolders[] = array(
242 'folder' => $fileMountInfo['folder'],
243 'name' => $fileMountInfo['title']
247 $rootLevelFolders[] = array(
248 'folder' => $storageObject->getRootLevelFolder(),
249 'name' => $storageObject->getName()
254 // Go through all "root level folders" of this tree (can be the rootlevel folder or any file mount points)
255 foreach ($rootLevelFolders as $rootLevelFolderInfo) {
256 /** @var $rootLevelFolder \TYPO3\CMS\Core\Resource\Folder */
257 $rootLevelFolder = $rootLevelFolderInfo['folder'];
258 $rootLevelFolderName = $rootLevelFolderInfo['name'];
259 $folderHashSpecUID = GeneralUtility
::md5int($rootLevelFolder->getCombinedIdentifier());
260 $this->specUIDmap
[$folderHashSpecUID] = $rootLevelFolder->getCombinedIdentifier();
262 $storageHashNumber = $this->getShortHashNumberForStorage($storageObject, $rootLevelFolder);
264 $this->bank
= $storageHashNumber;
265 $isOpen = $this->stored
[$storageHashNumber][$folderHashSpecUID] ||
$this->expandFirst
;
267 $cmd = $this->generateExpandCollapseParameter($this->bank
, !$isOpen, $rootLevelFolder);
268 if (!$storageObject->isBrowsable() ||
$this->getNumberOfSubfolders($rootLevelFolder) === 0) {
270 } elseif (!$isOpen) {
271 $rootIcon = 'plusonly';
273 $rootIcon = 'minusonly';
275 $icon = '<img' . IconUtility
::skinImg($this->backPath
, ('gfx/ol/' . $rootIcon . '.gif')) . ' alt="" />';
276 // Only link icon if storage is browseable
277 if (in_array($rootIcon, array('minusonly', 'plusonly'))) {
278 $firstHtml = $this->PM_ATagWrap($icon, $cmd);
282 // @todo: create sprite icons for user/group mounts etc
283 if ($storageObject->isBrowsable() === FALSE) {
284 $icon = 'apps-filetree-folder-locked';
286 $icon = 'apps-filetree-root';
288 // Mark a storage which is not online, as offline
289 // maybe someday there will be a special icon for this
290 if ($storageObject->isOnline() === FALSE) {
291 $rootLevelFolderName .= ' (' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_mod_file.xlf:sys_file_storage.isOffline') . ')';
293 // Preparing rootRec for the mount
294 $firstHtml .= $this->wrapIcon(IconUtility
::getSpriteIcon($icon), $rootLevelFolder);
296 'uid' => $folderHashSpecUID,
297 'title' => $rootLevelFolderName,
298 'path' => $rootLevelFolder->getCombinedIdentifier(),
299 'folder' => $rootLevelFolder
301 // Add the storage root to ->tree
302 $this->tree
[] = array(
303 'HTML' => $firstHtml,
305 'bank' => $this->bank
,
306 // hasSub is TRUE when the root of the storage is expanded
307 'hasSub' => $isOpen && $storageObject->isBrowsable()
309 // If the mount is expanded, go down:
310 if ($isOpen && $storageObject->isBrowsable()) {
312 $this->getFolderTree($rootLevelFolder, 999);
318 * Fetches the data for the tree
320 * @param \TYPO3\CMS\Core\Resource\Folder $folderObject the folderobject
321 * @param integer $depth Max depth (recursivity limit)
322 * @param string $type HTML-code prefix for recursive calls.
323 * @return integer The count of items on the level
324 * @see getBrowsableTree()
326 public function getFolderTree(\TYPO3\CMS\Core\
Resource\Folder
$folderObject, $depth = 999, $type = '') {
327 $depth = intval($depth);
329 // This generates the directory tree
330 /* array of \TYPO3\CMS\Core\Resource\Folder */
331 $subFolders = $folderObject->getSubfolders();
332 $subFolders = \TYPO3\CMS\Core\
Resource\Utility\ListUtility
::resolveSpecialFolderNames($subFolders);
333 uksort($subFolders, 'strnatcasecmp');
335 $totalSubFolders = count($subFolders);
337 $subFolderCounter = 0;
338 foreach ($subFolders as $subFolderName => $subFolder) {
341 $this->tree
[] = array();
342 // Get the key for this space
344 $treeKey = key($this->tree
);
345 $specUID = GeneralUtility
::md5int($subFolder->getCombinedIdentifier());
346 $this->specUIDmap
[$specUID] = $subFolder->getCombinedIdentifier();
349 'path' => $subFolder->getCombinedIdentifier(),
350 'title' => $subFolderName,
351 'folder' => $subFolder
353 // Make a recursive call to the next level
354 if ($depth > 1 && $this->expandNext($specUID)) {
355 $nextCount = $this->getFolderTree($subFolder, $depth - 1, $type);
356 // Set "did expand" flag
359 $nextCount = $this->getNumberOfSubfolders($subFolder);
360 // Clear "did expand" flag
363 // Set HTML-icons, if any:
364 if ($this->makeHTML
) {
365 $HTML = $this->PMicon($subFolder, $subFolderCounter, $totalSubFolders, $nextCount, $isOpen);
366 if ($subFolder->checkActionPermission('write')) {
371 $overlays = array('status-overlay-locked' => array());
374 $icon = 'apps-filetree-folder-opened';
376 $icon = 'apps-filetree-folder-default';
378 $role = $subFolder->getRole();
379 if ($role !== FolderInterface
::ROLE_DEFAULT
) {
380 $row['_title'] = '<strong>' . $subFolderName . '</strong>';
382 if ($role === FolderInterface
::ROLE_TEMPORARY
) {
383 $icon = 'apps-filetree-folder-temp';
384 } elseif ($role === FolderInterface
::ROLE_RECYCLER
) {
385 $icon = 'apps-filetree-folder-recycler';
387 $icon = IconUtility
::getSpriteIcon($icon, array('title' => $subFolderName), $overlays);
388 $HTML .= $this->wrapIcon($icon, $subFolder);
390 // Finally, add the row/HTML content to the ->tree array in the reserved key.
391 $this->tree
[$treeKey] = array(
394 'hasSub' => $nextCount && $this->expandNext($specUID),
395 'isFirst' => $subFolderCounter == 1,
397 'invertedDepth' => $depth,
398 'bank' => $this->bank
401 if ($subFolderCounter > 0) {
402 $this->tree
[$treeKey]['isLast'] = TRUE;
404 return $totalSubFolders;
408 * Compiles the HTML code for displaying the structure found inside the ->tree array
410 * @param array|string $treeItems "tree-array" - if blank string, the internal ->tree array is used.
411 * @return string The HTML code for the tree
413 public function printTree($treeItems = '') {
417 $titleLength = intval($this->BE_USER
->uc
['titleLen']);
418 if (!is_array($treeItems)) {
419 $treeItems = $this->tree
;
422 <!-- TYPO3 folder tree structure. -->
423 <ul class="tree" id="treeRoot">
425 // Evaluate AJAX request
426 if (TYPO3_REQUESTTYPE
& TYPO3_REQUESTTYPE_AJAX
) {
427 list(, $expandCollapseCommand, $expandedFolderHash, ) = $this->evaluateExpandCollapseParameter();
428 if ($expandCollapseCommand == 1) {
429 // We don't know yet. Will be set later.
430 $invertedDepthOfAjaxRequestedItem = 0;
436 // We need to count the opened <ul>'s every time we dig into another level,
437 // so we know how many we have to close when all children are done rendering
438 $closeDepth = array();
439 foreach ($treeItems as $treeItem) {
440 /** @var $folderObject \TYPO3\CMS\Core\Resource\Folder */
441 $folderObject = $treeItem['row']['folder'];
442 $classAttr = $treeItem['row']['_CSSCLASS'];
443 $folderIdentifier = $folderObject->getCombinedIdentifier();
444 // this is set if the AJAX request has just opened this folder (via the PM command)
445 $isExpandedFolderIdentifier = $expandedFolderHash == GeneralUtility
::md5int($folderIdentifier);
446 $idAttr = htmlspecialchars($this->domIdPrefix
. $this->getId($folderObject) . '_' . $treeItem['bank']);
448 // If this item is the start of a new level,
449 // then a new level <ul> is needed, but not in ajax mode
450 if ($treeItem['isFirst'] && !$doCollapse && !($doExpand && $isExpandedFolderIdentifier)) {
454 // Add CSS classes to the list item
455 if ($treeItem['hasSub']) {
456 $classAttr .= ' expanded';
458 if ($treeItem['isLast']) {
459 $classAttr .= ' last';
462 <li id="' . $idAttr . '" ' . ($classAttr ?
' class="' . trim($classAttr) . '"' : '') . '><div class="treeLinkItem">' . $treeItem['HTML'] . $this->wrapTitle($this->getTitleStr($treeItem['row'], $titleLength), $folderObject, $treeItem['bank']) . '</div>';
463 if (!$treeItem['hasSub']) {
467 // We have to remember if this is the last one
468 // on level X so the last child on level X+1 closes the <ul>-tag
469 if ($treeItem['isLast'] && !($doExpand && $isExpandedFolderIdentifier)) {
470 $closeDepth[$treeItem['invertedDepth']] = 1;
472 // If this is the last one and does not have subitems, we need to close
473 // the tree as long as the upper levels have last items too
474 if ($treeItem['isLast'] && !$treeItem['hasSub'] && !$doCollapse && !($doExpand && $isExpandedFolderIdentifier)) {
475 for ($i = $treeItem['invertedDepth']; $closeDepth[$i] == 1; $i++
) {
477 $itemHTML .= '</ul></li>
481 // Ajax request: collapse
482 if ($doCollapse && $isExpandedFolderIdentifier) {
483 $this->ajaxStatus
= TRUE;
486 // Ajax request: expand
487 if ($doExpand && $isExpandedFolderIdentifier) {
488 $ajaxOutput .= $itemHTML;
489 $invertedDepthOfAjaxRequestedItem = $treeItem['invertedDepth'];
490 } elseif ($invertedDepthOfAjaxRequestedItem) {
491 if ($treeItem['invertedDepth'] < $invertedDepthOfAjaxRequestedItem) {
492 $ajaxOutput .= $itemHTML;
494 $this->ajaxStatus
= TRUE;
500 // If this is a AJAX request, output directly
502 $this->ajaxStatus
= TRUE;
505 // Finally close the first ul
512 * Counts the number of directories in a file path.
514 * @param string $file File path.
516 * @deprecated since TYPO3 6.0, as the folder objects do the counting automatically
518 public function getCount($file) {
519 GeneralUtility
::logDeprecatedFunction();
520 // This generates the directory tree
521 $dirs = GeneralUtility
::get_dirs($file);
523 if (is_array($dirs)) {
530 * Counts the number of directories in a file path.
532 * @param \TYPO3\CMS\Core\Resource\Folder $folderObject File path.
535 public function getNumberOfSubfolders(\TYPO3\CMS\Core\
Resource\Folder
$folderObject) {
536 $subFolders = $folderObject->getSubfolders();
537 return count($subFolders);
541 * Get stored tree structure AND updating it if needed according to incoming PM GET var.
545 * @todo Define visibility
547 public function initializePositionSaving() {
548 // Get stored tree structure:
549 $this->stored
= unserialize($this->BE_USER
->uc
['browseTrees'][$this->treeName
]);
550 $this->getShortHashNumberForStorage();
552 // (If an plus/minus icon has been clicked,
553 // the PM GET var is sent and we must update the stored positions in the tree):
554 // 0: mount key, 1: set/clear boolean, 2: item ID (cannot contain "_"), 3: treeName
555 list($storageHashNumber, $doExpand, $numericFolderHash, $treeName) = $this->evaluateExpandCollapseParameter();
556 if ($treeName && $treeName == $this->treeName
) {
557 if (in_array($storageHashNumber, $this->storageHashNumbers
)) {
558 if ($doExpand == 1) {
560 $this->stored
[$storageHashNumber][$numericFolderHash] = 1;
563 unset($this->stored
[$storageHashNumber][$numericFolderHash]);
565 $this->savePosition();
571 * Helper method to map md5-hash to shorter number
573 * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storageObject
574 * @param \TYPO3\CMS\Core\Resource\Folder $startingPointFolder
577 protected function getShortHashNumberForStorage(\TYPO3\CMS\Core\
Resource\ResourceStorage
$storageObject = NULL, \TYPO3\CMS\Core\
Resource\Folder
$startingPointFolder = NULL) {
578 if (!$this->storageHashNumbers
) {
579 $this->storageHashNumbers
= array();
580 // Mapping md5-hash to shorter number:
582 foreach ($this->storages
as $storageUid => $storage) {
583 $fileMounts = $storage->getFileMounts();
584 if (count($fileMounts)) {
585 foreach ($fileMounts as $fileMount) {
586 $nkey = hexdec(substr(GeneralUtility
::md5int($fileMount['folder']->getCombinedIdentifier()), 0, 4));
587 $this->storageHashNumbers
[$storageUid . $fileMount['folder']->getCombinedIdentifier()] = $nkey;
590 $folder = $storage->getRootLevelFolder();
591 $nkey = hexdec(substr(GeneralUtility
::md5int($folder->getCombinedIdentifier()), 0, 4));
592 $this->storageHashNumbers
[$storageUid . $folder->getCombinedIdentifier()] = $nkey;
596 if ($storageObject) {
597 if ($startingPointFolder) {
598 return $this->storageHashNumbers
[$storageObject->getUid() . $startingPointFolder->getCombinedIdentifier()];
600 return $this->storageHashNumbers
[$storageObject->getUid()];
608 * Gets the values from the Expand/Collapse Parameter (&PM)
609 * previously known as "PM" (plus/minus)
611 * (If an plus/minus icon has been clicked,
612 * the PM GET var is sent and we must update the stored positions in the tree):
613 * 0: mount key, 1: set/clear boolean, 2: item ID (cannot contain "_"), 3: treeName
615 * @param string $PM The "plus/minus" command
618 protected function evaluateExpandCollapseParameter($PM = NULL) {
620 $PM = GeneralUtility
::_GP('PM');
621 // IE takes anchor as parameter
622 if (($PMpos = strpos($PM, '#')) !== FALSE) {
623 $PM = substr($PM, 0, $PMpos);
626 // Take the first three parameters
627 list($mountKey, $doExpand, $folderIdentifier) = explode('_', $PM, 3);
628 // In case the folder identifier contains "_", we just need to get the fourth/last parameter
629 list($folderIdentifier, $treeName) = GeneralUtility
::revExplode('_', $folderIdentifier, 2);
639 * Generates the "PM" string to sent to expand/collapse items
641 * @param string $mountKey The mount key / storage UID
642 * @param boolean $doExpand Whether to expand/collapse
643 * @param \TYPO3\CMS\Core\Resource\Folder $folderObject The folder object
644 * @param string $treeName The name of the tree
647 protected function generateExpandCollapseParameter($mountKey = NULL, $doExpand = FALSE, \TYPO3\CMS\Core\
Resource\Folder
$folderObject = NULL, $treeName = NULL) {
649 $mountKey !== NULL ?
$mountKey : $this->bank
,
650 $doExpand == 1 ?
1 : 0,
651 $folderObject !== NULL ? GeneralUtility
::md5int($folderObject->getCombinedIdentifier()) : '',
652 $treeName !== NULL ?
$treeName : $this->treeName
654 return implode('_', $parts);
658 * Gets the AJAX status.
662 public function getAjaxStatus() {
663 return $this->ajaxStatus
;