2010-12-01 Steffen Kamper <steffen@typo3.org>
+ * Fixed bug #16622: PageTree - Milestone 2 Release (Thanks to Stefan Galinski + Peter Foerger)
* Fixed bug #16621: Stabilize the Context Menu API (Thanks to Stefan Galinski)
* Fixed bug #16463: Bug: Custom configured modules can't be enabled for non-admins (Thanks to Bastian Waidelich)
* Fixed bug #16091: ExtDirect calls get cached with domain resulting in "unable to connect to the server" exceptions (Thanks to Andreas Kiessling)
--- /dev/null
+<?php
+/***************************************************************
+* Copyright notice
+*
+* (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+* 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.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* 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!
+***************************************************************/
+
+/**
+ * Page Tree and Context Menu Commands
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+final class tx_pagetree_Commands {
+ /**
+ * Visibly the page
+ *
+ * @param tx_pagetree_Node $nodeData
+ * @return void
+ */
+ public static function visiblyNode(tx_pagetree_Node $node) {
+ $data['pages'][$node->getId()]['hidden'] = 0;
+ self::processTceCmdAndDataMap(array(), $data);
+ }
+
+ /**
+ * Hide the page
+ *
+ * @param tx_pagetree_Node $nodeData
+ * @return void
+ */
+ public static function disableNode(tx_pagetree_Node $node) {
+ $data['pages'][$node->getId()]['hidden'] = 1;
+ self::processTceCmdAndDataMap(array(), $data);
+ }
+
+ /**
+ * Delete the page
+ *
+ * @param tx_pagetree_Node $nodeData
+ * @return void
+ */
+ public static function deleteNode(tx_pagetree_Node $node) {
+ $cmd['pages'][$node->getId()]['delete'] = 1;
+ self::processTceCmdAndDataMap($cmd);
+ }
+
+ /**
+ * Restore the page
+ *
+ * @param tx_pagetree_Node $nodeData
+ * @return void
+ */
+ public static function restoreNode(tx_pagetree_Node $node) {
+ $cmd['pages'][$node->getId()]['undelete'] = 1;
+ self::processTceCmdAndDataMap($cmd);
+ }
+
+ /**
+ * Updates the node label
+ *
+ * @param tx_pagetree_Node $nodeData
+ * @param string $updatedLabel
+ * @return void
+ */
+ public static function updateNodeLabel(tx_pagetree_Node $node, $updatedLabel) {
+ $updatedLabel = str_replace($node->getPrefix(), '', $updatedLabel);
+ $data['pages'][$node->getId()][$node->getTextSourceField()] = $updatedLabel;
+ self::processTceCmdAndDataMap(array(), $data);
+ }
+
+ /**
+ * Copies a page and returns the id of the new page
+ *
+ * Node: Use a negative target id to specify a sibling target else the parent is used
+ *
+ * @param tx_pagetree_Node $sourceNode
+ * @param int $targetId
+ * @return int
+ */
+ public static function copyNode(tx_pagetree_Node $sourceNode, $targetId) {
+ $cmd['pages'][$sourceNode->getId()]['copy'] = $targetId;
+ $returnValue = self::processTceCmdAndDataMap($cmd);
+
+ return $returnValue['pages'][$sourceNode->getId()];
+ }
+
+ /**
+ * Moves a page
+ *
+ * Node: Use a negative target id to specify a sibling target else the parent is used
+ *
+ * @param tx_pagetree_Node $sourceNode
+ * @param int $targetId
+ * @return void
+ */
+ public static function moveNode(tx_pagetree_Node $sourceNode, $targetId) {
+ $cmd['pages'][$sourceNode->getId()]['move'] = $targetId;
+ self::processTceCmdAndDataMap($cmd);
+ }
+
+ /**
+ * Creates a page of the given doktype and returns the id of the created page
+ *
+ * @param tx_pagetree_Node $parentNode
+ * @param int $targetId
+ * @param int $pageType
+ * @return int
+ */
+ public static function createNode(tx_pagetree_Node $parentNode, $targetId, $pageType) {
+ $placeholder = 'NEW12345';
+ $data['pages'][$placeholder] = array(
+ 'pid' => $parentNode->getId(),
+ 'doktype' => $pageType,
+ 'title' => $GLOBALS['LANG']->sL('LLL:EXT:pagetree/locallang_pagetree.xml:defaultTitle', TRUE),
+ );
+ $newPageId = self::processTceCmdAndDataMap(array(), $data);
+ $node = self::getNode($newPageId[$placeholder]);
+
+ if ($parentNode->getId() !== $targetId) {
+ self::moveNode($node, $targetId);
+ }
+
+ return $newPageId[$placeholder];
+ }
+
+ /**
+ * Process TCEMAIN commands and data maps
+ *
+ * Command Map:
+ * Used for moving, recover, remove and some more operations.
+ *
+ * Data Map:
+ * Used for creating and updating records,
+ *
+ * This API contains all necessary access checks.
+ *
+ * @param array $cmd
+ * @param array $data
+ * @throws Exception if an error happened while the TCE processing
+ * @return array
+ */
+ protected static function processTceCmdAndDataMap(array $cmd, array $data = array()) {
+ /** @var $tce t3lib_TCEmain */
+ $tce = t3lib_div::makeInstance('t3lib_TCEmain');
+ $tce->stripslashes_values = 0;
+ $tce->start($data, $cmd);
+
+ if (count($cmd)) {
+ $tce->process_cmdmap();
+ $returnValues = $tce->copyMappingArray_merged;
+ } elseif (count($data)) {
+ $tce->process_datamap();
+ $returnValues = $tce->substNEWwithIDs;
+ }
+
+ // check errors
+ if (count($tce->errorLog)) {
+ throw new Exception(implode(chr(10), $tce->errorLog));
+ }
+
+ return $returnValues;
+ }
+
+ /**
+ * Returns a node from the given node id
+ *
+ * @param int $nodeId
+ * @return tx_pagetree_Node
+ */
+ public static function getNode($nodeId) {
+ $record = self::getNodeRecord($nodeId);
+ return self::getNewNode($record);
+ }
+
+ /**
+ * Returns a node record from a given id
+ *
+ * @param int $nodeId
+ * @return array
+ */
+ public static function getNodeRecord($nodeId) {
+ return t3lib_BEfunc::getRecordWSOL('pages', $nodeId, '*', '', TRUE);
+ }
+
+ /**
+ * Creates a node with the given record information's
+ *
+ * @param array $record
+ * @return tx_pagetree_Node
+ */
+ public static function getNewNode($record) {
+ $useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
+ $addIdAsPrefix = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
+
+ /** @var $subNode tx_pagetree_Node */
+ $subNode = t3lib_div::makeInstance('tx_pagetree_Node');
+ $subNode->setRecord($record);
+ $subNode->setId($record['uid']);
+ $subNode->setQTip('ID: ' . $record['uid']);
+
+ $field = 'title';
+ $text = $record['title'];
+ if ($useNavTitle && trim($record['nav_title']) !== '') {
+ $field = 'nav_title';
+ $text = $record['nav_title'];
+ }
+
+ $prefix = ($addIdAsPrefix ? '[' . $record['uid'] . '] ' : '');
+ $subNode->setText($text, $field, $prefix);
+
+ if ($record['uid'] !== 0) {
+ $spriteIconCode = t3lib_iconWorks::getSpriteIconForRecord('pages', $record);
+ } else {
+ $spriteIconCode = t3lib_iconWorks::getSpriteIcon('apps-pagetree-root');
+ }
+ $subNode->setSpriteIconCode($spriteIconCode);
+
+ return $subNode;
+ }
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***************************************************************
+* Copyright notice
+*
+* (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+* 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.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* 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!
+***************************************************************/
+
+/**
+ * Abstract Tree Data Provider
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+class tx_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
+ /**
+ * Returns the root node
+ *
+ * Not used for the page tree, because the multiple domains/roots feature
+ *
+ * @return t3lib_tree_Node
+ */
+ public function getRoot() {
+ return NULL;
+ }
+
+ /**
+ * Fetches the sub-nodes of the given node
+ *
+ * @param t3lib_tree_Node $node
+ * @return t3lib_tree_NodeCollection
+ */
+ public function getNodes(t3lib_tree_Node $node) {
+ /** @var $nodeCollection tx_pagetree_NodeCollection */
+ $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
+
+ $subpages = $this->getSubpages($node->getId());
+ if (!is_array($subpages) || !count($subpages)) {
+ return $nodeCollection;
+ }
+
+ foreach ($subpages as $subpage) {
+ $subpage = t3lib_befunc::getRecordWSOL('pages', $subpage['uid'], '*', '', TRUE);
+
+ $subNode = tx_pagetree_Commands::getNewNode($subpage);
+ $childNodes = $this->getNodes($subNode);
+ $subNode->setChildNodes($childNodes);
+
+ $nodeCollection->append($subNode);
+ }
+
+ return $nodeCollection;
+ }
+
+ /**
+ * Returns a node collection of filtered nodes
+ *
+ * @param string $searchFilter
+ * @return void
+ */
+ public function getFilteredNodes($searchFilter) {
+ /** @var $nodeCollection tx_pagetree_NodeCollection */
+ $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
+
+ $subpages = $this->getSubpages(-1, $searchFilter);
+ if (!is_array($subpages) || !count($subpages)) {
+ return $nodeCollection;
+ }
+
+ foreach ($subpages as $subpage) {
+ $rootline = array_reverse(t3lib_BEfunc::BEgetRootLine($subpage['uid']));
+ array_shift($rootline);
+ $reference = $nodeCollection;
+
+ foreach ($rootline as $rootlineElement) {
+ if ($reference->offsetExists($rootlineElement['uid'])) {
+ /** @var $node tx_pagetree_Node */
+ $node = $reference->offsetGet($rootlineElement['uid']);
+ $reference = $node->getChildNodes();
+ continue;
+ }
+
+ /** @var $childCollection tx_pagetree_NodeCollection */
+ $childCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
+
+ $node = tx_pagetree_Commands::getNewNode($rootlineElement);
+ $node->setExpanded(TRUE);
+ $node->setChildNodes($childCollection);
+ $node->setLeaf(FALSE);
+ $node->setText(str_replace(
+ $searchFilter,
+ '<strong class="pagetree-highlight">' . $searchFilter . '</strong>',
+ $node->getText()
+ ));
+
+ $reference->offsetSet($rootlineElement['uid'], $node);
+ $reference = $childCollection;
+ }
+ }
+
+ return $nodeCollection;
+ }
+
+ /**
+ * Returns the page tree mounts for the current user
+ *
+ * @return array
+ */
+ public function getTreeMounts() {
+ /** @var $nodeCollection tx_pagetree_NodeCollection */
+ $nodeCollection = t3lib_div::makeInstance('tx_pagetree_NodeCollection');
+
+ $webmountIds = array_map('intval', $GLOBALS['BE_USER']->returnWebmounts());
+ if (empty($webmountIds)) {
+ return $nodeCollection;
+ }
+
+ foreach ($webmountIds as $webmount) {
+ if ($webmount === 0) {
+ $sitename = 'TYPO3';
+ if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] !== '') {
+ $sitename = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
+ }
+
+ $record = array(
+ 'uid' => 0,
+ 'title' => $sitename,
+ );
+ $subNode = tx_pagetree_Commands::getNewNode($record);
+ $subNode->setEditableLable(FALSE);
+ $subNode->setType('root');
+ } else {
+ $record = t3lib_BEfunc::getRecordWSOL('pages', $webmount, '*', '', TRUE);
+ $subNode = tx_pagetree_Commands::getNewNode($record);
+ }
+
+ $childNodes = $this->getNodes($subNode);
+ $subNode->setChildNodes($childNodes);
+
+ $nodeCollection->append($subNode);
+ }
+
+ return $nodeCollection;
+ }
+
+ /**
+ * Returns all sub-pages of a given id
+ *
+ * @param int $id
+ * @param string $searchFilter
+ * @return array
+ */
+ protected function getSubpages($id, $searchFilter = '') {
+ $where = $GLOBALS['BE_USER']->getPagePermsClause(1)
+ . t3lib_BEfunc::deleteClause('pages')
+ . t3lib_BEfunc::versioningPlaceholderClause('pages');
+
+ if (is_numeric($id) && $id >= 0) {
+ $where .= ' AND pid= ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(intval($id), 'pages');
+ }
+
+ if ($searchFilter !== '') {
+ $where .= ' AND title LIKE ' . $GLOBALS['TYPO3_DB']->fullQuoteStr('%' . $searchFilter . '%', 'pages');
+ }
+
+ $subpages = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+ 'uid', 'pages', $where, '', 'sorting', '', 'uid'
+ );
+
+ return $subpages;
+ }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php']) {
+ include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_dataprovider.php']);
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***************************************************************
+* Copyright notice
+*
+* (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+* 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.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* 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!
+***************************************************************/
+
+/**
+ * Node designated for the page tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+class tx_pagetree_Node extends t3lib_tree_Node {
+ /**
+ * Node type
+ *
+ * @var string
+ */
+ protected $type = 'page';
+
+ /**
+ * Leaf Node Indicator
+ *
+ * @var bool
+ */
+ protected $leaf = TRUE;
+
+ /**
+ * Expanded Node Indicator
+ *
+ * @var bool
+ */
+ protected $expanded = FALSE;
+
+ /**
+ * Label
+ *
+ * @var string
+ */
+ protected $text = '';
+
+ /**
+ * Prefix text of the label
+ *
+ * @var string
+ */
+ protected $prefix = '';
+
+ /**
+ * CSS Class
+ *
+ * @var string
+ */
+ protected $cls = '';
+
+ /**
+ * Quick Tip
+ *
+ * @var string
+ */
+ protected $qtip = '';
+
+ /**
+ * Sprite Icon HTML
+ *
+ * @var string
+ */
+ protected $spriteIconCode = '';
+
+ /**
+ * Text source field (title, nav_title, ...)
+ *
+ * @var string
+ */
+ protected $t3TextSourceField = '';
+
+ /**
+ * Callback action on a node click
+ *
+ * @var string
+ */
+ protected $t3CallbackAction = 'TYPO3.Components.PageTree.PageActions.singleClick';
+
+ /**
+ * Indicator if the copy mode is activated
+ *
+ * @var bool
+ */
+ protected $t3InCopyMode = FALSE;
+
+ /**
+ * Indicator if the cut mode is activated
+ *
+ * @var bool
+ */
+ protected $t3InCutMode = FALSE;
+
+ /**
+ * Database record (not serialized or merged into the result array!)
+ *
+ * @var array
+ */
+ protected $record = array();
+
+ /**
+ * Context Info
+ *
+ * @var array
+ */
+ protected $contextInfo = array();
+
+ /**
+ * Cached access rights to save some performance
+ *
+ * @var array
+ */
+ protected $cachedAccessRights = array();
+
+ /**
+ * Indicator if the label is editable
+ *
+ * @var bool
+ */
+ protected $editableLabel = TRUE;
+
+ /**
+ * Set's the node type
+ *
+ * @param string $type
+ * @return void
+ */
+ public function setType($type) {
+ $this->type = $type;
+ }
+
+ /**
+ * Returns the node type
+ *
+ * @return string
+ */
+ public function getType() {
+ return $this->type;
+ }
+
+ /**
+ * Sets the leaf node indicator
+ *
+ * @param bool $isLeaf
+ * @return void
+ */
+ public function setLeaf($isLeaf) {
+ $this->leaf = $isLeaf;
+ }
+
+ /**
+ * Returns if the node is a leaf node
+ *
+ * @return bool
+ */
+ public function isLeafNode() {
+ return $this->leaf;
+ }
+
+ /**
+ * Sets the expanded indicator
+ *
+ * @param bool $expanded
+ * @return void
+ */
+ public function setExpanded($expanded) {
+ $this->expanded = $expanded;
+ }
+
+ /**
+ * Returns the expanded indicator
+ *
+ * @return bool
+ */
+ public function isExpanded() {
+ return $this->expanded;
+ }
+
+ /**
+ * Sets the label of the node with the source field and the prefix
+ *
+ * @param string $text
+ * @param string $textSourceField
+ * @param string $prefix
+ * @return void
+ */
+ public function setText($text, $textSourceField = 'title', $prefix = '') {
+ $this->text = $text;
+ $this->t3TextSourceField = $textSourceField;
+ $this->prefix = $prefix;
+ }
+
+ /**
+ * Returns the label
+ *
+ * @return string
+ */
+ public function getText() {
+ return $this->text;
+ }
+
+ /**
+ * Returns the source field of the label
+ *
+ * @return string
+ */
+ public function getTextSourceField() {
+ return $this->t3TextSourceField;
+ }
+
+ /**
+ * Sets the paste copy indicator
+ *
+ * @param boolean $inCopyMode
+ * @return void
+ */
+ public function setInCopyMode($inCopyMode) {
+ $this->t3InCopyMode = $inCopyMode;
+ }
+
+ /**
+ * Returns the copy mode indicator
+ *
+ * @return bool
+ */
+ public function isInCopyMode() {
+ return $this->t3InCopyMode;
+ }
+
+ /**
+ * Sets the paste cut indicator
+ *
+ * @param boolean $inCutMode
+ * @return void
+ */
+ public function setInCutMode($inCutMode) {
+ $this->t3InCutMode = $inCutMode;
+ }
+
+ /**
+ * Returns the cut mode indicator
+ *
+ * @return bool
+ */
+ public function isInCutMode() {
+ return $this->t3InCutMode;
+ }
+
+ /**
+ * Returns the prefix text of the label
+ *
+ * @return string
+ */
+ public function getPrefix() {
+ return $this->prefix;
+ }
+
+ /**
+ * Sets the css class(es)
+ *
+ * @param string $class
+ * @return void
+ */
+ public function setCls($class) {
+ $this->cls = $class;
+ }
+
+ /**
+ * Returns the css class(es)
+ *
+ * @return string
+ */
+ public function getCls() {
+ return $this->cls;
+ }
+
+ /**
+ * Sets the quick tip
+ *
+ * @param string $qtip
+ * @return void
+ */
+ public function setQTip($qtip) {
+ $this->qtip = $qtip;
+ }
+
+ /**
+ * Returns the quick tip
+ *
+ * @return string
+ */
+ public function getQTip() {
+ return $this->qtip;
+ }
+
+ /**
+ * Sets the sprite icon code
+ *
+ * @param string $spriteIcon
+ * @return void
+ */
+ public function setSpriteIconCode($spriteIcon) {
+ $this->spriteIconCode = $spriteIcon;
+ }
+
+ /**
+ * Returns the sprite icon code
+ *
+ * @return string
+ */
+ public function getSpriteIconCode() {
+ return $this->spriteIconCode;
+ }
+
+ /**
+ * Sets the callback action
+ *
+ * @param string $callbackAction
+ * @return void
+ */
+ public function setCallbackAction($callbackAction) {
+ $this->t3CallbackAction = $callbackAction;
+ }
+
+ /**
+ * Returns the callback action
+ *
+ * @return string
+ */
+ public function getCallbackAction() {
+ return $this->t3CallbackAction;
+ }
+
+ /**
+ * Sets the indicator if the label is editable
+ *
+ * @param bool $labelIsEditable
+ * @return void
+ */
+ public function setEditableLable($labelIsEditable) {
+ $this->editableLabel = $labelIsEditable;
+ }
+
+ /**
+ * Returns the editable label indicator
+ *
+ * @return bool
+ */
+ public function isLabelEditable() {
+ return $this->editableLabel;
+ }
+
+ /**
+ * Sets the database record array
+ *
+ * @param array $record
+ * @return void
+ */
+ public function setRecord($record) {
+ $this->record = $record;
+ }
+
+ /**
+ * Returns the database record array
+ *
+ * @return array
+ */
+ public function getRecord() {
+ return $this->record;
+ }
+
+ /**
+ * Sets the context info
+ *
+ * @param array $contextInfo
+ * @return void
+ */
+ public function setContextInfo($contextInfo) {
+ $this->contextInfo = $contextInfo;
+ }
+
+ /**
+ * Returns the context info
+ *
+ * @return array
+ */
+ public function getContextInfo() {
+ return (array) $this->contextInfo;
+ }
+
+ /**
+ * Sets the child nodes collection
+ *
+ * @param t3lib_tree_NodeCollection $childNodes
+ * @return void
+ */
+ public function setChildNodes(t3lib_tree_NodeCollection $childNodes) {
+ parent::setChildNodes($childNodes);
+
+ if ($childNodes->count()) {
+ $this->setLeaf(FALSE);
+ }
+ }
+
+ /**
+ * Checks if the user may create pages below the given page
+ *
+ * @return void
+ */
+ protected function canCreate() {
+ if (!isset($this->cachedAccessRights['create'])) {
+ $this->cachedAccessRights['create'] =
+ $GLOBALS['BE_USER']->doesUserHaveAccess($this->record, 8);
+ }
+
+ return $this->cachedAccessRights['create'];
+ }
+
+ /**
+ * Checks if the user has editing rights
+ *
+ * @return void
+ */
+ protected function canEdit() {
+ if (!isset($this->cachedAccessRights['edit'])) {
+ $this->cachedAccessRights['edit'] =
+ $GLOBALS['BE_USER']->doesUserHaveAccess($this->record, 2);
+ }
+
+ return $this->cachedAccessRights['edit'];
+ }
+
+ /**
+ * Checks if the user has the right to delete the page
+ *
+ * @return void
+ */
+ protected function canRemove() {
+ if (!isset($this->cachedAccessRights['remove'])) {
+ $this->cachedAccessRights['remove'] =
+ $GLOBALS['BE_USER']->doesUserHaveAccess($this->record, 4);
+
+ if (!$this->isLeafNode() && !$GLOBALS['BE_USER']->uc['recursiveDelete']) {
+ $this->cachedAccessRights['remove'] = FALSE;
+ }
+ }
+
+ return $this->cachedAccessRights['remove'];
+ }
+
+ /**
+ * Checks if the page can be disabled
+ *
+ * @return void
+ */
+ public function canBeDisabledAndEnabled() {
+ return $this->canEdit($this->record);
+ }
+
+ /**
+ * Checks if the page is allowed to can be cut
+ *
+ * @return void
+ */
+ public function canBeCut() {
+ return $this->canEdit($this->record);
+ }
+
+ /**
+ * Checks if the page is allowed to be edited
+ *
+ * @return void
+ */
+ public function canBeEdited() {
+ return $this->canEdit($this->record);
+ }
+
+ /**
+ * Checks if the page is allowed to be copied
+ *
+ * @return void
+ */
+ public function canBeCopied() {
+ return $this->canCreate($this->record);
+ }
+
+ /**
+ * Checks if there can be new pages created
+ *
+ * @return void
+ */
+ public function canCreateNewPages() {
+ return $this->canCreate($this->record);
+ }
+
+ /**
+ * Checks if the page is allowed to be removed
+ *
+ * @return void
+ */
+ public function canBeRemoved() {
+ return $this->canRemove($this->record);
+ }
+
+ /**
+ * Checks if the page is allowed to show history
+ *
+ * @return void
+ */
+ public function canShowHistory() {
+ return TRUE;
+ }
+
+ /**
+ * Checks if the page is allowed to be viewed
+ *
+ * @return void
+ */
+ public function canBeViewed() {
+ return TRUE;
+ }
+
+ /**
+ * Checks if the page is allowed to show info
+ *
+ * @return void
+ */
+ public function canShowInfo() {
+ return TRUE;
+ }
+
+ /**
+ * Checks if the page is allowed to be a temporary mount point
+ *
+ * @return void
+ */
+ public function canBeTemporaryMountPoint() {
+ return TRUE;
+ }
+
+ /**
+ * Returns the node in an array representation that can be used for serialization
+ *
+ * @return array
+ */
+ public function toArray() {
+ $arrayRepresentation = array(
+ 'serializeClassName' => get_class($this),
+ 'id' => $this->getId(),
+ 'type' => $this->getType(),
+ 'leaf' => $this->isLeafNode(),
+ 'label' => $this->getText(),
+ 'text' => $this->getPrefix() . $this->getText(),
+ 'cls' => $this->getCls(),
+ 'prefix' => $this->getPrefix(),
+ 'qtip' => $this->getQTip(),
+ 'expanded' => $this->isExpanded(),
+ 'spriteIconCode' => $this->getSpriteIconCode(),
+ 't3TextSourceField' => $this->getTextSourceField(),
+ 't3CallbackAction' => $this->getCallbackAction(),
+ 't3InCopyMode' => $this->isInCopyMode(),
+ 't3InCutMode' => $this->isInCutMode(),
+ 't3ContextInfo' => $this->getContextInfo(),
+ 'editable' => $this->isLabelEditable(),
+ );
+ $arrayRepresentation['nodeData'] = $arrayRepresentation;
+
+ $arrayRepresentation['children'] = '';
+ if ($this->hasChildNodes()) {
+ $arrayRepresentation['children'] = $this->childNodes->toArray();
+ }
+
+ return $arrayRepresentation;
+ }
+
+ /**
+ * Sets data of the node by a given data array
+ *
+ * @param array $data
+ * @return void
+ */
+ public function dataFromArray($data) {
+ parent::dataFromArray($data);
+
+ $this->setType($data['type']);
+ $this->setLeaf($data['leaf']);
+ $this->setText($data['label'], $data['t3TextSourceField'], $data['prefix']);
+ $this->setCls($data['cls']);
+ $this->setQTip($data['qtip']);
+ $this->setExpanded($data['expanded']);
+ $this->setCallbackAction($data['t3CallbackAction']);
+ $this->setSpriteIconCode($data['spriteIconCode']);
+ $this->setInCopyMode($data['t3InCopyMode']);
+ $this->setInCutMode($data['t3InCutMode']);
+ $this->setContextInfo($data['t3ContextInfo']);
+ $this->setEditableLable($data['editable']);
+ }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_node.php']) {
+ include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_node.php']);
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***************************************************************
+* Copyright notice
+*
+* (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+* 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.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* 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!
+***************************************************************/
+
+/**
+ * Tree Node Collection
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class tx_pagetree_NodeCollection extends t3lib_tree_NodeCollection {
+ /**
+ * Returns the collection in an array representation for e.g. serialization
+ *
+ * @return array
+ */
+ public function toArray() {
+ $arrayRepresentation = parent::toArray();
+ unset($arrayRepresentation['serializeClassName']);
+ return $arrayRepresentation;
+ }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_nodecollection.php']) {
+ include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_nodecollection.php']);
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***************************************************************
+* Copyright notice
+*
+* (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+* 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.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* 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!
+***************************************************************/
+
+/**
+ * Abstract State Provider
+ *
+ * @TODO Needs to be implemented
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+class tx_pagetree_StateProvider {
+ /**
+ * Sets the current tree state
+ * @return void
+ */
+ public function setState() {
+
+ }
+
+ /**
+ * Returns the last tree state
+ * @return string
+ */
+ public function getState() {
+ return '';
+ }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_stateprovider.php']) {
+ include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_stateprovider.php']);
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+ * 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.
+ * A copy is found in the textfile GPL.txt and important notices to the license
+ * from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ * 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!
+ ***************************************************************/
+
+/**
+ * Context Menu Action for the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class tx_pagetree_ContextMenu_Action extends t3lib_contextmenu_Action {
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_contextmenu_action.php']) {
+ include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_contextmenu_action.php']);
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+ * 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.
+ * A copy is found in the textfile GPL.txt and important notices to the license
+ * from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ * 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!
+ ***************************************************************/
+
+/**
+ * Context Menu Data Provider for the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class tx_pagetree_ContextMenu_DataProvider extends t3lib_contextmenu_AbstractDataProvider {
+ /**
+ * Old Context Menu Options (access mapping)
+ *
+ * @var array
+ */
+ protected $contextMenuMapping = array(
+ // @todo should be used (compatibility)
+ 'view' => 'canBeViewed',
+ 'edit' => 'canBeEdited',
+ 'new' => 'canCreateNewPages',
+ 'info' => 'canShowInfo',
+ 'copy' => 'canBeCopied',
+ 'cut' => 'canBeCut',
+ 'paste' => 'canBePasted',
+ 'move_wizard' => 'canBeMoved',
+ 'new_wizard' => 'dsfdsfdsf',
+ 'mount_as_treeroot' => 'canBeTemporaryMountPoint',
+ 'hide' => 'canBeDisabled',
+ 'delete' => 'canBeRemoved',
+ 'history' => 'canShowHistory',
+ );
+
+ /**
+ * Returns the actions for the node
+ *
+ * @param tx_pagetree_Node $node
+ * @return t3lib_contextmenu_ActionCollection
+ */
+ public function getActionsForNode(t3lib_tree_Node $node) {
+ $contextMenuActions = $this->getNextContextMenuLevel($this->getConfiguration(), $node);
+
+ return $contextMenuActions;
+ }
+
+ /**
+ * Evaluates a given display condition and returns true if the condition matches
+ *
+ * Examples:
+ * getContextInfo|inCutMode:1 || isInCopyMode:1
+ * isLeafNode:1
+ * isLeafNode:1 && isInCutMode:1
+ *
+ * @param tx_pagetree_Node $node
+ * @param string $displayCondition
+ * @return boolean
+ */
+ protected function evaluateDisplayCondition(tx_pagetree_Node $node, $displayCondition) {
+ if ($displayCondition === '') {
+ return TRUE;
+ }
+
+ // parse condition string
+ $conditions = array();
+ preg_match_all('/(.+?)(>=|<=|!=|=|>|<)(.+?)(\|\||&&|$)/is', $displayCondition, $conditions);
+
+ $lastResult = FALSE;
+ $chainType = '';
+ $amountOfConditions = count($conditions[0]);
+ for ($i = 0; $i < $amountOfConditions; ++$i) {
+ // check method for existence
+ $method = trim($conditions[1][$i]);
+ list($method, $index) = explode('|', $method);
+ if (!method_exists($node, $method)) {
+ continue;
+ }
+
+ // fetch compare value
+ $returnValue = call_user_func(array($node, $method));
+ if (is_array($returnValue)) {
+ $returnValue = $returnValue[$index];
+ }
+
+ // compare fetched and expected values
+ $operator = trim($conditions[2][$i]);
+ $expected = trim($conditions[3][$i]);
+ if ($operator === '=') {
+ $returnValue = ($returnValue == $expected);
+ } elseif ($operator === '>') {
+ $returnValue = ($returnValue > $expected);
+ } elseif ($operator === '<') {
+ $returnValue = ($returnValue < $expected);
+ } elseif ($operator === '>=') {
+ $returnValue = ($returnValue >= $expected);
+ } elseif ($operator === '<=') {
+ $returnValue = ($returnValue <= $expected);
+ } elseif ($operator === '!=') {
+ $returnValue = ($returnValue != $expected);
+ } else {
+ $returnValue = FALSE;
+ $lastResult = FALSE;
+ }
+
+ // chain last result and the current if requested
+ if ($chainType === '||') {
+ $lastResult = ($lastResult || $returnValue);
+ } elseif ($chainType === '&&') {
+ $lastResult = ($lastResult && $returnValue);
+ } else {
+ $lastResult = $returnValue;
+ }
+
+ // save chain type for the next condition
+ $chainType = trim($conditions[4][$i]);
+ }
+
+ return $lastResult;
+ }
+
+ /**
+ * Returns the next context menu level
+ *
+ * @param array $actions
+ * @param tx_pagetree_Node $node
+ * @param int $level
+ * @return t3lib_contextmenu_ActionCollection
+ */
+ protected function getNextContextMenuLevel(array $actions, tx_pagetree_Node $node, $level = 0) {
+ /** @var $actionCollection t3lib_contextmenu_ActionCollection */
+ $actionCollection = t3lib_div::makeInstance('t3lib_contextmenu_ActionCollection');
+
+ if ($level > 5) {
+ return $actionCollection;
+ }
+
+ $type = '';
+ foreach ($actions as $index => $actionConfiguration) {
+ if (substr($index, -1) !== '.') {
+ $type = $actionConfiguration;
+ if ($type !== 'DIVIDER') {
+ continue;
+ }
+ }
+
+ if (!in_array($type, array('DIVIDER', 'SUBMENU', 'ITEM'))) {
+ continue;
+ }
+
+ /** @var $action tx_pagetree_ContextMenu_Action */
+ $action = t3lib_div::makeInstance('tx_pagetree_ContextMenu_Action');
+ $action->setId($index);
+
+ if ($type === 'DIVIDER') {
+ $action->setType('divider');
+ } else {
+ if (isset($actionConfiguration['displayCondition'])
+ && trim($actionConfiguration['displayCondition']) !== ''
+ && !$this->evaluateDisplayCondition($node, $actionConfiguration['displayCondition'])
+ ) {
+ unset($action);
+ continue;
+ }
+
+ if ($type === 'SUBMENU') {
+ $label = $GLOBALS['LANG']->sL($actionConfiguration['label'], TRUE);
+ $action->setType('submenu');
+ $action->setChildActions(
+ $this->getNextContextMenuLevel($actionConfiguration, $node, ++$level)
+ );
+ } else {
+ $label = $GLOBALS['LANG']->sL($actionConfiguration['label'], TRUE);
+ $action->setType('action');
+ $action->setCallbackAction($actionConfiguration['callbackAction']);
+ }
+
+ $action->setLabel($label);
+ if (isset($actionConfiguration['icon']) && trim($actionConfiguration['icon']) !== '') {
+ $action->setIcon($actionConfiguration['icon']);
+ } elseif (isset($actionConfiguration['spriteIcon'])) {
+ $action->setClass(
+ t3lib_iconWorks::getSpriteIconClasses($actionConfiguration['spriteIcon'])
+ );
+ }
+ }
+
+ $actionCollection->append($action);
+ }
+
+ return $actionCollection;
+ }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_contextmenu_dataprovider.php']) {
+ include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/class.tx_pagetree_contextmenu_dataprovider.php']);
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***************************************************************
+* Copyright notice
+*
+* (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+* 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.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* 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!
+***************************************************************/
+
+/**
+ * Commands for the Page tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+class tx_pagetree_ExtDirect_Commands {
+ /**
+ * Visibly the page
+ *
+ * @param stdClass $nodeData
+ * @return array
+ */
+ public function visiblyNode($nodeData) {
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+ try {
+ tx_pagetree_Commands::visiblyNode($node);
+ $newNode = tx_pagetree_Commands::getNode($node->getId());
+ $newNode->setLeaf($node->isLeafNode());
+ $returnValue = $newNode->toArray();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'error' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Hide the page
+ *
+ * @param stdClass $nodeData
+ * @return array
+ */
+ public function disableNode($nodeData) {
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+ try {
+ tx_pagetree_Commands::disableNode($node);
+ $newNode = tx_pagetree_Commands::getNode($node->getId());
+ $newNode->setLeaf($node->isLeafNode());
+ $returnValue = $newNode->toArray();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'message' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Delete the page
+ *
+ * @param stdClass $nodeData
+ * @return array
+ */
+ public function deleteNode($nodeData) {
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+ try {
+ tx_pagetree_Commands::deleteNode($node);
+ $returnValue = array();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'message' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+
+ }
+
+ /**
+ * Restore the page
+ *
+ * @param stdClass $nodeData
+ * @return array
+ */
+ public function restoreNode($nodeData) {
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+ try {
+ tx_pagetree_Commands::restoreNode($node);
+ $newNode = tx_pagetree_Commands::getNode($node->getId());
+ $returnValue = $newNode->toArray();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'message' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Updates the given field with a new text value, may be used to inline update
+ * the title field in the new page tree
+ *
+ * @param stdClass $nodeData
+ * @param string $updatedLabel
+ * @return array
+ */
+ public function updateLabel($nodeData, $updatedLabel) {
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+ try {
+ tx_pagetree_Commands::updateNodeLabel($node, $updatedLabel);
+ $returnValue = array();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'message' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Moves the source node directly as the first child of the destination node
+ *
+ * @param stdClass $nodeData
+ * @param int $destination
+ * @return array
+ */
+ public function moveNodeToFirstChildOfDestination($nodeData, $destination) {
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+ try {
+ tx_pagetree_Commands::moveNode($node, $destination);
+ $returnValue = array();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'message' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Moves the source node directly after the destination node
+ *
+ * @param stdClass $nodeData
+ * @param int $destination
+ * @return void
+ */
+ public function moveNodeAfterDestination($nodeData, $destination) {
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+ try {
+ tx_pagetree_Commands::moveNode($node, -$destination);
+ $returnValue = array();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'message' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Copies the source node directly as the first child of the destination node and
+ * returns the created node.
+ *
+ * @param stdClass $nodeData
+ * @param int $destination
+ * @return array
+ */
+ public function copyNodeToFirstChildOfDestination($nodeData, $destination) {
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+ try {
+ $newPageId = tx_pagetree_Commands::copyNode($node, $destination);
+ $returnValue = tx_pagetree_Commands::getNode($newPageId)->toArray();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'message' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Copies the source node directly after the destination node and returns the
+ * created node.
+ *
+ * @param stdClass $nodeData
+ * @param int $destination
+ * @return array
+ */
+ public function copyNodeAfterDestination($nodeData, $destination) {
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+ try {
+ $newPageId = tx_pagetree_Commands::copyNode($node, -$destination);
+ $returnValue = tx_pagetree_Commands::getNode($newPageId)->toArray();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'message' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Inserts a new node as the first child node of the destination node and returns the created node.
+ *
+ * @param stdClass $parentNodeData
+ * @param int $pageType
+ * @return array
+ */
+ public function insertNodeToFirstChildOfDestination($parentNodeData, $pageType) {
+ /** @var $parentNode tx_pagetree_Node */
+ $parentNode = t3lib_div::makeInstance('tx_pagetree_Node', (array) $parentNodeData);
+
+ try {
+ $newPageId = tx_pagetree_Commands::createNode($parentNode, $parentNode->getId(), $pageType);
+ $returnValue = tx_pagetree_Commands::getNode($newPageId)->toArray();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'message' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Inserts a new node directly after the destination node and returns the created node.
+ *
+ * @param stdClass $parentNodeData
+ * @param int $destination
+ * @param int $pageType
+ * @return array
+ */
+ public function insertNodeAfterDestination($parentNodeData, $destination, $pageType) {
+ /** @var $parentNode tx_pagetree_Node */
+ $parentNode = t3lib_div::makeInstance('tx_pagetree_Node', (array) $parentNodeData);
+
+ try {
+ $newPageId = tx_pagetree_Commands::createNode($parentNode, -$destination, $pageType);
+ $returnValue = tx_pagetree_Commands::getNode($newPageId)->toArray();
+ } catch (Exception $exception) {
+ $returnValue = array(
+ 'success' => FALSE,
+ 'message' => $exception->getMessage(),
+ );
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * Returns the view link of a given node
+ *
+ * @param stdClass $nodeData
+ * @param string $workspacePreview
+ * @return string
+ */
+ public static function getViewLink($nodeData, $workspacePreview) {
+ // @TODO use the hook to get the needed information's
+
+
+// $viewScriptPreviewEnabled = '/' . TYPO3_mainDir . 'mod/user/ws/wsol_preview.php?id=';
+// $viewScriptPreviewDisabled = '/index.php?id=';
+//
+// // check alternate Domains
+// $rootLine = t3lib_BEfunc::BEgetRootLine($id);
+// if ($rootLine) {
+// $parts = parse_url(t3lib_div::getIndpEnv('TYPO3_SITE_URL'));
+// if (t3lib_BEfunc::getDomainStartPage($parts['host'], $parts['path'])) {
+// $preUrl_temp = t3lib_BEfunc::firstDomainRecord($rootLine);
+// }
+// }
+// $preUrl = ($preUrl_temp ? (t3lib_div::getIndpEnv('TYPO3_SSL') ?
+// 'https://' : 'http://') . $preUrl_temp : '' . '..');
+//
+// // Look if a fixed preview language should be added:
+// $viewLanguageOrder = $GLOBALS['BE_USER']->getTSConfigVal('options.view.languageOrder');
+// if (strlen($viewLanguageOrder)) {
+// $suffix = '';
+//
+// // Find allowed languages (if none, all are allowed!)
+// if (!$GLOBALS['BE_USER']->user['admin'] &&
+// strlen($GLOBALS['BE_USER']->groupData['allowed_languages'])) {
+// $allowed_languages = array_flip(explode(',', $GLOBALS['BE_USER']->groupData['allowed_languages']));
+// }
+//
+// // Traverse the view order, match first occurrence
+// $lOrder = t3lib_div::intExplode(',',$viewLanguageOrder);
+// foreach($lOrder as $langUid) {
+// if (is_array($allowed_languages) && count($allowed_languages)) {
+// if (isset($allowed_languages[$langUid])) { // Choose if set.
+// $suffix = '&L='.$langUid;
+// break;
+// }
+// } else { // All allowed since no lang. are listed.
+// $suffix = '&L='.$langUid;
+// break;
+// }
+// }
+//
+// // Add it:
+// $addGetVars.= $suffix;
+// }
+//
+// $urlPreviewEnabled = $preUrl . $viewScriptPreviewEnabled . $id . $addGetVars;
+// $urlPreviewDisabled = $preUrl . $viewScriptPreviewDisabled . $id . $addGetVars;
+//
+// if ($workspacePreview) {
+// return $urlPreviewEnabled;
+// } else {
+// return $urlPreviewDisabled;
+// }
+
+// $javascriptLink = t3lib_BEfunc::viewOnClick($id);
+// debug($javascriptLink);
+
+ return 'http://linux-schmie.de/wp-content/uploads/2010/07/Baustelle.png';
+ }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_commands.php']) {
+ include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_commands.php']);
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+ * 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.
+ * A copy is found in the textfile GPL.txt and important notices to the license
+ * from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ * 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!
+ ***************************************************************/
+
+/**
+ * Context Menu of the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class tx_pagetree_ExtDirect_ContextMenu extends t3lib_contextmenu_extdirect_ContextMenu {
+ /**
+ * Sets the data provider
+ *
+ * @return void
+ */
+ protected function initDataProvider() {
+ /** @var $dataProvider tx_pagetree_ContextMenu_DataProvider */
+ $dataProvider = t3lib_div::makeInstance('tx_pagetree_ContextMenu_DataProvider');
+ $dataProvider->setContextMenuType('table.pages');
+ $this->setDataProvider($dataProvider);
+ }
+
+ /**
+ * Returns the actions for the given node information's
+ *
+ * @param stdClass $node
+ * @return array
+ */
+ public function getActionsForNodeArray($nodeData) {
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+ $node->setRecord(tx_pagetree_Commands::getNodeRecord($node->getId()));
+
+ $this->initDataProvider();
+ $actionCollection = $this->dataProvider->getActionsForNode($node);
+
+ return $actionCollection->toArray();
+ }
+}
+
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php']) {
+ include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php']);
+}
+
+?>
\ No newline at end of file
--- /dev/null
+<?php
+/***************************************************************
+* Copyright notice
+*
+* (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+* 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.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* 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!
+***************************************************************/
+
+/**
+ * Data Provider of the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage tx_pagetree
+ */
+class tx_pagetree_ExtDirect_Tree extends t3lib_tree_ExtDirect_AbstractExtJsTree {
+ /**
+ * Sets the data provider
+ *
+ * @return void
+ */
+ protected function initDataProvider() {
+ /** @var $dataProvider tx_pagetree_DataProvider */
+ $dataProvider = t3lib_div::makeInstance('tx_pagetree_DataProvider');
+ $this->setDataProvider($dataProvider);
+ }
+
+ /**
+ * Data Provider
+ *
+ * @return tx_pagetree_DataProvider
+ */
+ protected $dataProvider = NULL;
+
+ /**
+ * Returns the root node of the tree
+ *
+ * Not used for the page tree, because the multiple domains/roots feature
+ *
+ * @return array
+ */
+ public function getRoot() {
+ return array();
+ }
+
+ /**
+ * Fetches the next tree level
+ *
+ * @param int $nodeId
+ * @param stdClass $nodeData
+ * @return array
+ */
+ public function getNextTreeLevel($nodeId, $nodeData) {
+ $this->initDataProvider();
+
+ /** @var $node tx_pagetree_Node */
+ $node = t3lib_div::makeInstance('tx_pagetree_Node', (array) $nodeData);
+
+ if ($nodeId === 'root') {
+ $nodeCollection = $this->dataProvider->getTreeMounts();
+ } else {
+ $nodeCollection = $this->dataProvider->getNodes($node);
+ }
+
+ return $nodeCollection->toArray();
+ }
+
+ /**
+ * Returns a tree that only contains elements that match the given search string
+ *
+ * @param string $searchFilter
+ * @return array
+ */
+ public function getFilteredTree($searchFilter) {
+ $this->initDataProvider();
+
+ $nodeCollection = $this->dataProvider->getFilteredNodes($searchFilter);
+
+ return $nodeCollection->toArray();
+ }
+
+ /**
+ * Returns the localized list of doktypes to display
+ *
+ * Note: The list can be filtered by the user typoscript
+ * option "options.pageTree.doktypesToShowInNewPageDragArea".
+ *
+ * @return array
+ */
+ public function getNodeTypes() {
+ $doktypes = t3lib_div::trimExplode(
+ ',', $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.doktypesToShowInNewPageDragArea')
+ );
+
+ $output = array();
+ foreach ($doktypes as $doktype) {
+ $label = $GLOBALS['LANG']->sL('LLL:EXT:pagetree/locallang_pagetree.xml:page.doktype.' . $doktype, TRUE);
+ $spriteIcon = $this->getSpriteIconClasses($GLOBALS['TCA']['pages']['ctrl']['typeicon_classes'][$doktype]);
+
+ $output[] = array(
+ 'nodeType' => $doktype,
+ 'cls' => 'topPanel-button ' . $spriteIcon,
+ 'title' => $label,
+ 'tooltip' => $label,
+ );
+ }
+
+ return $output;
+ }
+
+ /**
+ * Returns the sprite icon classes for a given icon
+ *
+ * @param string $icon
+ * @return string
+ */
+ public function getSpriteIconClasses($icon) {
+ return t3lib_iconWorks::getSpriteIconClasses($icon);
+ }
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_tree.php']) {
+ include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/classes/extdirect/class.tx_pagetree_extdirect_tree.php']);
+}
+
+?>
\ No newline at end of file
--- /dev/null
+/******************************************************************
+ * @class Ext.ux.plugins.TreePanelStateful
+ * @extends Ext.util.Observable
+
+ * @constructor
+ * var treePanel = new Ext.ux.TreePanel({
+ ...add TreePanel options
+ plugins:new Ext.ux.plugins.TreePanelStateful()
+ });
+ *****************************************************************/
+Ext.namespace('Ext.ux.plugins');
+
+Ext.ux.plugins.TreePanelStateful = function(config) {
+ Ext.apply(this, config);
+};
+
+Ext.extend(Ext.ux.plugins.TreePanelStateful, Ext.util.Observable, {
+ treePanel: null,
+ init: function(treePanel) {
+ this.treePanel = treePanel;
+ Ext.apply(treePanel, {
+ // internal variables
+ taskId: '',
+ ignoreCookie: false,
+ startQueryClicked: false,
+ nodeAttrs: {},
+ oldParentNodeAttrs: {},
+ newParentNodeAttrs: {},
+
+ //CookieProvider - hold state of TreePanel
+ cp: null,
+
+ //TreePanel state - simple array
+ state: null,
+
+ //stateful option set to true
+ stateful: true,
+
+ //Last selected node
+ lastSelectedNode: null,
+
+ //Function which saves TreePanel state
+ saveState : function(newState) {
+ this.state = newState;
+ this.cp.set('TreePanelStateful_' + treePanel.taskId, this.state);
+ },
+
+ //Function which restores TreePanel state
+ restoreState : function(defaultPath) {
+ if (!treePanel.ignoreCookie) {
+ var stateToRestore = this.state;
+
+ if (this.state.length == 0) {
+ var newState = new Array(defaultPath);
+ this.saveState(newState);
+ this.expandPath(defaultPath);
+ return;
+ }
+
+ for (var i = 0; i < stateToRestore.length; ++i) {
+ // activate all path strings from the state
+ try {
+ var path = stateToRestore[i];
+ this.expandPath(path);
+ }
+ catch(e) {
+ // ignore invalid path, seems to be remove in the datamodel
+ // TODO fix state at this point
+ }
+ }
+ }
+ },
+
+ /***** Events which cause TreePanel to remember its state
+ * click, expandnode, collapsenode, load, textchange,
+ * remove, render
+ ********************************************************/
+ stateEvents: [{
+ click: {
+ fn: function(node) {
+ this.cp.set('LastSelectedNodePath_' + treePanel.taskId, node.getPath());
+ this.cp.set('LastSelectedNodeId_' + treePanel.taskId, node.id);
+ }
+ },
+ expandnode: {
+ fn: function(node) {
+ var currentPath = node.getPath();
+ var newState = new Array();
+
+ for (var i = 0; i < this.state.length; ++i) {
+ var path = this.state[i];
+
+ if (currentPath.indexOf(path) == -1) {
+ // this path does not already exist
+ newState.push(path);
+ }
+ }
+
+ // now ad the new path
+ newState.push(currentPath);
+ this.saveState(newState);
+ }
+ },
+ collapsenode: {
+ fn: function(node) {
+ var parentNode;
+ if (node.id == this.root.id) {
+ return;
+ }
+
+ var closedPath = node.getPath();
+ var newState = new Array();
+
+ for (var i = 0; i < this.state.length; ++i) {
+ var path = this.state[i];
+ if (path.indexOf(closedPath) == -1) {
+ // this path is not a subpath of the closed path
+ newState.push(path);
+ }
+ else {
+ if (path == closedPath) {
+ parentNode = node.parentNode;
+
+ if (parentNode.id != this.root.id) {
+ newState.push(parentNode.getPath());
+ }
+ }
+ }
+ }
+
+ if (newState.length == 0) {
+ parentNode = node.parentNode;
+ newState.push((parentNode == null ? this.pathSeparator : parentNode.getPath()));
+ }
+
+ this.saveState(newState);
+ }
+ },
+ load: {
+ fn: function(node) {
+ var lastSelectedNodePath = this.cp.get('LastSelectedNodePath_' + treePanel.taskId);
+ var lastSelectedNodeId = this.cp.get('LastSelectedNodeId_' + treePanel.taskId);
+
+ var rootNode = this.getRootNode();
+ if (node.id == rootNode.id == lastSelectedNodeId) {
+ this.selectPath(lastSelectedNodePath);
+ node.fireEvent('click', node);
+ return;
+ }
+
+ if (node.id == lastSelectedNodeId) {
+ node.fireEvent('click', node);
+ } else {
+ var childNode = node.findChild('id', lastSelectedNodeId);
+
+ if (childNode && childNode.isLeaf()) {
+ childNode.ensureVisible();
+ this.selectPath(lastSelectedNodePath);
+ childNode.fireEvent('click', childNode);
+ }
+ else if (childNode && !childNode.isLeaf()) {
+ this.selectPath(lastSelectedNodePath);
+ childNode.fireEvent('click', childNode);
+ }
+ }
+ }
+ },
+ textchange: {
+ fn: function(node, text, oldText) {
+ var lastSelectedNodePath = this.cp.get('LastSelectedNodePath_' + treePanel.taskId);
+ if (lastSelectedNodePath) {
+ return;
+ }
+
+ var newSelectedNodePath = lastSelectedNodePath.replace(oldText, text);
+
+ this.cp.set('LastSelectedNodePath_' + treePanel.taskId, newSelectedNodePath);
+
+ this.expandPath(node.getPath());
+ this.selectPath(node.getPath());
+ }
+ },
+ remove: {
+ fn: function(tree, parentNode, node) {
+ var lastSelectedNodeId = this.cp.get('LastSelectedNodeId_' + treePanel.taskId);
+ if (!tree.movingNode) {
+ if (node.id == lastSelectedNodeId) {
+ this.cp.set('LastSelectedNodePath_' + treePanel.taskId, parentNode.getPath());
+ this.cp.set('LastSelectedNodeId_' + treePanel.taskId, parentNode.id);
+ }
+
+ this.cp.set('DeletedNodeParent_' + treePanel.taskId + '_' + node.id, parentNode.id);
+ this.cp.set('DeletedNode_' + treePanel.taskId + '_' + node.id, node.id);
+
+ if (tree.deleteWithChildren)
+ this.cp.set('DeletedNodeWithChildren_' + treePanel.taskId + '_' + node.id, "true");
+
+ tree.deleteWithChildren = false;
+ }
+ }
+ },
+ movenode: {
+ fn: function(tree, node, oldParent, newParent) {
+ var lastSelectedNodeId = this.cp.get('LastSelectedNodeId_' + treePanel.taskId);
+ if (node.id == lastSelectedNodeId) {
+ this.cp.set('LastSelectedNodePath_' + treePanel.taskId, newParent.getPath());
+ this.cp.set('LastSelectedNodeId_' + treePanel.taskId, newParent.id);
+ }
+
+ this.cp.set('MovedNodeOldParent_' + treePanel.taskId + '_' + node.id, oldParent.id);
+ this.cp.set('MovedNodeNewParent_' + treePanel.taskId + '_' + node.id, newParent.id);
+ this.cp.set('MovedNode_' + treePanel.taskId + '_' + node.id, node.id);
+ }
+ }
+ }]
+ });
+
+ if (!treePanel.stateful) {
+ treePanel.stateful = true;
+ }
+
+ if (!treePanel.cp) {
+ treePanel.cp = new Ext.state.CookieProvider({expires: null});
+ }
+
+ if (!treePanel.lastSelectedNode) {
+ var cookieLastSelectedNode = treePanel.cp.get('LastSelectedNodeId_' + treePanel.taskId);
+
+ if (!cookieLastSelectedNode) {
+ treePanel.lastSelectedNode = treePanel.root;
+ }
+ else {
+ treePanel.lastSelectedNode = cookieLastSelectedNode;
+ }
+ }
+
+ if (!treePanel.state) {
+ var cookieState = treePanel.cp.get('TreePanelStateful_' + treePanel.taskId);
+
+ if (!cookieState) {
+ treePanel.state = new Array();
+ }
+ else {
+ treePanel.state = cookieState;
+ }
+ }
+
+ treePanel.restoreState(treePanel.root.getPath());
+ },
+ updateState: function(treePanel, parentNode, node) {
+ if (!treePanel.ignoreCookie && !treePanel.startQueryClicked) {
+ /*
+ * Check for deleted nodes.
+ */
+ var deletedNode = treePanel.getNodeById(treePanel.cp.get('DeletedNode_' + this.treePanel.taskId + '_' + node.id));
+
+ if (deletedNode != undefined) {
+ var deleteWithChildren = treePanel.cp.get('DeletedNodeWithChildren_' + this.treePanel.taskId + '_' + node.id);
+
+ if (deleteWithChildren === "true")
+ treePanel.deleteWithChildren = true;
+
+ deletedNode.remove();
+
+ if (!parentNode.hasChildNodes())
+ parentNode.expand();
+ }
+ else {
+ /*
+ * Check for moved nodes.
+ */
+ treePanel.movingNode = true;
+
+ var movedNode = treePanel.getNodeById(treePanel.cp.get('MovedNode_' + treePanel.taskId + '_' + node.id));
+
+ if (movedNode != undefined) {
+ var oldParentNode = treePanel.getNodeById(treePanel.cp.get('MovedNodeOldParent_' + treePanel.taskId + '_' + node.id));
+ var newParentNode = treePanel.getNodeById(treePanel.cp.get('MovedNodeNewParent_' + treePanel.taskId + '_' + node.id));
+
+ if (oldParentNode != undefined && newParentNode != undefined) {
+ oldParentNode.removeChild(node);
+ newParentNode.appendChild(node);
+ newParentNode.lastChild = node;
+
+ if (treePanel.nodeAttrs.indexOf(node.attributes.id) === -1) {
+ treePanel.nodeAttrs.push(node.id);
+ treePanel.oldParentNodeAttrs.push(oldParentNode.id);
+ treePanel.newParentNodeAttrs.push(newParentNode.id);
+ }
+ else {
+ treePanel.nodeAttrs[treePanel.nodeAttrs.indexOf(node.attributes.id)] = node.id;
+ treePanel.oldParentNodeAttrs[treePanel.nodeAttrs.indexOf(node.attributes.id)] = oldParentNode.id;
+ treePanel.newParentNodeAttrs[treePanel.nodeAttrs.indexOf(node.attributes.id)] = newParentNode.id;
+ }
+ treePanel.gridModified = true;
+ }
+ }
+
+ treePanel.movingNode = false;
+ }
+ }
+ else {
+ treePanel.cp.clear('TreePanelStateful_' + treePanel.taskId);
+ treePanel.cp.clear('LastSelectedNodePath_' + treePanel.taskId);
+ treePanel.cp.clear('LastSelectedNodeId_' + treePanel.taskId);
+ treePanel.cp.clear('DeletedNodeParent_' + treePanel.taskId + '_' + node.id);
+ treePanel.cp.clear('DeletedNode_' + treePanel.taskId + '_' + node.id);
+ treePanel.cp.clear('DeletedNodeWithChildren_' + treePanel.taskId + '_' + node.id);
+ treePanel.cp.clear('MovedNodeOldParent_' + treePanel.taskId + '_' + node.id);
+ treePanel.cp.clear('MovedNodeNewParent_' + treePanel.taskId + '_' + node.id);
+ treePanel.cp.clear('MovedNode_' + treePanel.taskId + '_' + node.id);
+ }
+ }
+});
\ No newline at end of file
--- /dev/null
+Ext.namespace('TYPO3.Components.PageTree');
+
+TYPO3.Components.PageTree.Actions = {
+ evaluateResponse: function(response) {
+ if (response.success === false) {
+ TYPO3.Flashmessage.display(4, 'Exception', response.message);
+ return false;
+ }
+
+ return true;
+ },
+
+ removeNode: function(node) {
+ TYPO3.Components.PageTree.Commands.deleteNode(
+ node.attributes.nodeData,
+ function(response) {
+ if (this.evaluateResponse(response)) {
+ node.remove();
+ }
+ },
+ this
+ );
+ },
+
+ restoreNode: function(node) {
+ TYPO3.Components.PageTree.Commands.restoreNode(node.attributes.nodeData);
+ },
+
+ stub: function() {
+ alert('Just a Stub! Don\'t Panic!');
+ },
+
+ viewPage: function(node) {
+ TYPO3.Components.PageTree.Commands.getViewLink(
+ node.attributes.nodeData,
+ (TYPO3.configuration.workspaceFrontendPreviewEnabled && TYPO3.configuration.currentWorkspace != 0),
+ function(result) {
+ openUrlInWindow(result, 'typo3-contextMenu-view');
+ }
+ );
+ },
+
+ editPageProperties: function(node) {
+ TYPO3.Backend.ContentContainer.setUrl(
+ 'alt_doc.php?edit[pages][' + node.attributes.id + ']=edit'
+ );
+ },
+
+ newPageWizard: function(node) {
+ TYPO3.Backend.ContentContainer.setUrl(
+ 'db_new.php?id=' + node.attributes.id + '&pagesOnly=1'
+ );
+ },
+
+ openInfoPopUp: function(node) {
+ launchView('pages', node.attributes.id);
+ },
+
+ openHistoryPopUp: function(node) {
+ TYPO3.Backend.ContentContainer.setUrl(
+ 'show_rechis.php?element=pages:' + node.attributes.id
+ );
+ },
+
+ enableCutMode: function(node, pageTree) {
+ this.disableCopyMode(node, pageTree);
+ node.attributes.nodeData.t3InCutMode = true;
+ pageTree.tree.t3ContextInfo.inCutMode = true;
+ pageTree.tree.t3ContextNode = node;
+ },
+
+ disableCutMode: function(node, pageTree) {
+ this.releaseCutAndCopyModes(pageTree);
+ node.attributes.nodeData.t3InCutMode = false;
+ },
+
+ enableCopyMode: function(node, pageTree) {
+ this.disableCutMode(node, pageTree);
+ node.attributes.nodeData.t3InCopyMode = true;
+ pageTree.tree.t3ContextInfo.inCopyMode = true;
+ pageTree.tree.t3ContextNode = node;
+ },
+
+ disableCopyMode: function(node, pageTree) {
+ this.releaseCutAndCopyModes(pageTree);
+ node.attributes.nodeData.t3InCopyMode = false;
+ },
+
+ pasteIntoNode: function(node, pageTree) {
+ this.releaseCutAndCopyModes(pageTree);
+ this.stub();
+ },
+
+ pasteAfterNode: function(node, pageTree) {
+ this.releaseCutAndCopyModes(pageTree);
+ this.stub();
+ },
+
+ releaseCutAndCopyModes: function(pageTree) {
+ pageTree.tree.t3ContextInfo.inCutMode = false;
+ pageTree.tree.t3ContextInfo.inCopyMode = false;
+
+ if (pageTree.tree.t3ContextNode) {
+ pageTree.tree.t3ContextNode.attributes.nodeData.t3InCutMode = false;
+ pageTree.tree.t3ContextNode.attributes.nodeData.t3InCopyMode = false;
+ pageTree.tree.t3ContextNode = null;
+ }
+ },
+
+ moveNodeToFirstChildOfDestination: function(node, newParent) {
+ TYPO3.Components.PageTree.Commands.moveNodeToFirstChildOfDestination(
+ node.attributes.nodeData,
+ newParent
+ );
+ },
+
+ moveNodeAfterDestination: function(node, newParent) {
+ TYPO3.Components.PageTree.Commands.moveNodeAfterDestination(
+ node.attributes.nodeData,
+ newParent
+ );
+ },
+
+ insertNodeAfterDestination: function(node, callback) {
+ TYPO3.Components.PageTree.Commands.insertNodeAfterDestination(
+ node.parentNode.attributes.nodeData,
+ node.previousSibling.id,
+ node.serverNodeType,
+ callback.createDelegate(node)
+ );
+ },
+
+ insertNodeToFirstChildOfDestination: function(node, callback) {
+ TYPO3.Components.PageTree.Commands.insertNodeToFirstChildOfDestination(
+ node.parentNode.attributes.nodeData,
+ node.serverNodeType,
+ callback.createDelegate(node)
+ );
+ },
+
+ copyNodeToFirstChildOfDestination: function(node, callback) {
+ TYPO3.Components.PageTree.Commands.copyNodeToFirstChildOfDestination(
+ node.attributes.nodeData,
+ node.parentNode.id,
+ callback.createDelegate(node)
+ );
+ },
+
+ copyNodeAfterDestination: function(node, callback) {
+ TYPO3.Components.PageTree.Commands.copyNodeAfterDestination(
+ node.attributes.nodeData,
+ node.previousSibling.id,
+ callback.createDelegate(node)
+ );
+ },
+
+ enablePage: function(node) {
+ TYPO3.Components.PageTree.Commands.visiblyNode(
+ node.attributes.nodeData,
+ function(response) {
+ if (this.evaluateResponse(response)) {
+ this.updateNode(node, response);
+ }
+ },
+ this
+ );
+ },
+
+ disablePage: function(node) {
+ TYPO3.Components.PageTree.Commands.disableNode(
+ node.attributes.nodeData,
+ function(response) {
+ if (this.evaluateResponse(response)) {
+ this.updateNode(node, response);
+ }
+ },
+ this
+ );
+ },
+
+ updateNode: function(node, updatedNode) {
+ updatedNode.uiProvider = TYPO3.Components.PageTree.PageTreeUI;
+ var newTreeNode = new Ext.tree.TreeNode(updatedNode);
+ node.parentNode.replaceChild(newTreeNode, node);
+ newTreeNode.getOwnerTree().refreshNode(newTreeNode);
+ },
+
+ singleClick: function(node) {
+ TYPO3.Backend.ContentContainer.setUrl(
+ TS.PATH_typo3 + currentSubScript + '?id=' + node.attributes.id
+ );
+ },
+
+ saveTitle: function(node, newText, oldText) {
+ if (newText === oldText) {
+ return;
+ }
+
+ TYPO3.Components.PageTree.Commands.updateLabel(
+ node.editNode.attributes.nodeData,
+ newText,
+ this.evaluateResponse
+ );
+ }
+};
\ No newline at end of file
Ext.namespace('TYPO3.Components.PageTree');
TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
- dataRecord: null,
+ node: null,
+ pageTree: null,
id: 'typo3-pagetree-contextmenu',
+
listeners: {
itemclick: {
- scope: this,
fn: function (item) {
- if (item.callbackAction != undefined) {
- eval(item.callbackAction + '(item.parentMenu.dataRecord, item.attributes)');
- }
+ this.pageTree.commandProvider[item.callbackAction](
+ item.parentMenu.node,
+ item.parentMenu.pageTree
+ );
}
}
},
-
/**
- * Fill menu with menu items.
- *
- * @param dataRecord
- * The data record to bind to the menu.
- * MUST contain "attributes.actions" as an array defining the allowed actions for the current item.
+ * Fill menu with menu items and returns the number of context menu items
*
+ * @param node
+ * @param pageTree
* @param contextMenuConfiguration
- * Context menu configuration. See Ext.MenuItem for properties.
- * Additionally, the following two properties have to exist:
- * - callback: Callback method to be called when the click happens. Gets two parameters: the dataRecord, and item.attributes.
- * - action: The name of the action
- *
- * @return the number of menu items in the first level.
+ * @return int
*/
- fillWithMenuItems: function(dataRecord, contextMenuConfiguration) {
- this.dataRecord = dataRecord;
- this.dataRecord.attributes.actions = Ext.toArray(this.dataRecord.attributes.actions);
- //
+ fillWithMenuItems: function(node, pageTree, contextMenuConfiguration) {
+ this.node = node;
+ this.pageTree = pageTree;
+
var components = this.preProcessContextMenuConfiguration(contextMenuConfiguration);
if (components.length) {
for (var component in components) {
- if (components[component] == '-') {
+ if (components[component] === '-') {
this.addSeparator();
} else {
- if (typeof components[component] == 'object') {
+ if (typeof components[component] === 'object') {
this.addItem(components[component]);
}
}
var modulesInsideGroup = false;
var subMenus = 0;
for (var singleAction in contextMenuConfiguration) {
- if (singleAction.indexOf('--submenu') != -1) {
+ if (contextMenuConfiguration[singleAction]['type'] === 'submenu') {
var subMenuComponents = this.preProcessContextMenuConfiguration(
- contextMenuConfiguration[singleAction],
- level + 1
- );
+ contextMenuConfiguration[singleAction]['childActions'],
+ level + 1
+ );
if (subMenuComponents.length) {
var subMenu = new TYPO3.Components.PageTree.ContextMenu({
id: this.id + '-sub' + ++subMenus,
items: subMenuComponents,
- dataRecord: this.dataRecord
+ node: this.node,
+ pageTree: this.pageTree
});
components[index++] = {
- text: contextMenuConfiguration[singleAction]['text'],
+ text: contextMenuConfiguration[singleAction]['label'],
cls: 'contextMenu-subMenu',
menu: subMenu
};
}
+ } else if (contextMenuConfiguration[singleAction]['type'] === 'divider') {
+ if (modulesInsideGroup) {
+ components[index++] = '-';
+ modulesInsideGroup = false;
+ }
} else {
- if (singleAction.indexOf('--divider') != -1) {
- if (modulesInsideGroup) {
- components[index++] = '-';
- modulesInsideGroup = false;
- }
- } else {
- modulesInsideGroup = true;
+ modulesInsideGroup = true;
+
+ if (typeof contextMenuConfiguration[singleAction] === 'object') {
+ var component = {
+ 'text': contextMenuConfiguration[singleAction]['label'],
+ 'icon': contextMenuConfiguration[singleAction]['icon'],
+ 'iconCls': contextMenuConfiguration[singleAction]['class'],
+ 'callbackAction': contextMenuConfiguration[singleAction]['callbackAction']
+ };
- if (typeof contextMenuConfiguration[singleAction] == 'object') {
- var component = contextMenuConfiguration[singleAction];
- component.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
- '<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}">',
- '<span class="{hrefTarget}">',
+ component.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
+ '<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}">',
+ '<span class="{hrefTarget}">',
'<img src="{icon}" class="x-menu-item-icon {iconCls}" unselectable="on" />',
- '</span>',
- '<span class="x-menu-item-text">{text}</span>',
- '</a>'
- );
+ '</span>',
+ '<span class="x-menu-item-text">{text}</span>',
+ '</a>'
+ );
- components[index++] = component;
- }
+ components[index++] = component;
}
}
}
+ // remove divider if it's the last item of the context menu
+ if (components.last() === '-') {
+ components[components.length - 1] = '';
+ }
+
return components;
}
});
+++ /dev/null
-Ext.namespace('TYPO3.Components.PageTree');
-
-TYPO3.Components.PageTree.ContextMenuActions = {
- removeNode: function(node) {
- if (node.parentNode) {
- node.remove();
- }
- },
-
- stub: function() {
- alert('Just a Stub! Don\'t Panic!');
- },
-
- viewPage: function(node) {
- TYPO3.Components.PageTree.DataProvider.getViewLink(
- node.id,
- (TYPO3.configuration.workspaceFrontendPreviewEnabled && TYPO3.configuration.currentWorkspace != 0),
- function(result) {
- openUrlInWindow(result, 'typo3-contextMenu-view');
- }
- );
- },
-
- editPageProperties: function(node) {
- TYPO3.Backend.ContentContainer.setUrl(
- 'alt_doc.php?edit[pages][' + node.attributes.properties.realId + ']=edit'
- );
- },
-
- newPageWizard: function(node) {
- TYPO3.Backend.ContentContainer.setUrl(
- 'db_new.php?id=' + node.attributes.properties.realId + '&pagesOnly=1'
- );
- },
-
- openInfoPopUp: function(node) {
- launchView('pages', node.attributes.properties.realId);
- },
-
- openHistoryPopUp: function(node) {
- TYPO3.Backend.ContentContainer.setUrl(
- 'show_rechis.php?element=pages:' + node.attributes.properties.realId
- );
- },
-
- enablePage: function(node) {
- this.tooglePageVisibility(node, false);
- },
-
- disablePage: function(node) {
- this.tooglePageVisibility(node, true);
- },
-
- tooglePageVisibility: function(node, enabled) {
- TYPO3.Components.PageTree.DataProvider.tooglePageVisibility(
- node.id,
- enabled,
- function(updatedNodeFromServer) {
- updatedNodeFromServer.uiProvider = TYPO3.Components.PageTree.PageTreeUI;
- var newTreeNode = new Ext.tree.TreeNode(updatedNodeFromServer);
- node.parentNode.replaceChild(newTreeNode, node);
- }
- );
- }
-};
\ No newline at end of file
(new Ext.dd.DropTarget(this.getEl(), {
notifyDrop: function(ddProxy, e, n) {
var node = n.node;
- // TODO: Permission checking again
var dropZoneBody = Ext.get(this.el.query('.x-panel-body')[0]);
dropZoneBody.update('You just deleted "' + node.text + '"<span class="undelete" style="text-decoration: underline;">Undelete</span>');
+
Ext.get(dropZoneBody.query('.undelete')[0]).on('click', function() {
- filteringTree.dataProvider.undeleteNode(node.id);
- filteringTree.refreshTree();
+ filteringTree.commandProvider.restoreNode(node, filteringTree);
+ filteringTree.tree.refreshTree();
this.update('<strong>Restored</strong>'); // TODO: LOCALIZE
}.createDelegate(dropZoneBody, [node.id, filteringTree]));
};
fadeOutFn.defer(5000, dropZoneBody);
- filteringTree.dataProvider.deleteNode(node.id);
- node.remove();
+ node.ownerTree.pageTree.commandProvider.removeNode(node, node.ownerTree);
},
ddGroup: 'TreeDD',
overClass: 'dd-delete-over'
// Only call the server if the server implements getNodeTypes();
this.pageTree.dataProvider.getNodeTypes(function(response) {
var length = response.length;
+ var item = null;
for (var i = 0; i < length; ++i) {
- newNodeToolbar.addItem(response[i]);
+ item = new Ext.Toolbar.Button(response[i]);
+ newNodeToolbar.addItem(item);
}
newNodeToolbar.doLayout();
});
this.pageTree.dataProvider.getSpriteIconClasses('actions-page-new', function(result) {
var topPanelButton = new Ext.Button({
- //text: 'filter',
cls: 'topPanel-button ' + result
});
},
/**
- * Adds a language selection menu to the topbar
+ * Adds a language selection menu to the top bar
* @internal
*/
addLanguageSelection: function() {
var topPanelButton = new Ext.Button({
cls: 'topPanel-button ' + result,
listeners: {
- scope: this.pageTree,
+ scope: this.pageTree.tree,
'click': {
- fn: this.pageTree.refreshTree
+ fn: this.pageTree.tree.refreshTree
}
}
});
--- /dev/null
+/***************************************************************
+* Copyright notice
+*
+* (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+* 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.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* 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!
+***************************************************************/
+
+/**
+ * Override TreeNodeUI
+ */
+
+Ext.namespace('TYPO3.Components.PageTree');
+
+TYPO3.Components.PageTree.PageTreeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+ // private
+ // This method is taken from ExtJS sources. Modifications are marked with // START TYPO3-MODIFICATION
+ renderElements : function(n, a, targetNode, bulkRender) {
+ // add some indent caching, this helps performance when rendering a large tree
+ this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
+ var cb = typeof a.checked === 'boolean';
+ var href = a.href ? a.href : Ext.isGecko ? "" : "#";
+ var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
+ '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
+ '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
+ // START TYPO3-MODIFICATION
+ a.spriteIconCode,
+ '<span class="prefixText">', a.prefixText, '</span>',
+ // END TYPO3-MODIFICATION
+ cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
+ '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
+ a.hrefTarget ? ' target="' + a.hrefTarget + '"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
+ '<ul class="x-tree-node-ct" style="display:none;"></ul>',
+ "</li>"].join('');
+
+ var nel;
+ if (bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())) {
+ this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
+ } else {
+ this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
+ }
+
+ this.elNode = this.wrap.childNodes[0];
+ this.ctNode = this.wrap.childNodes[1];
+ var cs = this.elNode.childNodes;
+ this.indentNode = cs[0];
+ this.ecNode = cs[1];
+ this.iconNode = cs[2];
+ // START TYPO3-MODIFICATION
+ Ext.fly(this.iconNode).on('click', function(event) {
+ this.getOwnerTree().openContextMenu(this, event); // calling the context-menu event doesn't work!'
+ event.stopEvent();
+ }, n);
+ // Index from 3 to 4 incremented!
+ var index = 4;
+ // STOP TYPO3-MODIFICATION
+ if (cb) {
+ this.checkbox = cs[3];
+ // fix for IE6
+ this.checkbox.defaultChecked = this.checkbox.checked;
+ index++;
+ }
+ this.anchor = cs[index];
+ this.textNode = cs[index].firstChild;
+ }
+});
\ No newline at end of file
+++ /dev/null
-/**
- * This is a library of callback actions for the page tree.
- */
-
-Ext.namespace('TYPO3.Components.PageTree');
-
-TYPO3.Components.PageTree.PageActions = {
- singleClick: function(node) {
- TYPO3.Backend.ContentContainer.setUrl(
- TS.PATH_typo3 + currentSubScript + '?id=' + node.attributes.properties.realId
- );
- },
-
- saveTitle: function(node, newText, oldText) {
- if (newText == oldText) {
- return;
- }
-
- node = node.editNode;
- TYPO3.Components.PageTree.DataProvider.setPageTitle(
- node.id,
- newText,
- node.attributes.properties.textSourceField,
- Ext.emptyFn
- );
- }
-};
\ No newline at end of file
-Ext.namespace('TYPO3.Components.PageTree');
+/***************************************************************
+* Copyright notice
+*
+* (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+* 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.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* 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!
+***************************************************************/
/**
- * This is the TreeNodeUI for the FilteringTree. This is the class which renders
- * the tree nodes.
- * The below modifications add another span tag around the icon for better skinning,
- * and a prefix text which is displayed in front of the real "text" contents.
- * Because the "text" property can be edited inline, the "prefixText" is used to
- * prepend the editable text.
+ * TYPO3 Page Tree Application
*/
-TYPO3.Components.PageTree.PageTreeUI = function() {
- TYPO3.Components.PageTree.PageTreeUI.superclass.constructor.apply(this, arguments);
-};
-Ext.extend(TYPO3.Components.PageTree.PageTreeUI, Ext.tree.TreeNodeUI, {
- // private
- // This method is taken from ExtJS sources. Modifications are marked with // START TYPO3-MODIFICATION
- renderElements : function(n, a, targetNode, bulkRender) {
- // add some indent caching, this helps performance when rendering a large tree
- this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
- var cb = typeof a.checked == 'boolean';
- var href = a.href ? a.href : Ext.isGecko ? "" : "#";
- var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
- '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
- '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
- // START TYPO3-MODIFICATION
- a.spriteIconCode,
- '<span class="prefixText">', a.prefixText, '</span>',
- // END TYPO3-MODIFICATION
- cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
- '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
- a.hrefTarget ? ' target="' + a.hrefTarget + '"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
- '<ul class="x-tree-node-ct" style="display:none;"></ul>',
- "</li>"].join('');
-
- var nel;
- if (bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())) {
- this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
- } else {
- this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
- }
-
- this.elNode = this.wrap.childNodes[0];
- this.ctNode = this.wrap.childNodes[1];
- var cs = this.elNode.childNodes;
- this.indentNode = cs[0];
- this.ecNode = cs[1];
- this.iconNode = cs[2];
- // START TYPO3-MODIFICATION
- Ext.fly(this.iconNode).on('click', function(event) {
- this.getOwnerTree().openContextMenu(this, event); // calling the context-menu event doesn't work!'
- event.stopEvent();
- }, n);
- // Index from 3 to 4 incremented!
- var index = 4;
- // STOP TYPO3-MODIFICATION
- if (cb) {
- this.checkbox = cs[3];
- // fix for IE6
- this.checkbox.defaultChecked = this.checkbox.checked;
- index++;
- }
- this.anchor = cs[index];
- this.textNode = cs[index].firstChild;
- },
- // private
- // Overwriting the double click event, because we don't want to collapse or expand nodes
- // by this event
- onDblClick : function(e) {
- if (this.disabled) {
- return;
- }
-
- if (this.fireEvent('beforedblclick', this.node, e) !== false) {
- this.fireEvent('dblclick', this.node, e);
- }
- }
-});
+Ext.namespace('TYPO3.Components.PageTree');
TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
id: 'typo3-pagetree',
topPanel: null,
dataProvider: null,
+ commandProvider : null,
+ contextMenuDataProvider: null,
contextMenuConfiguration: null,
initComponent: function() {
this.dataProvider = TYPO3.Components.PageTree.DataProvider;
+ this.commandProvider = TYPO3.Components.PageTree.Actions;
+ this.contextMenuDataProvider = TYPO3.Components.PageTree.ContextMenuDataProvider;
this.tree = new TYPO3.Components.PageTree.Tree({
- pageTree: this
+ pageTree: this,
+ plugins: new Ext.ux.plugins.TreePanelStateful()
});
this.topPanel = new TYPO3.Components.PageTree.FeaturePanel({
TYPO3.Components.PageTree.App.superclass.initComponent.apply(this, arguments);
},
- refreshTree: function() {
- this.tree.root.reload();
- },
-
/**
* Initialize the inline editor for the given tree.
*
*/
addInlineEditorFeature: function(tree) {
var treeEditor = new Ext.tree.TreeEditor(
- tree, {
- cancelOnEsc: true,
- completeOnEnter: true,
- ignoreNoChange: true,
- editDelay: 250,
- shadow: false
- }
- );
+ tree, {
+ ignoreNoChange: true,
+ editDelay: 250,
+ shadow: false
+ }
+ );
- treeEditor.addListener('complete', TYPO3.Components.PageTree.PageActions.saveTitle, this);
+ treeEditor.on({
+ beforestartedit: {
+ scope: this,
+ fn: function(treeEditor) {
+ // @todo treeEditor.editNode.attributes.label should be used as editable label
+ }
+ },
+
+ complete: {
+ scope: this,
+ fn: this.commandProvider.saveTitle
+ }
+ });
},
addNodeCopyPasteFeature: function(tree) {
// This event is ONLY called on move, NOT on copy, insert or delete.
tree.addListener('movenode', function(tree, movedNode, oldParent, newParent, position) {
if (position == 0) {
- this.dataProvider.moveNodeToFirstChildOfDestination(movedNode.id, newParent.id);
+ this.commandProvider.moveNodeToFirstChildOfDestination(movedNode, newParent.id);
} else {
var previousSibling = newParent.childNodes[position - 1];
- this.dataProvider.moveNodeAfterDestination(movedNode.id, previousSibling.id);
+ this.commandProvider.moveNodeAfterDestination(movedNode, previousSibling.id);
}
}, this);
de.dropNode.disable();
if (de.dropNode.previousSibling) {
// We have previous sibling, so we want to add the record AFTER the previous sibling
- this.dataProvider.insertNodeAfterDestination(de.dropNode.parentNode.id, de.dropNode.previousSibling.id, de.dropNode.serverNodeType, callback.createDelegate(de.dropNode));
+ this.commandProvider.insertNodeAfterDestination(de.dropNode, callback);
} else {
if (de.dropNode.parentNode) {
// We do not have a previous sibling, but a parent node. Thus, we add the node as the first child
// of the parent.
- this.dataProvider.insertNodeToFirstChildOfDestination(de.dropNode.parentNode.id, de.dropNode.serverNodeType, callback.createDelegate(de.dropNode));
+ this.commandProvider.insertNodeToFirstChildOfDestination(de.dropNode, callback);
} else {
// Should not happen!
}
de.dropNode.disable();
if (de.dropNode.previousSibling) {
// We have previous sibling, so we want to add the record AFTER the previous sibling
- this.dataProvider.copyNodeAfterDestination(de.dropNode.id, de.dropNode.previousSibling.id, callback.createDelegate(de.dropNode));
+ this.commandProvider.copyNodeAfterDestination(de.dropNode, callback);
} else {
if (de.dropNode.parentNode) {
// We do not have a previous sibling, but a parent node. Thus, we add the node as the first child
// of the parent.
- this.dataProvider.copyNodeToFirstChildOfDestination(de.dropNode.id, de.dropNode.parentNode, callback.createDelegate(de.dropNode));
+ this.commandProvider.copyNodeToFirstChildOfDestination(de.dropNode, callback);
} else {
// Should not happen!
}
}
}, this);
- // SECTION: Key Handlers
- new Ext.KeyMap(document, {
+ // SECTION: Key Handlers
+ (new Ext.KeyMap(document, {
key: Ext.EventObject.CONTROL,
fn: function() {
this.isControlPressed = true;
}
},
scope: this
- }, 'keydown');
+ }, 'keydown'));
- new Ext.KeyMap(document, {
+ (new Ext.KeyMap(document, {
key: Ext.EventObject.CONTROL,
fn: function() {
this.isControlPressed = false;
}
},
scope: this
- }, 'keyup');
+ }, 'keyup'));
}
});
+/***************************************************************
+* Copyright notice
+*
+* (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+* 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.
+* A copy is found in the textfile GPL.txt and important notices to the license
+* from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+* 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!
+***************************************************************/
+
+/**
+ * TYPO3 Page Tree Panel
+ */
+
Ext.namespace('TYPO3.Components.PageTree');
TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
ddGroup: 'TreeDD'
},
+ t3ContextNode: null,
+ t3ContextInfo: {
+ inCopyMode: false,
+ inCutMode: false
+ },
+
rootVisible: false,
pageTree: null,
contextMenuConfiguration: null,
this.loader = new Ext.tree.TreeLoader({
directFn: this.pageTree.dataProvider.getNextTreeLevel,
- paramOrder: 'rootline',
+ paramOrder: 'attributes',
baseAttrs: {
uiProvider: 't3'
t3: TYPO3.Components.PageTree.PageTreeUI,
rootNodeProvider: Ext.tree.TreeNodeUI
},
-
- // The below method fixes a stupid bug of ExtJS / PHP JSON:
- // ExtJS expects the "expanded" attribute to be "true", and
- // it compares it with ===.
- // PHP json_encode submits a "1" if the value is true - thus,
- // the expanded property is not correctly evaluated by ExtJS.
- // Below, we do a loose type checking, and if it matches, we
- // set the JavaScript value "true". This circumvents the bug.
+
createNode: function(attr) {
- if (attr.expanded) {
- attr.expanded = true;
+ if (attr.id == 0) {
+ attr.id = 'siteRootNode';
}
+
return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);
},
listeners: {
- // We always have to transmit the rootline to the server.
beforeload: function(treeLoader, node) {
- treeLoader.baseParams.rootline = node.getPath();
+ treeLoader.baseParams.attributes = node.attributes;
},
- load: function(treeLoader, node) {
- // Helper function
- var expandTransmittedNodesRecursively = function(node) {
- var numberOfSubNodes = node.childNodes.length;
- if (numberOfSubNodes > 0) {
- node.expand(false, false);
- }
- for (var i = 0; i < numberOfSubNodes; i++) {
- expandTransmittedNodesRecursively(node.childNodes[i]);
- }
- };
- expandTransmittedNodesRecursively(node);
+
+ load: {
+ scope: this,
+ fn: function(treeLoader, node) {
+ this.restoreState(node.getPath());
+ }
}
}
});
// shows the context menu and creates it if it's not already done
openContextMenu: function(node, event) {
node.select();
- var contextMenu = node.getOwnerTree().contextMenu;
- contextMenu.removeAll();
- var numberOfElementsInside = contextMenu.fillWithMenuItems(node, this.contextMenuConfiguration);
- if (numberOfElementsInside > 0) {
- contextMenu.showAt(event.getXY());
- }
- },
+ var attributes = { t3ContextInfo: node.ownerTree.t3ContextInfo };
+ attributes = Ext.apply(node.attributes.nodeData, attributes);
- listeners: {
- // SECTION Contextmenu
- // After rendering of the tree, we start the preloading of the context
- // menu configuration
- afterrender: {
- fn: function(tree) {
- if (tree.contextMenuConfiguration == null) {
- this.pageTree.dataProvider.getContextMenuConfiguration(
- function(result) {
- tree.contextMenuConfiguration = result;
- }
- );
+ this.pageTree.contextMenuDataProvider.getActionsForNodeArray(
+ attributes,
+ function(result) {
+ var contextMenu = node.getOwnerTree().contextMenu;
+ contextMenu.removeAll();
+
+ var numberOfElementsInside = contextMenu.fillWithMenuItems(node, this.pageTree, result);
+ if (numberOfElementsInside > 0) {
+ contextMenu.showAt(event.getXY());
}
- }
- },
+ },
+ this
+ );
+ },
+
+ refreshTree: function() {
+ this.getLoader().load(this.root);
+ },
+ refreshNode: function(node) {
+ this.getLoader().load(node);
+ },
+
+ listeners: {
// this event triggers the context menu
contextmenu: {
+ scope: this,
fn: function(node, event) {
node.getOwnerTree().openContextMenu(node, event);
}
},
- // SECTION Tree State Remember
- expandnode: {
- fn: function (node) {
- this.pageTree.dataProvider.registerExpandedNode(node.getPath());
- }
- },
-
- collapsenode: {
- fn: function(node) {
- this.pageTree.dataProvider.registerCollapsedNode(node.getPath());
- }
- },
-
- // calls a given single click callback for the tree
+ // calls a given single click callback for the tree
click: {
- fn: function (node, event) {
- if (this.doubleClickEventActive) {
- this.doubleClickEventActive = false;
+ fn: function(node, event) {
+ if (this.clicksRegistered === 2) {
+ this.clicksRegistered = 0;
event.stopEvent();
- } else {
- eval(node.attributes.properties.clickCallback + '(node)');
+ return false;
}
+
+ this.clicksRegistered = 0;
+ this.pageTree.commandProvider.singleClick(node);
},
delay: 400
},
- // seems to prevent some internal issues with the double-click for the tree editor
- dblclick: {
+ // needed or the label edit will never work
+ beforedblclick: {
fn: function() {
- this.doubleClickEventActive = true;
return false;
}
+ },
+
+ beforeclick: {
+ fn: function(node, event) {
+ if (!this.clicksRegistered && this.getSelectionModel().isSelected(node)) {
+ node.fireEvent('click', node, event);
+ ++this.clicksRegistered;
+ return false;
+ }
+ ++this.clicksRegistered;
+ }
}
}
});
$extensionPath = t3lib_extMgm::extPath('pagetree');
return array(
- 'tx_pagetree_abstracttree' => $extensionPath . 'classes/class.tx_pagetree_abstracttree.php',
- 'tx_pagetree_pagetree' => $extensionPath . 'classes/class.tx_pagetree_pagetree.php',
- 'tx_contextmenu_contextmenu' => $extensionPath . 'classes/class.tx_contextmenu_contextmenu.php',
- 'tx_pagetree_dataprovider_pagetree' => $extensionPath . 'extdirect/dataproviderclass.tx_pagetree_dataprovider_pagetree.php',
- 'tx_pagetree_dataprovider_abstracttree' => $extensionPath . 'extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php',
+ 'tx_pagetree_extdirect_tree' => $extensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_tree.php',
+ 'tx_pagetree_extdirect_commands' => $extensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_commands.php',
+ 'tx_pagetree_extdirect_contextmenu' => $extensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php',
+ 'tx_pagetree_dataprovider' => $extensionPath . 'classes/class.tx_pagetree_dataprovider.php',
+ 'tx_pagetree_node' => $extensionPath . 'classes/class.tx_pagetree_node.php',
+ 'tx_pagetree_nodecollection' => $extensionPath . 'classes/class.tx_pagetree_nodecollection.php',
+ 'tx_pagetree_stateprovider' => $extensionPath . 'classes/class.tx_pagetree_stateprovider.php',
+ 'tx_pagetree_commands' => $extensionPath . 'classes/class.tx_pagetree_commands.php',
+ 'tx_pagetree_contextmenu_action' => $extensionPath . 'classes/contextmenu/class.tx_pagetree_contextmenu_action.php',
+ 'tx_pagetree_contextmenu_dataprovider' => $extensionPath . 'classes/contextmenu/class.tx_pagetree_contextmenu_dataprovider.php',
);
?>
\ No newline at end of file
########################################################################
# Extension Manager/Repository config file for ext "pagetree".
#
-# Auto generated 16-11-2010 23:35
+# Auto generated 01-12-2010 12:27
#
# Manual updates:
# Only the data in the array - everything else is removed by next
'author_company' => '',
'CGLcompliance' => '',
'CGLcompliance_note' => '',
- 'version' => '1.0.0',
- '_md5_values_when_last_written' => 'a:19:{s:16:"ext_autoload.php";s:4:"c92c";s:12:"ext_icon.gif";s:4:"39bd";s:17:"ext_localconf.php";s:4:"a736";s:14:"ext_tables.php";s:4:"1e9f";s:25:"locallang_contextmenu.xml";s:4:"72dd";s:22:"locallang_pagetree.xml";s:4:"cd10";s:44:"classes/class.tx_contextmenu_contextmenu.php";s:4:"d8ab";s:42:"classes/class.tx_pagetree_abstracttree.php";s:4:"fc36";s:38:"classes/class.tx_pagetree_pagetree.php";s:4:"a142";s:36:"components/pagetree/css/pagetree.css";s:4:"9764";s:45:"components/pagetree/javascript/contextmenu.js";s:4:"3661";s:52:"components/pagetree/javascript/contextmenuactions.js";s:4:"89bd";s:50:"components/pagetree/javascript/deletiondropzone.js";s:4:"a924";s:46:"components/pagetree/javascript/featurepanel.js";s:4:"7c58";s:45:"components/pagetree/javascript/pageactions.js";s:4:"83f9";s:42:"components/pagetree/javascript/pagetree.js";s:4:"0786";s:38:"components/pagetree/javascript/tree.js";s:4:"4a3e";s:70:"extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php";s:4:"bfef";s:66:"extdirect/dataprovider/class.tx_pagetree_dataprovider_pagetree.php";s:4:"3eb3";}',
+ 'version' => '1.1.0',
+ '_md5_values_when_last_written' => 'a:30:{s:16:"ext_autoload.php";s:4:"b480";s:12:"ext_icon.gif";s:4:"39bd";s:17:"ext_localconf.php";s:4:"d1c7";s:14:"ext_tables.php";s:4:"7d74";s:25:"locallang_contextmenu.xml";s:4:"72dd";s:22:"locallang_pagetree.xml";s:4:"1265";s:38:"classes/class.tx_pagetree_commands.php";s:4:"7371";s:42:"classes/class.tx_pagetree_dataprovider.php";s:4:"eb8e";s:34:"classes/class.tx_pagetree_node.php";s:4:"b0a7";s:44:"classes/class.tx_pagetree_nodecollection.php";s:4:"a52a";s:43:"classes/class.tx_pagetree_stateprovider.php";s:4:"e0ab";s:60:"classes/contextmenu/class.tx_pagetree_contextmenu_action.php";s:4:"efa8";s:66:"classes/contextmenu/class.tx_pagetree_contextmenu_dataprovider.php";s:4:"9ad1";s:58:"classes/extdirect/class.tx_pagetree_extdirect_commands.php";s:4:"eade";s:61:"classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php";s:4:"c7bc";s:54:"classes/extdirect/class.tx_pagetree_extdirect_tree.php";s:4:"b483";s:43:"components/pagetree/pagetree-application.js";s:4:"46be";s:43:"components/pagetree/pagetree-contextmenu.js";s:4:"bfad";s:39:"components/pagetree/pagetree-factory.js";s:4:"d503";s:41:"components/pagetree/pagetree-overrides.js";s:4:"1552";s:36:"components/pagetree/pagetree-tree.js";s:4:"b338";s:36:"components/pagetree/css/pagetree.css";s:4:"9764";s:66:"components/pagetree/javascript/Ext.ux.plugins.TreePanelStateful.js";s:4:"c062";s:41:"components/pagetree/javascript/actions.js";s:4:"3a05";s:45:"components/pagetree/javascript/contextmenu.js";s:4:"0424";s:50:"components/pagetree/javascript/deletiondropzone.js";s:4:"c21f";s:46:"components/pagetree/javascript/featurepanel.js";s:4:"d398";s:43:"components/pagetree/javascript/overrides.js";s:4:"f231";s:42:"components/pagetree/javascript/pagetree.js";s:4:"46d5";s:38:"components/pagetree/javascript/tree.js";s:4:"9dfa";}',
'constraints' => array(
'depends' => array(
'cms' => '',
die ('Access denied.');
}
- // pagetree user default configuration
+ // context menu user default configuration
$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
- options.pageTree.doktypesToShowInNewPageDragArea = 1,3,4,6,7,199,254
-';
+ options.pageTree {
+ doktypesToShowInNewPageDragArea = 1,3,4,6,7,199,254
+ }
- // contextmenu user default configuration
-$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
options.contextMenu {
defaults {
}
100 = ITEM
100 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.viewPage
- outerIcon = actions-document-view
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.viewPage
+ spriteIcon = actions-document-view
+ displayCondition = canBeViewed != 0
+ callbackAction = viewPage
}
200 = DIVIDER
300 = ITEM
300 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.disablePage
- outerIcon = actions-edit-hide
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.disablePage
+ spriteIcon = actions-edit-hide
+ displayCondition = getRecord|hidden = 0 && canBeDisabledAndEnabled != 0
+ callbackAction = disablePage
}
400 = ITEM
400 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.enablePage
- outerIcon = actions-edit-unhide
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.enablePage
+ spriteIcon = actions-edit-unhide
+ displayCondition = getRecord|hidden = 1 && canBeDisabledAndEnabled != 0
+ callbackAction = enablePage
}
500 = ITEM
500 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.editPageProperties
- outerIcon = actions-document-open
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.editPageProperties
+ spriteIcon = actions-document-open
+ displayCondition = canBeEdited != 0
+ callbackAction = editPageProperties
}
600 = ITEM
600 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.info
- outerIcon = actions-document-info
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.openInfoPopUp
+ spriteIcon = actions-document-info
+ displayCondition = canShowInfo != 0
+ callbackAction = openInfoPopUp
}
700 = ITEM
700 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.history
- outerIcon = apps-pagetree-page-default+status-overlay-timing
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.openHistoryPopUp
+ spriteIcon = actions-document-history-open
+ displayCondition = canShowHistory != 0
+ callbackAction = openHistoryPopUp
}
800 = DIVIDER
100 = ITEM
100 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.newPage
- outerIcon = actions-document-new
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.newPageWizard
+ spriteIcon = actions-document-new
+ displayCondition = canCreateNewPages != 0
+ callbackAction = newPageWizard
}
200 = DIVIDER
300 = ITEM
300 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutPage
- outerIcon = actions-edit-cut
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+ spriteIcon = actions-edit-cut
+ displayCondition = isInCutMode = 0 && canBeCut != 0
+ callbackAction = enableCutMode
}
400 = ITEM
400 {
- label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPage
- outerIcon = actions-edit-copy
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+ label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutPage
+ spriteIcon = actions-edit-cut-release
+ displayCondition = isInCutMode = 1 && canBeCut != 0
+ callbackAction = disableCutMode
}
500 = ITEM
500 {
- label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteIntoPage
- outerIcon = actions-document-paste-after
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+ label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPage
+ spriteIcon = actions-edit-copy
+ displayCondition = isInCopyMode = 0 && canBeCopied != 0
+ callbackAction = enableCopyMode
}
600 = ITEM
600 {
- label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteAfterPage
- outerIcon = actions-document-paste-into
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+ label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyPage
+ spriteIcon = actions-edit-copy-release
+ displayCondition = isInCopyMode = 1 && canBeCopied != 0
+ callbackAction = disableCopyMode
}
- 700 = DIVIDER
+ 700 = ITEM
+ 700 {
+ label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteIntoPage
+ spriteIcon = actions-document-paste-after
+ displayCondition = getContextInfo|inCopyMode = 1 || getContextInfo|inCutMode = 1
+ callbackAction = pasteIntoNode
+ }
800 = ITEM
800 {
+ label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteAfterPage
+ spriteIcon = actions-document-paste-into
+ displayCondition = getContextInfo|inCopyMode = 1 || getContextInfo|inCutMode = 1
+ callbackAction = pasteAfterNode
+ }
+
+ 900 = DIVIDER
+
+ 1000 = ITEM
+ 1000 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.deletePage
- outerIcon = actions-edit-delete
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+ spriteIcon = actions-edit-delete
+ displayCondition = canBeRemoved != 0
+ callbackAction = removeNode
}
}
100 = ITEM
100 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.tempMountPoint
- outerIcon = actions-system-extension-documentation
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.stub
+ spriteIcon = actions-system-extension-documentation
+ displayCondition = canBeTemporaryMountPoint != 0
+ callbackAction = stub
}
}
}
100 = ITEM
100 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.renameFolder
- outerIcon = actions-edit-rename
- icon =
- callbackAction = TYPO3.Widget.ContextMenu.FolderActions.renameFolder
+ spriteIcon = actions-edit-rename
+ callbackAction = renameFolder
}
200 = ITEM
200 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.uploadFilesToFolder
- outerIcon = actions-edit-upload
- icon =
- callbackAction = TYPO3.Widget.ContextMenu.FolderActions.uploadFilesToFolder
+ spriteIcon = actions-edit-upload
+ callbackAction = uploadFilesToFolder
}
300 = ITEM
300 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.createFolder
- outerIcon = actions-edit-add
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.createFolder
+ spriteIcon = actions-edit-add
+ callbackAction = createFolder
}
400 = ITEM
400 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.folderInfo
- outerIcon = actions-document-info
- icon =
- callbackAction = TYPO3.Widget.ContextMenu.FolderActions.openInfoPopUp
+ spriteIcon = actions-document-info
+ callbackAction = openInfoPopUp
}
500 = DIVIDER
600 = ITEM
600 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.copyFolder
- outerIcon = actions-edit-copy
- icon =
- callbackAction = TYPO3.Widget.ContextMenu.FolderActions.copyFolder
+ spriteIcon = actions-edit-copy
+ callbackAction = copyFolder
}
700 = ITEM
700 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.cutFolder
- outerIcon = actions-edit-cut
- icon =
- callbackAction = TYPO3.Widget.ContextMenu.FolderActions.cutFolder
+ spriteIcon = actions-edit-cut
+ callbackAction = cutFolder
}
800 = ITEM
800 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.pasteIntoFolder
- outerIcon = actions-document-paste-after
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.pasteIntoFolder
+ spriteIcon = actions-document-paste-after
+ callbackAction = pasteIntoFolder
}
900 = DIVIDER
1000 = ITEM
1000 {
label = LLL:EXT:pagetree/locallang_contextmenu.xml:cm.deleteFolder
- outerIcon = actions-edit-delete
- icon =
- callbackAction = TYPO3.Components.PageTree.ContextMenuActions.deleteFolder
+ spriteIcon = actions-edit-delete
+ callbackAction = deleteFolder
}
}
}
));
}
- $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']['TYPO3.Components.PageTree.DataProvider'] =
- t3lib_extMgm::extPath($_EXTKEY) . 'extdirect/dataprovider/class.tx_pagetree_dataprovider_pagetree.php:tx_pagetree_dataprovider_Pagetree';
+ $absoluteExtensionPath = t3lib_extMgm::extPath($_EXTKEY);
+ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'] = array_merge(
+ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'], array(
+ 'TYPO3.Components.PageTree.DataProvider' =>
+ $absoluteExtensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_tree.php:tx_pagetree_ExtDirect_Tree',
+ 'TYPO3.Components.PageTree.Commands' =>
+ $absoluteExtensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_tree.php:tx_pagetree_ExtDirect_Commands',
+ 'TYPO3.Components.PageTree.ContextMenuDataProvider' =>
+ $absoluteExtensionPath . 'classes/extdirect/class.tx_pagetree_extdirect_contextmenu.php:tx_pagetree_ExtDirect_ContextMenu',
+ )
+ );
}
?>
\ No newline at end of file
+++ /dev/null
-<?php
-/***************************************************************
- * Copyright notice
- *
- * (c) 2009 Sebastian Kurfuerst
- * 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.
- * A copy is found in the textfile GPL.txt and important notices to the license
- * from the author is found in LICENSE.txt distributed with these scripts.
- *
- *
- * 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!
- ***************************************************************/
-
-/**
- * Abstract tree dataprovider
- *
- * @author Sebastian Kurfuerst <sebastian@typo3.org>
- * @package TYPO3
- */
-abstract class tx_pagetree_dataprovider_AbstractTree {
-
- protected $treeName;
-
- /**
- * Fetches the Items for the next level of the tree
- *
- * @param mixed The ID of the tree node
- * @param string The rootline of the element
- * @return array The next level tree elements
- */
- public function getNextTreeLevel($id, $rootline) {
- // Load UC
- $GLOBALS['BE_USER']->backendSetUC();
- $treeState =& $GLOBALS['BE_USER']->uc['treeState'][$this->treeName];
-
- $records = $this->getRecordsForNextTreeLevel($this->decodeTreeNodeId($id));
- $results = array();
- foreach ($records as $record) {
- $singleResult = $this->prepareRecordForResultList($record, $rootline);
- $rootlineOfSubElement = $rootline;
- // the rootline functionality is completely nonsense and should be replaced completely
- if ($singleResult['id']) {
- $rootlineOfSubElement = $rootline . '/' . $singleResult['id'];
- }
- if (isset($treeState[$rootlineOfSubElement])) {
- $singleResult['expanded'] = true;
- $singleResult['children'] = $this->getNextTreeLevel($singleResult['id'], $rootlineOfSubElement);
- }
-
- $results[] = $singleResult;
- }
- return $results;
- }
-
- /**
- * Prepares the records for the result list & fetches the actions
- *
- * @param array $record The record to be prepared
- * @param string $rootline The rootline of the record
- * @return array The prepared result
- */
- protected function prepareRecordForResultList($record, $rootline = '') {
- $currentResult = $this->getTreeNodePropertiesForRecord($record, $rootline);
- $currentResult['actions'] = $this->getActionsForRecord($record);
- return $currentResult;
- }
-
- /**
- * Saves the current expanded state of the tree to the user settings
- *
- * @param string $rootline The current rootline
- */
- public function registerExpandedNode($rootline) {
- $GLOBALS['BE_USER']->backendSetUC();
- $treeState =& $GLOBALS['BE_USER']->uc['treeState'][$this->treeName];
- $treeState[$rootline] = TRUE;
- $GLOBALS['BE_USER']->writeUC();
- }
-
- /**
- * Saves the current collapsed state of the tree to the user settings
- *
- * @param string $rootline The current rootline
- */
- public function registerCollapsedNode($rootline) {
- $GLOBALS['BE_USER']->backendSetUC();
- $treeState =& $GLOBALS['BE_USER']->uc['treeState'][$this->treeName];
- if (isset($treeState[$rootline])) {
- unset($treeState[$rootline]);
- }
- $GLOBALS['BE_USER']->writeUC();
- }
-
-
- /**
- * Encode node id and its rootline into an global unique identifier even if the same
- * node id is used a couple of times (webmounts, filemount, ...)
- *
- * @param string $id node id
- * @param string $rootline rootline / path include base-node like webmount-id/filemount-name
- */
- protected function encodeTreeNodeId($id, $rootline) {
- if ($rootline == '/root') {
- return $this->idEncode($id);
- } else {
- list(, , $mountpoint) = explode('/', $rootline);
- return 'mp' . $this->idEncode($mountpoint) . '-' . $this->idEncode($id);
- }
- }
-
- /**
- * Decodes the id of the tree node
- *
- * @param string $id The ID string
- * @return int
- */
- protected function decodeTreeNodeId($id) {
- if (strpos($id, 'mp') === 0) {
- // everything _INSIDE_ a mountpage
- // mp is in there, extract the ID!
- list(, $id) = explode('-', $id);
- return $this->idDecode($id);
- } else {
- // /root, and /root/XXX (mountpage)
- return $id;
- }
- }
-
- /**
- * Encodes an id, this one just does an intval, if you need
- * something more implement your own method
- * @return the encoded ID
- */
- protected function idEncode($id) {
- return intval($id);
- }
-
- /**
- * Decodes an id, this one just does an intval, if you need
- * something more implement your own method
- * @return the decoded ID
- */
- protected function idDecode($id) {
- return intval($id);
- }
-
- /**
- * Get Label
- *
- * @param string $label label name
- * @return string the localized label string
- */
- protected function getLabel($label) {
- return $GLOBALS['LANG']->sL($label, TRUE);
- }
-
- /**
- * Get Icon for Context Menu
- *
- * @param string $icon Icon name
- * @return string Returns part of the img tag like ' src="[backPath][src]" [wHattribs]'
- */
- protected function getIcon($icon) {
-
- return $icon;
- }
-
- /**
- * Fetches a filtered tree
- *
- * @param string $searchString The string to search for
- *
- */
- abstract public function getFilteredTree($searchString);
-
- /**
- * Fetches the records for the next tree level (subpages or subdirectories f.e.)
- *
- * @return array a multidimensional array of records to be displayed in the tree on the next level, including the metainformation for the record
- */
- abstract protected function getRecordsForNextTreeLevel($id);
-
- /**
- * gets a record, and MUST return an array with the following properties:
- * - id (UNIQUE id)
- * - leaf (boolean) - FALSE, if it has child records
- * - text - the title of the node in the tree
- * additionally, you can specify any of the Ext.tree.TreeNode properties, except "attributes".
- */
- abstract protected function getTreeNodePropertiesForRecord($record, $rootline);
-
-
- /**
- * Get an array of actions which can be performed with this single record. Used for the context menu.
- */
- abstract protected function getActionsForRecord($record);
-
- /**
- * Generates the context menu items which can be toogled on/off by the record actions.
- * You need to define them inside a hash array with the fields "text" and "callback".
- * @see getActionsForRecord
- */
- abstract public function getContextMenuConfiguration();
-}
-
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php']) {
- include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/extdirect/dataprovider/class.tx_pagetree_dataprovider_abstracttree.php']);
-}
-
-?>
\ No newline at end of file
+++ /dev/null
-<?php
-/***************************************************************
- * Copyright notice
- *
- * (c) 2009 Sebastian Kurfuerst
- * 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.
- * A copy is found in the textfile GPL.txt and important notices to the license
- * from the author is found in LICENSE.txt distributed with these scripts.
- *
- *
- * 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!
- ***************************************************************/
-
-class tx_pagetree_dataprovider_Pagetree extends tx_pagetree_dataprovider_AbstractTree {
- public $enableIcons = TRUE;
- public $backPath = '';
- protected $treeName = 'pages';
-
- /**
- * PageTree
- *
- * @var tx_pagetree_Pagetree
- */
- protected $pageTree;
-
- public function __construct() {
- $this->pageTree = t3lib_div::makeInstance('tx_pagetree_Pagetree');
-
- if ($GLOBALS['BE_USER']->uc['noMenuMode']
- && strcmp($GLOBALS['BE_USER']->uc['noMenuMode'], 'icons')
- ) {
- $this->enableIcons = FALSE;
- }
- }
-
- public function moveNodeToFirstChildOfDestination($movedNode, $destination) {
- $movedNode = $this->decodeTreeNodeId($movedNode);
- $destination = $this->decodeTreeNodeId($destination);
-
- $uid = intval($movedNode);
- $destination = intval($destination);
- $this->pageTree->move($uid, $destination);
- }
-
- public function moveNodeAfterDestination($movedNode, $destination) {
- $movedNode = $this->decodeTreeNodeId($movedNode);
- $destination = $this->decodeTreeNodeId($destination);
-
- $uid = intval($movedNode);
- $destination = intval($destination);
- $this->pageTree->move($uid, -$destination);
- }
-
- public function copyNodeToFirstChildOfDestination($copiedNode, $destination) {
- $copiedNode = $this->decodeTreeNodeId($copiedNode);
- $destination = $this->decodeTreeNodeId($destination);
-
- $uid = intval($copiedNode);
- $destination = intval($destination);
- $newPageId = $this->pageTree->copy($uid, $destination);
-
- return $this->getWholeRecordForIdAndPrepareItForResultList($newPageId);
- }
-
- public function copyNodeAfterDestination($copiedNode, $destination) {
- $copiedNode = $this->decodeTreeNodeId($copiedNode);
- $destination = $this->decodeTreeNodeId($destination);
-
- $uid = intval($copiedNode);
- $destination = intval($destination);
-
- $newPageId = $this->pageTree->copy($uid, -$destination);
-
- return $this->getWholeRecordForIdAndPrepareItForResultList($newPageId);
- }
-
- public function insertNodeToFirstChildOfDestination($parentNode, $pageType) {
- $parentNode = intval($this->decodeTreeNodeId($parentNode));
-
- $newPageId = $this->pageTree->create($parentNode, $parentNode, $pageType);
- return $this->getWholeRecordForIdAndPrepareItForResultList($newPageId);
- }
-
- public function insertNodeAfterDestination($parentNode, $destination, $pageType) {
- $parentNode = intval($this->decodeTreeNodeId($parentNode));
- $destination = intval($this->decodeTreeNodeId($destination));
-
- $newPageId = $this->pageTree->create($parentNode, -$destination, $pageType);
- return $this->getWholeRecordForIdAndPrepareItForResultList($newPageId);
- }
-
-
- public function deleteNode($nodeId) {
- $id = $this->decodeTreeNodeId($nodeId);
- $this->pageTree->remove($id);
- }
-
- public function undeleteNode($nodeId) {
- $id = $this->decodeTreeNodeId($nodeId);
- $this->pageTree->restore($id);
- }
-
- protected function getWholeRecordForIdAndPrepareItForResultList($newNode) {
- $resultRow = t3lib_BEfunc::getRecordWSOL(
- 'pages',
- $newNode,
- $fields = '*',
- $where = '',
- $useDeleteClause = TRUE,
- $GLOBALS['BE_USER']->uc['currentPageTreeLanguage']
- );
- return $this->prepareRecordForResultList($resultRow);
- }
-
- public function getFilteredTree($searchString) {
- $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
- 'uid',
- 'pages',
- 'title LIKE ' . $GLOBALS['TYPO3_DB']->fullQuoteStr('%' . $searchString . '%', 'pages') .
- t3lib_BEfunc::deleteClause('pages') .
- t3lib_BEfunc::versioningPlaceholderClause('pages') . ' AND ' .
- $GLOBALS['BE_USER']->getPagePermsClause(1)
- );
-
- $result = array();
- foreach ($records as $singleRecord) {
- $rootline = t3lib_BEfunc::BEgetRootLine($singleRecord['uid']);
- $rootline = array_reverse($rootline);
- array_shift($rootline);
- $currentNode = &$result; // what the fuck? Who codes such unmaintainable stuff?
-
- foreach ($rootline as $rootlineElement) {
- $rootlineElement['_subpages'] = 1;
- if (isset($currentNode[$rootlineElement['uid']])) {
- $currentNode = &$currentNode[$rootlineElement['uid']]['children'];
- }
- else {
- $currentNode[$rootlineElement['uid']] = $this->prepareRecordForResultList($rootlineElement);
- $currentNode[$rootlineElement['uid']]['text'] = preg_replace('/(' .
- preg_quote($searchString, '/') . ')/i', '<strong class="highlight">$1</strong>',
- $currentNode[$rootlineElement['uid']]['text']);
-
-
- $currentNode[$rootlineElement['uid']]['children'] = array();
- $currentNode = &$currentNode[$rootlineElement['uid']]['children'];
- }
- }
- }
- $this->convertChildrenToUnnamedArray($result);
- return $result;
- }
-
- private function convertChildrenToUnnamedArray(&$array) {
- $array = array_values($array);
- foreach ($array as &$value) {
- if (isset($value['children']) && is_array($value['children'])) {
- $this->convertChildrenToUnnamedArray($value['children']);
- }
- }
- }
-
- protected function getRecordsForNextTreeLevel($id) {
- if ($id === 'root') {
- return $this->pageTree->getTreeMounts();
- } else {
- return $this->pageTree->getSubPages($id);
- }
- }
-
- protected function getTreeNodePropertiesForRecord($record, $rootline) {
- if ($this->pageTree->getTsConfigOptionForPagetree('showNavTitle')) {
- $fields = array('nav_title', 'title');
- } else {
- $fields = array('title', 'nav_title');
- }
-
- $textSourceField = '';
- foreach ($fields as $field) {
- if (!empty($record[$field])) {
- $text = $record[$field];
- $textSourceField = $field;
- break;
- }
- }
-
- $languageOverlayIcon = '';
- if ($record['_PAGES_OVERLAY']) {
- $currentTreeLanguage = intval($GLOBALS['BE_USER']->uc['currentPageTreeLanguage']);
- $languageRecord = $this->getLanguage($currentTreeLanguage);
- $languageShortcut = $this->getLanguageShortcutFromFile($languageRecord['flag']);
- $languageOverlayIcon = t3lib_iconWorks::getSpriteIcon(
- 'flags-' . $languageShortcut . '-overlay'
- );
- unset($languageRecord, $languageShortcut);
- }
-
- if ($record['uid'] !== 0) {
- $spriteIconCode = t3lib_iconWorks::getSpriteIconForRecord(
- 'pages',
- $record,
- array(
- 'html' => $languageOverlayIcon,
- )
- );
- } else {
- $spriteIconCode = t3lib_iconWorks::getSpriteIcon('apps-pagetree-root');
- }
- return array(
- 'record' => $record,
- 'id' => $this->encodeTreeNodeId($record['uid'], $rootline),
- 'qtip' => 'ID: ' . $record['uid'],
- 'leaf' => $record['_subpages'] == 0,
- 'text' => $text,
- 'prefixText' => $this->getPrefixForDisplayedTitle($record), // This is the prefix before the title string
- 'spriteIconCode' => $spriteIconCode,
- '_meta' => array('numSubPages' => $record['_subpages']),
- 'properties' => array(
- 'clickCallback' => 'TYPO3.Components.PageTree.PageActions.singleClick',
- 'textSourceField' => $textSourceField,
- 'realId' => $record['uid']
- )
- );
- }
-
- public function getSpriteIconClasses($icon) {
- return t3lib_iconWorks::getSpriteIconClasses($icon);
- }
-
- // @todo respect tsconfig options
- protected function getActionsForRecord($record) {
- return $record['_actions'];
- }
-
- protected function getPrefixForDisplayedTitle($row) {
- $prefix = '';
-
- if ($this->pageTree->getTsConfigOptionForPagetree('showPageIdWithTitle')) {
- $prefix .= $row['uid'];
- }
- return $prefix;
- }
-
- public function getPageInformation($pageId, $fields) {
- return $this->pageTree->getPageInformationForGivenFields($pageId, $fields);
- }
-
- protected function getNextContextMenuLevel($typoScriptConfiguration, $level) {
- if ($level > 5) {
- return array();
- }
-
- $type = '';
- $contextMenuItems = array();
- foreach ($typoScriptConfiguration as $index => $typoScriptItem) {
- $hash = md5(microtime());
-
- if (substr($index, -1) === '.') {
- switch ($type) {
- case 'SUBMENU':
- $contextMenuItems['--submenu-' . $hash . '--'] =
- $this->getNextContextMenuLevel($typoScriptItem, ++$level);
-
- $contextMenuItems['--submenu-' . $hash . '--']['text'] =
- $this->getLabel($typoScriptItem['label']);
- break;
-
- case 'ITEM':
- // transform icon and text
- $contextMenuItems[$index] = array(
- 'text' => $this->getLabel($typoScriptItem['label'])
- );
-
- // push additional attributes
- $contextMenuItems[$index] = array_merge(
- $typoScriptItem,
- $contextMenuItems[$index]
- );
-
- if ($this->enableIcons) {
- if (!empty($typoScriptItem['icon'])) {
- $contextMenuItems[$index]['icon'] =
- $this->getIcon($typoScriptItem['icon']);
- } elseif (isset($typoScriptItem['outerIcon'])) {
- $contextMenuItems[$index] = array_merge(
- $contextMenuItems[$index],
- $this->getIconClassFromIcon($typoScriptItem['outerIcon'])
- );
- }
- } else {
- $contextMenuItems[$index]['icon'] = '';
- }
- break;
-
- default:
- break;
- }
- } else {
- $type = $typoScriptItem;
-
- // add divider
- if ($type === 'DIVIDER') {
- $contextMenuItems['--divider-' . $hash . '--'] = array(
- 'action' => 'divider'
- );
- }
- }
- }
-
- return $contextMenuItems;
- }
-
- public function getContextMenuConfiguration() {
- // @TODO defaults must be considered
- $contextMenuItemTypoScriptConfiguration = $GLOBALS['BE_USER']->getTSConfig(
- 'options.contextMenu.table.pages.items'
- );
- $contextMenuItemTypoScriptConfiguration = $contextMenuItemTypoScriptConfiguration['properties'];
-
- $contextMenuItems = $this->getNextContextMenuLevel(
- $contextMenuItemTypoScriptConfiguration,
- 0
- );
- return $contextMenuItems;
- }
-
- /**
- * Fetches the attributes for an action inside the context menu.
- * @todo optimize to prevent much useless ajax calls...
- *
- * @param int $id page uid
- * @param string $menuItemId clickmenu item identifier
- */
- public function getAttributesForContextMenu($id, $menuItemId) {
- $this->decodeTreeNodeId($id);
-
- switch ($menuItemId) {
- default:
- $attributes = array();
- break;
- }
-
- return $attributes;
- }
-
- /**
- * Helper function to generate the neede css classes for img display with overlay
- *
- * @param string $icon icon identifier
- */
- protected function getIconClassFromIcon($icon) {
- return array(
- // 'hrefTarget' => $iconClass[0], // href target is used as a small hack for the template function of the menu.Item
- 'iconCls' => $this->getSpriteIconClasses($icon)
- );
- }
-
- /**
- * Returns the page view link
- *
- * @param int $id page id
- * @param unknown $workspacePreview ???
- * @return string
- */
- public function getViewLink($id, $workspacePreview) {
- $id = $this->decodeTreeNodeId($id);
- return $this->pageTree->getViewLink($id, $workspacePreview);
- }
-
- /**
- *
- * @param string $id page id (can be numerical or like "mp-12" in case of mount-points ,...)
- * @param string $title
- * @param string $textSourceField
- */
- public function setPageTitle($id, $title, $textSourceField) {
- $id = $this->decodeTreeNodeId($id);
- $this->pageTree->updateTextInputField($id, $title, $textSourceField);
- }
-
- /**
- * Enables or disables a page and returns the new node
- *
- * @param string $id page id (can be numerical or like "mp-12" in case of mount-points ,...)
- * @param boolean $enabled true for enabling and false for disabling
- * @return array new node
- */
- public function tooglePageVisibility($id, $enabled) {
- $id = $this->decodeTreeNodeId($id);
- $this->pageTree->updateTextInputField($id, $enabled, 'hidden');
-
- $node = $this->getWholeRecordForIdAndPrepareItForResultList($id);
- return $node;
- }
-
- /**
- * Returns the localized list of doktypes to display
- *
- * see User TSconfig: options.pageTree.doktypesToShowInNewPageDragArea
- */
- public function getNodeTypes() {
- $doktypes = t3lib_div::trimExplode(
- ',',
- $this->pageTree->getTsConfigOptionForPagetree('doktypesToShowInNewPageDragArea')
- );
-
- $output = array();
- foreach ($doktypes as $doktype) {
- $label = $this->getLabel('LLL:EXT:pagetree/locallang_pagetree.xml:page.doktype.' . $doktype);
- $output[] = array(
- 'nodeType' => $doktype,
- 'title' => $label,
- 'cls' => 'topPanel-button ' . $this->getSpriteIconClasses(
- $GLOBALS['TCA']['pages']['ctrl']['typeicon_classes'][$doktype]
- ),
- );
- }
- return $output;
- }
-
- /**
- * Returns the language shortcut from a language file
- *
- * @param string $file language flag with or without the related directory
- * @return mixed language shortcut or boolean false
- */
- protected function getLanguageShortcutFromFile($file) {
- if (strpos($file, '/') !== FALSE) {
- $file = basename($file);
- }
-
- return substr($file, 0, strrpos($file, '.'));
- }
-
- /**
- * Returns a language record defined by the id parameter
- *
- * @param int $uid language id
- * @return array
- */
- protected function getLanguage($uid) {
- $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
- 'flag',
- 'sys_language',
- 'pid=0 AND uid=' . $uid .
- t3lib_BEfunc::deleteClause('sys_language')
- );
-
- $record = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
- $GLOBALS['TYPO3_DB']->sql_free_result($res);
-
- return $record;
- }
-
- /**
- * Returns an array of system languages with parameters based on the properties
- * of Ext.Button.
- *
- * @return array
- */
- public function getLanguages() {
- $languageRecords = t3lib_befunc::getSystemLanguages();
-
- $output = array();
- foreach ($languageRecords as $languageRecord) {
- $languageShortcut = $this->getLanguageShortcutFromFile($languageRecord[2]);
- if ($languageShortcut === FALSE) {
- $languageShortcut = 'europeanunion';
- }
-
- $output[] = array(
- 'language' => $languageRecord[1],
- 'languageShortcut' => $languageShortcut,
- 'cls' => 'topPanel-button ' .
- $this->getSpriteIconClasses('flags-' . $languageShortcut),
- );
- }
-
- return $output;
- }
-
- /**
- * Returns the european flag sprite icon css classes
- *
- * @TODO What if a flag is added to the core, but isn't inside the sprite?
- * @return string
- */
- public function getIconForCurrentLanguage() {
- $currentTreeLanguage = intval($GLOBALS['BE_USER']->uc['currentPageTreeLanguage']);
-
- $icon = 'flags-europeanunion';
- if ($currentTreeLanguage !== 0) {
- $languageRecord = $this->getLanguage($currentTreeLanguage);
- $icon = 'flags-' . $this->getLanguageShortcutFromFile($languageRecord['flag']);
- }
-
- return $this->getSpriteIconClasses($icon);
- }
-
- /**
- * Saves the given language id into the backend user configuration array
- *
- * @param int $languageId
- * @return void
- */
- public function saveCurrentTreeLanguage($languageId) {
- $GLOBALS['BE_USER']->backendSetUC();
- $GLOBALS['BE_USER']->uc['currentPageTreeLanguage'] = intval($languageId);
- $GLOBALS['BE_USER']->writeUC();
- }
-}
-
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/extdirect/dataprovider/class.t3lib_tree_dataprovider_pagetree.php']) {
- include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/sysext/pagetree/extdirect/dataprovider/class.t3lib_tree_dataprovider_pagetree.php']);
-}
-
-?>
<label index="page.doktype.7">Mountpoint</label>
<label index="page.doktype.199">Spacer</label>
<label index="page.doktype.254">Sysfolder</label>
+ <label index="defaultTitle">[Default Title]</label>
</languageKey>
</data>
</T3locallang>