/** * Action to edit records * * @param array $record sys_action record * @return string list of records */ protected function viewEditRecord($record) { $content = ''; $actionList = array(); $dbAnalysis = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Database\\RelationHandler'); $dbAnalysis->setFetchAllFields(TRUE); $dbAnalysis->start($record['t4_recordsToEdit'], '*'); $dbAnalysis->getFromDB(); // collect the records foreach ($dbAnalysis->itemArray as $el) { $path = BackendUtility::getRecordPath($el['id'], $this->taskObject->perms_clause, $GLOBALS['BE_USER']->uc['titleLen']); $record = BackendUtility::getRecord($el['table'], $dbAnalysis->results[$el['table']][$el['id']]); $title = BackendUtility::getRecordTitle($el['table'], $dbAnalysis->results[$el['table']][$el['id']]); $description = $GLOBALS['LANG']->sL($GLOBALS['TCA'][$el['table']]['ctrl']['title'], TRUE); // @todo: which information could be needful if (isset($record['crdate'])) { $description .= ' - ' . BackendUtility::dateTimeAge($record['crdate']); } $actionList[$el['id']] = array('title' => $title, 'description' => BackendUtility::getRecordTitle($el['table'], $dbAnalysis->results[$el['table']][$el['id']]), 'descriptionHtml' => $description, 'link' => $GLOBALS['BACK_PATH'] . 'alt_doc.php?returnUrl=' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI')) . '&edit[' . $el['table'] . '][' . $el['id'] . ']=edit', 'icon' => \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord($el['table'], $dbAnalysis->results[$el['table']][$el['id']], array('title' => htmlspecialchars($path)))); } // Render the record list $content .= $this->taskObject->renderListMenu($actionList); return $content; }
/** * Generates grid list array from given versions. * * @param array $versions All available version records * @param string $filterTxt Text to be used to filter record result * @return void */ protected function generateDataArray(array $versions, $filterTxt) { $workspaceAccess = $GLOBALS['BE_USER']->checkWorkspace($GLOBALS['BE_USER']->workspace); $swapStage = $workspaceAccess['publish_access'] & 1 ? \TYPO3\CMS\Workspaces\Service\StagesService::STAGE_PUBLISH_ID : 0; $swapAccess = $GLOBALS['BE_USER']->workspacePublishAccess($GLOBALS['BE_USER']->workspace) && $GLOBALS['BE_USER']->workspaceSwapAccess(); $this->initializeWorkspacesCachingFramework(); // check for dataArray in cache if ($this->getDataArrayFromCache($versions, $filterTxt) === FALSE) { /** @var $stagesObj \TYPO3\CMS\Workspaces\Service\StagesService */ $stagesObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Workspaces\\Service\\StagesService'); $defaultGridColumns = array(self::GridColumn_Collection => 0, self::GridColumn_CollectionLevel => 0, self::GridColumn_CollectionParent => '', self::GridColumn_CollectionCurrent => '', self::GridColumn_CollectionChildren => 0); foreach ($versions as $table => $records) { $hiddenField = $this->getTcaEnableColumnsFieldName($table, 'disabled'); $isRecordTypeAllowedToModify = $GLOBALS['BE_USER']->check('tables_modify', $table); foreach ($records as $record) { $origRecord = BackendUtility::getRecord($table, $record['t3ver_oid']); $versionRecord = BackendUtility::getRecord($table, $record['uid']); $combinedRecord = \TYPO3\CMS\Workspaces\Domain\Model\CombinedRecord::createFromArrays($table, $origRecord, $versionRecord); $this->getIntegrityService()->checkElement($combinedRecord); if ($hiddenField !== NULL) { $recordState = $this->workspaceState($versionRecord['t3ver_state'], $origRecord[$hiddenField], $versionRecord[$hiddenField]); } else { $recordState = $this->workspaceState($versionRecord['t3ver_state']); } $isDeletedPage = $table == 'pages' && $recordState == 'deleted'; $viewUrl = \TYPO3\CMS\Workspaces\Service\WorkspaceService::viewSingleRecord($table, $record['uid'], $origRecord, $versionRecord); $versionArray = array(); $versionArray['table'] = $table; $versionArray['id'] = $table . ':' . $record['uid']; $versionArray['uid'] = $record['uid']; $versionArray['workspace'] = $versionRecord['t3ver_id']; $versionArray = array_merge($versionArray, $defaultGridColumns); $versionArray['label_Workspace'] = htmlspecialchars(BackendUtility::getRecordTitle($table, $versionRecord)); $versionArray['label_Live'] = htmlspecialchars(BackendUtility::getRecordTitle($table, $origRecord)); $versionArray['label_Stage'] = htmlspecialchars($stagesObj->getStageTitle($versionRecord['t3ver_stage'])); $tempStage = $stagesObj->getNextStage($versionRecord['t3ver_stage']); $versionArray['label_nextStage'] = htmlspecialchars($stagesObj->getStageTitle($tempStage['uid'])); $tempStage = $stagesObj->getPrevStage($versionRecord['t3ver_stage']); $versionArray['label_prevStage'] = htmlspecialchars($stagesObj->getStageTitle($tempStage['uid'])); $versionArray['path_Live'] = htmlspecialchars(BackendUtility::getRecordPath($record['livepid'], '', 999)); $versionArray['path_Workspace'] = htmlspecialchars(BackendUtility::getRecordPath($record['wspid'], '', 999)); $versionArray['workspace_Title'] = htmlspecialchars(\TYPO3\CMS\Workspaces\Service\WorkspaceService::getWorkspaceTitle($versionRecord['t3ver_wsid'])); $versionArray['workspace_Tstamp'] = $versionRecord['tstamp']; $versionArray['workspace_Formated_Tstamp'] = BackendUtility::datetime($versionRecord['tstamp']); $versionArray['t3ver_wsid'] = $versionRecord['t3ver_wsid']; $versionArray['t3ver_oid'] = $record['t3ver_oid']; $versionArray['livepid'] = $record['livepid']; $versionArray['stage'] = $versionRecord['t3ver_stage']; $versionArray['icon_Live'] = \TYPO3\CMS\Backend\Utility\IconUtility::mapRecordTypeToSpriteIconClass($table, $origRecord); $versionArray['icon_Workspace'] = \TYPO3\CMS\Backend\Utility\IconUtility::mapRecordTypeToSpriteIconClass($table, $versionRecord); $languageValue = $this->getLanguageValue($table, $versionRecord); $versionArray['languageValue'] = $languageValue; $versionArray['language'] = array('cls' => \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconClasses($this->getSystemLanguageValue($languageValue, 'flagIcon')), 'title' => htmlspecialchars($this->getSystemLanguageValue($languageValue, 'title'))); $versionArray['allowedAction_nextStage'] = $isRecordTypeAllowedToModify && $stagesObj->isNextStageAllowedForUser($versionRecord['t3ver_stage']); $versionArray['allowedAction_prevStage'] = $isRecordTypeAllowedToModify && $stagesObj->isPrevStageAllowedForUser($versionRecord['t3ver_stage']); if ($swapAccess && $swapStage != 0 && $versionRecord['t3ver_stage'] == $swapStage) { $versionArray['allowedAction_swap'] = $isRecordTypeAllowedToModify && $stagesObj->isNextStageAllowedForUser($swapStage); } elseif ($swapAccess && $swapStage == 0) { $versionArray['allowedAction_swap'] = $isRecordTypeAllowedToModify; } else { $versionArray['allowedAction_swap'] = FALSE; } $versionArray['allowedAction_delete'] = $isRecordTypeAllowedToModify; // preview and editing of a deleted page won't work ;) $versionArray['allowedAction_view'] = !$isDeletedPage && $viewUrl; $versionArray['allowedAction_edit'] = $isRecordTypeAllowedToModify && !$isDeletedPage; $versionArray['allowedAction_editVersionedPage'] = $isRecordTypeAllowedToModify && !$isDeletedPage; $versionArray['state_Workspace'] = $recordState; $versionArray = array_merge($versionArray, $this->getAdditionalColumnService()->getData($combinedRecord)); if ($filterTxt == '' || $this->isFilterTextInVisibleColumns($filterTxt, $versionArray)) { $versionIdentifier = $versionArray['id']; $this->dataArray[$versionIdentifier] = $versionArray; } } } // Suggested slot method: // methodName(\TYPO3\CMS\Workspaces\Service\GridDataService $gridData, array &$dataArray, array $versions) $this->emitSignal(self::SIGNAL_GenerateDataArray_BeforeCaching, $this->dataArray, $versions); // Enrich elements after everything has been processed: foreach ($this->dataArray as &$element) { $identifier = $element['table'] . ':' . $element['t3ver_oid']; $element['integrity'] = array('status' => $this->getIntegrityService()->getStatusRepresentation($identifier), 'messages' => htmlspecialchars($this->getIntegrityService()->getIssueMessages($identifier, TRUE))); } $this->setDataArrayIntoCache($versions, $filterTxt); } // Suggested slot method: // methodName(\TYPO3\CMS\Workspaces\Service\GridDataService $gridData, array &$dataArray, array $versions) $this->emitSignal(self::SIGNAL_GenerateDataArray_PostProcesss, $this->dataArray, $versions); $this->sortDataArray(); $this->resolveDataArrayDependencies(); }
/** * [Describe function...] * * @param [type] $arr: ... * @param [type] $depthData: ... * @param [type] $keyArray: ... * @param [type] $first: ... * @return [type] ... * @todo Define visibility */ public function ext_getTemplateHierarchyArr($arr, $depthData, $keyArray, $first = 0) { $keyArr = array(); foreach ($arr as $key => $value) { $key = preg_replace('/\\.$/', '', $key); if (substr($key, -1) != '.') { $keyArr[$key] = 1; } } $a = 0; $c = count($keyArr); static $i = 0; foreach ($keyArr as $key => $value) { $HTML = ''; $a++; $deeper = is_array($arr[$key . '.']); $row = $arr[$key]; $PM = 'join'; $LN = $a == $c ? 'blank' : 'line'; $BTM = $a == $c ? 'top' : ''; $PM = 'join'; $HTML .= $depthData; $alttext = '[' . $row['templateID'] . ']'; $alttext .= $row['pid'] ? ' - ' . BackendUtility::getRecordPath($row['pid'], $GLOBALS['SOBE']->perms_clause, 20) : ''; $icon = substr($row['templateID'], 0, 3) == 'sys' ? \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord('sys_template', $row, array('title' => $alttext)) : \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('mimetypes-x-content-template-static', array('title' => $alttext)); if (in_array($row['templateID'], $this->clearList_const) || in_array($row['templateID'], $this->clearList_setup)) { $urlParameters = array('id' => $GLOBALS['SOBE']->id, 'template' => $row['templateID']); $aHref = BackendUtility::getModuleUrl('web_ts', $urlParameters); $A_B = '<a href="' . htmlspecialchars($aHref) . '">'; $A_E = '</a>'; if (GeneralUtility::_GP('template') == $row['templateID']) { $A_B = '<strong>' . $A_B; $A_E .= '</strong>'; } } else { $A_B = ''; $A_E = ''; } $HTML .= ($first ? '' : IconUtility::getSpriteIcon('treeline-' . $PM . $BTM)) . $icon . $A_B . htmlspecialchars(GeneralUtility::fixed_lgd_cs($row['title'], $GLOBALS['BE_USER']->uc['titleLen'])) . $A_E . ' '; $RL = $this->ext_getRootlineNumber($row['pid']); $keyArray[] = '<tr class="' . ($i++ % 2 == 0 ? 'bgColor4' : 'bgColor6') . '"> <td nowrap="nowrap">' . $HTML . '</td> <td align="center">' . ($row['root'] ? \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-status-checked') : '') . ' </td> <td align="center">' . ($row['clConf'] ? \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-status-checked') : '') . ' ' . '</td> <td align="center">' . ($row['clConst'] ? \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-status-checked') : '') . ' ' . '</td> <td align="center">' . ($row['pid'] ?: '') . '</td> <td align="center">' . (strcmp($RL, '') ? $RL : '') . '</td> <td>' . ($row['next'] ? ' ' . $row['next'] . ' ' : '') . '</td> </tr>'; if ($deeper) { $keyArray = $this->ext_getTemplateHierarchyArr($arr[$key . '.'], $depthData . ($first ? '' : IconUtility::getSpriteIcon('treeline-' . $LN)), $keyArray); } } return $keyArray; }
/** * Action to edit records * * @param array $record sys_action record * @return string list of records */ protected function viewEditRecord($record) { $content = ''; $actionList = array(); $dbAnalysis = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Database\RelationHandler::class); $dbAnalysis->setFetchAllFields(true); $dbAnalysis->start($record['t4_recordsToEdit'], '*'); $dbAnalysis->getFromDB(); // collect the records foreach ($dbAnalysis->itemArray as $el) { $path = BackendUtility::getRecordPath($el['id'], $this->taskObject->perms_clause, $this->getBackendUser()->uc['titleLen']); $record = BackendUtility::getRecord($el['table'], $dbAnalysis->results[$el['table']][$el['id']]); $title = BackendUtility::getRecordTitle($el['table'], $dbAnalysis->results[$el['table']][$el['id']]); $description = $this->getLanguageService()->sL($GLOBALS['TCA'][$el['table']]['ctrl']['title'], true); // @todo: which information could be needful if (isset($record['crdate'])) { $description .= ' - ' . BackendUtility::dateTimeAge($record['crdate']); } $link = BackendUtility::getModuleUrl('record_edit', array('edit[' . $el['table'] . '][' . $el['id'] . ']' => 'edit', 'returnUrl' => $this->moduleUrl), false, true); $actionList[$el['id']] = array('uid' => 'record-' . $el['table'] . '-' . $el['id'], 'title' => $title, 'description' => BackendUtility::getRecordTitle($el['table'], $dbAnalysis->results[$el['table']][$el['id']]), 'descriptionHtml' => $description, 'link' => $link, 'icon' => '<span title="' . htmlspecialchars($path) . '">' . $this->iconFactory->getIconForRecord($el['table'], $dbAnalysis->results[$el['table']][$el['id']], Icon::SIZE_SMALL)->render() . '</span>'); } // Render the record list $content .= $this->taskObject->renderListMenu($actionList); return $content; }
/** * Send an email notification to users in workspace * * @param array $stat Workspace access array from \TYPO3\CMS\Core\Authentication\BackendUserAuthentication::checkWorkspace() * @param int $stageId New Stage number: 0 = editing, 1= just ready for review, 10 = ready for publication, -1 = rejected! * @param string $table Table name of element (or list of element names if $id is zero) * @param int $id Record uid of element (if zero, then $table is used as reference to element(s) alone) * @param string $comment User comment sent along with action * @param DataHandler $tcemainObj TCEmain object * @param array $notificationAlternativeRecipients List of recipients to notify instead of be_users selected by sys_workspace, list is generated by workspace extension module * @return void */ protected function notifyStageChange(array $stat, $stageId, $table, $id, $comment, DataHandler $tcemainObj, array $notificationAlternativeRecipients = array()) { $workspaceRec = BackendUtility::getRecord('sys_workspace', $stat['uid']); // So, if $id is not set, then $table is taken to be the complete element name! $elementName = $id ? $table . ':' . $id : $table; if (!is_array($workspaceRec)) { return; } // Get the new stage title from workspaces library, if workspaces extension is installed if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('workspaces')) { $stageService = GeneralUtility::makeInstance(\TYPO3\CMS\Workspaces\Service\StagesService::class); $newStage = $stageService->getStageTitle((int) $stageId); } else { // @todo CONSTANTS SHOULD BE USED - tx_service_workspace_workspaces // @todo use localized labels // Compile label: switch ((int) $stageId) { case 1: $newStage = 'Ready for review'; break; case 10: $newStage = 'Ready for publishing'; break; case -1: $newStage = 'Element was rejected!'; break; case 0: $newStage = 'Rejected element was noticed and edited'; break; default: $newStage = 'Unknown state change!?'; } } if (count($notificationAlternativeRecipients) == 0) { // Compile list of recipients: $emails = array(); switch ((int) $stat['stagechg_notification']) { case 1: switch ((int) $stageId) { case 1: $emails = $this->getEmailsForStageChangeNotification($workspaceRec['reviewers']); break; case 10: $emails = $this->getEmailsForStageChangeNotification($workspaceRec['adminusers'], TRUE); break; case -1: // List of elements to reject: $allElements = explode(',', $elementName); // Traverse them, and find the history of each foreach ($allElements as $elRef) { list($eTable, $eUid) = explode(':', $elRef); $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('log_data,tstamp,userid', 'sys_log', 'action=6 and details_nr=30 AND tablename=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($eTable, 'sys_log') . ' AND recuid=' . (int) $eUid, '', 'uid DESC'); // Find all implicated since the last stage-raise from editing to review: foreach ($rows as $dat) { $data = unserialize($dat['log_data']); $emails = $this->getEmailsForStageChangeNotification($dat['userid'], TRUE) + $emails; if ($data['stage'] == 1) { break; } } } break; case 0: $emails = $this->getEmailsForStageChangeNotification($workspaceRec['members']); break; default: $emails = $this->getEmailsForStageChangeNotification($workspaceRec['adminusers'], TRUE); } break; case 10: $emails = $this->getEmailsForStageChangeNotification($workspaceRec['adminusers'], TRUE); $emails = $this->getEmailsForStageChangeNotification($workspaceRec['reviewers']) + $emails; $emails = $this->getEmailsForStageChangeNotification($workspaceRec['members']) + $emails; break; default: // Do nothing } } else { $emails = $notificationAlternativeRecipients; } // prepare and then send the emails if (count($emails)) { // Path to record is found: list($elementTable, $elementUid) = explode(':', $elementName); $elementUid = (int) $elementUid; $elementRecord = BackendUtility::getRecord($elementTable, $elementUid); $recordTitle = BackendUtility::getRecordTitle($elementTable, $elementRecord); if ($elementTable == 'pages') { $pageUid = $elementUid; } else { BackendUtility::fixVersioningPid($elementTable, $elementRecord); $pageUid = $elementUid = $elementRecord['pid']; } // fetch the TSconfig settings for the email // old way, options are TCEMAIN.notificationEmail_body/subject $TCEmainTSConfig = $tcemainObj->getTCEMAIN_TSconfig($pageUid); // new way, options are // pageTSconfig: tx_version.workspaces.stageNotificationEmail.subject // userTSconfig: page.tx_version.workspaces.stageNotificationEmail.subject $pageTsConfig = BackendUtility::getPagesTSconfig($pageUid); $emailConfig = $pageTsConfig['tx_version.']['workspaces.']['stageNotificationEmail.']; $markers = array('###RECORD_TITLE###' => $recordTitle, '###RECORD_PATH###' => BackendUtility::getRecordPath($elementUid, '', 20), '###SITE_NAME###' => $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'], '###SITE_URL###' => GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . TYPO3_mainDir, '###WORKSPACE_TITLE###' => $workspaceRec['title'], '###WORKSPACE_UID###' => $workspaceRec['uid'], '###ELEMENT_NAME###' => $elementName, '###NEXT_STAGE###' => $newStage, '###COMMENT###' => $comment, '###USER_REALNAME###' => $tcemainObj->BE_USER->user['realName'], '###USER_FULLNAME###' => $tcemainObj->BE_USER->user['realName'], '###USER_USERNAME###' => $tcemainObj->BE_USER->user['username']); // add marker for preview links if workspace extension is loaded if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('workspaces')) { $this->workspaceService = GeneralUtility::makeInstance(\TYPO3\CMS\Workspaces\Service\WorkspaceService::class); // only generate the link if the marker is in the template - prevents database from getting to much entries if (GeneralUtility::isFirstPartOfStr($emailConfig['message'], 'LLL:')) { $tempEmailMessage = $GLOBALS['LANG']->sL($emailConfig['message']); } else { $tempEmailMessage = $emailConfig['message']; } if (strpos($tempEmailMessage, '###PREVIEW_LINK###') !== FALSE) { $markers['###PREVIEW_LINK###'] = $this->workspaceService->generateWorkspacePreviewLink($elementUid); } unset($tempEmailMessage); $markers['###SPLITTED_PREVIEW_LINK###'] = $this->workspaceService->generateWorkspaceSplittedPreviewLink($elementUid, TRUE); } // Hook for preprocessing of the content for formmails: if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/version/class.tx_version_tcemain.php']['notifyStageChange-postModifyMarkers'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/version/class.tx_version_tcemain.php']['notifyStageChange-postModifyMarkers'] as $_classRef) { $_procObj =& GeneralUtility::getUserObj($_classRef); $markers = $_procObj->postModifyMarkers($markers, $this); } } // send an email to each individual user, to ensure the // multilanguage version of the email $emailRecipients = array(); // an array of language objects that are needed // for emails with different languages $languageObjects = array($GLOBALS['LANG']->lang => $GLOBALS['LANG']); // loop through each recipient and send the email foreach ($emails as $recipientData) { // don't send an email twice if (isset($emailRecipients[$recipientData['email']])) { continue; } $emailSubject = $emailConfig['subject']; $emailMessage = $emailConfig['message']; $emailRecipients[$recipientData['email']] = $recipientData['email']; // check if the email needs to be localized // in the users' language if (GeneralUtility::isFirstPartOfStr($emailSubject, 'LLL:') || GeneralUtility::isFirstPartOfStr($emailMessage, 'LLL:')) { $recipientLanguage = $recipientData['lang'] ? $recipientData['lang'] : 'default'; if (!isset($languageObjects[$recipientLanguage])) { // a LANG object in this language hasn't been // instantiated yet, so this is done here /** @var $languageObject \TYPO3\CMS\Lang\LanguageService */ $languageObject = GeneralUtility::makeInstance(\TYPO3\CMS\Lang\LanguageService::class); $languageObject->init($recipientLanguage); $languageObjects[$recipientLanguage] = $languageObject; } else { $languageObject = $languageObjects[$recipientLanguage]; } if (GeneralUtility::isFirstPartOfStr($emailSubject, 'LLL:')) { $emailSubject = $languageObject->sL($emailSubject); } if (GeneralUtility::isFirstPartOfStr($emailMessage, 'LLL:')) { $emailMessage = $languageObject->sL($emailMessage); } } $emailSubject = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($emailSubject, $markers, '', TRUE, TRUE); $emailMessage = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($emailMessage, $markers, '', TRUE, TRUE); // Send an email to the recipient /** @var $mail \TYPO3\CMS\Core\Mail\MailMessage */ $mail = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class); if (!empty($recipientData['realName'])) { $recipient = array($recipientData['email'] => $recipientData['realName']); } else { $recipient = $recipientData['email']; } $mail->setTo($recipient)->setSubject($emailSubject)->setFrom(\TYPO3\CMS\Core\Utility\MailUtility::getSystemFrom())->setBody($emailMessage); $mail->send(); } $emailRecipients = implode(',', $emailRecipients); $tcemainObj->newlog2('Notification email for stage change was sent to "' . $emailRecipients . '"', $table, $id); } }
/** * Entry method * * @return array As defined in initializeResultArray() of AbstractNode */ public function render() { $languageService = $this->getLanguageService(); $backendUser = $this->getBackendUserAuthentication(); $table = $this->data['tableName']; $row = $this->data['databaseRow']; $options = $this->data; if (empty($this->data['fieldListToRender'])) { $options['renderType'] = 'fullRecordContainer'; } else { $options['renderType'] = 'listOfFieldsContainer'; } $result = $this->nodeFactory->create($options)->render(); $childHtml = $result['html']; $recordPath = ''; // @todo: what is this >= 0 check for? wsol cases?! if ($this->data['effectivePid'] >= 0) { $permissionsClause = $backendUser->getPagePermsClause(1); $recordPath = BackendUtility::getRecordPath($this->data['effectivePid'], $permissionsClause, 15); } $iconFactory = GeneralUtility::makeInstance(IconFactory::class); $icon = '<span title="' . htmlspecialchars($recordPath) . '">' . $iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render() . '</span>'; // @todo: Could this be done in a more clever way? Does it work at all? $tableTitle = $languageService->sL($this->data['processedTca']['ctrl']['title']); if ($this->data['command'] === 'new') { $newOrUid = ' <span class="typo3-TCEforms-newToken">' . $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.new', true) . '</span>'; // @todo: There is quite some stuff do to for WS overlays ... $workspacedPageRecord = BackendUtility::getRecordWSOL('pages', $this->data['effectivePid'], 'title'); $pageTitle = BackendUtility::getRecordTitle('pages', $workspacedPageRecord, true, false); if ($table === 'pages') { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.createNewPage', true); $pageTitle = sprintf($label, $tableTitle); } else { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.createNewRecord', true); if ($this->data['effectivePid'] === 0) { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.createNewRecordRootLevel', true); } $pageTitle = sprintf($label, $tableTitle, $pageTitle); } } else { $icon = BackendUtility::wrapClickMenuOnIcon($icon, $table, $row['uid'], 1, '', '+copy,info,edit,view'); $newOrUid = ' <span class="typo3-TCEforms-recUid">[' . htmlspecialchars($row['uid']) . ']</span>'; // @todo: getRecordTitlePrep applies an htmlspecialchars here $recordLabel = BackendUtility::getRecordTitlePrep($this->data['recordTitle']); if ($table === 'pages') { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.editPage', true); $pageTitle = sprintf($label, $tableTitle, $recordLabel); } else { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.editRecord', true); $workspacedPageRecord = BackendUtility::getRecordWSOL('pages', $row['pid'], 'uid,title'); $pageTitle = BackendUtility::getRecordTitle('pages', $workspacedPageRecord, true, false); if (empty($recordLabel)) { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.editRecordNoTitle', true); } if ($this->data['effectivePid'] === 0) { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.editRecordRootLevel', true); } if (!empty($recordLabel)) { // Use record title and prepend an edit label. $pageTitle = sprintf($label, $tableTitle, $recordLabel, $pageTitle); } else { // Leave out the record title since it is not set. $pageTitle = sprintf($label, $tableTitle, $pageTitle); } } } $html = array(); $html[] = '<h1>' . $pageTitle . '</h1>'; $html[] = '<div class="typo3-TCEforms">'; $html[] = $childHtml; $html[] = '<div class="help-block text-right">'; $html[] = $icon . ' <strong>' . htmlspecialchars($tableTitle) . '</strong>' . ' ' . $newOrUid; $html[] = '</div>'; $html[] = '</div>'; $result['html'] = implode(LF, $html); return $result; }
/** * Returns the path for a certain pid * The result is cached internally for the session, thus you can call * this function as much as you like without performance problems. * * @param int $pid The page id for which to get the path * @return mixed[] The path. */ public function recPath($pid) { if (!isset($this->recPath_cache[$pid])) { $this->recPath_cache[$pid] = BackendUtility::getRecordPath($pid, $this->perms_clause, 20); } return $this->recPath_cache[$pid]; }
/** * Main Task center module * * @return string HTML content. * @todo Define visibility */ public function main() { if ($id = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('display')) { return $this->urlInIframe($this->backPath . \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extRelPath('impexp') . 'app/index.php?tx_impexp[action]=export&preset[load]=1&preset[select]=' . $id, 1); } else { // Thumbnail folder and files: $tempDir = $this->userTempFolder(); if ($tempDir) { $thumbnails = \TYPO3\CMS\Core\Utility\GeneralUtility::getFilesInDir($tempDir, 'png,gif,jpg', 1); } $clause = $GLOBALS['BE_USER']->getPagePermsClause(1); $usernames = \TYPO3\CMS\Backend\Utility\BackendUtility::getUserNames(); // Create preset links: $presets = $this->getPresets(); $opt = array(); $opt[] = ' <tr class="bgColor5 tableheader"> <td>Icon:</td> <td>Preset Title:</td> <td>Public</td> <td>Owner:</td> <td>Page:</td> <td>Path:</td> <td>Meta data:</td> </tr>'; if (is_array($presets)) { foreach ($presets as $presetCfg) { $configuration = unserialize($presetCfg['preset_data']); $thumbnailFile = $thumbnails[$configuration['meta']['thumbnail']]; $title = strlen($presetCfg['title']) ? $presetCfg['title'] : '[' . $presetCfg['uid'] . ']'; $opt[] = ' <tr class="bgColor4"> <td>' . ($thumbnailFile ? '<img src="' . $this->backPath . '../' . substr($tempDir, strlen(PATH_site)) . basename($thumbnailFile) . '" hspace="2" width="70" style="border: solid black 1px;" alt="" /><br />' : ' ') . '</td> <td nowrap="nowrap"><a href="index.php?SET[function]=tx_impexp&display=' . $presetCfg['uid'] . '">' . htmlspecialchars(\TYPO3\CMS\Core\Utility\GeneralUtility::fixed_lgd_cs($title, 30)) . '</a> </td> <td>' . ($presetCfg['public'] ? 'Yes' : ' ') . '</td> <td>' . ($presetCfg['user_uid'] === $GLOBALS['BE_USER']->user['uid'] ? 'Own' : '[' . $usernames[$presetCfg['user_uid']]['username'] . ']') . '</td> <td>' . ($configuration['pagetree']['id'] ? $configuration['pagetree']['id'] : ' ') . '</td> <td>' . htmlspecialchars($configuration['pagetree']['id'] ? \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($configuration['pagetree']['id'], $clause, 20) : '[Single Records]') . '</td> <td> <strong>' . htmlspecialchars($configuration['meta']['title']) . '</strong><br />' . htmlspecialchars($configuration['meta']['description']) . ($configuration['meta']['notes'] ? '<br /><br /><strong>Notes:</strong> <em>' . htmlspecialchars($configuration['meta']['notes']) . '</em>' : '') . ' </td> </tr>'; } $content = '<table border="0" cellpadding="0" cellspacing="1" class="lrPadding">' . implode('', $opt) . '</table>'; } } // Output: $theOutput .= $this->pObj->doc->spacer(5); $theOutput .= $this->pObj->doc->section('Export presets', $content, 0, 1); return $theOutput; }
/** * Returns the path for a record. Is the whole path for all records except pages - for these the last part is cut * off, because it contains the pagetitle itself, which would be double information * * The path is returned uncut, cutting has to be done by calling function. * * @param array $row The row * @param array $record The record * @return string The record-path */ protected function getRecordPath(&$row, $uid) { $titleLimit = max($this->config['maxPathTitleLength'], 0); if (($this->mmForeignTable ? $this->mmForeignTable : $this->table) == 'pages') { $path = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($uid, '', $titleLimit); // For pages we only want the first (n-1) parts of the path, // because the n-th part is the page itself $path = substr($path, 0, strrpos($path, '/', -2)) . '/'; } else { $path = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($row['pid'], '', $titleLimit); } return $path; }
/** * * Displays the user administration interface. * This includes a list of all registered users ordered descending by * username. The list includes the usergroups a user is member in and the * user's age. A search function is also included. * * @return string The HTML output. * @todo Outsource user management into own class! */ function userManagement() { /* Get template */ $template = file_get_contents(GeneralUtility::getFileAbsFileName('EXT:mm_forum/res/tmpl/mod1/users.html')); $template = tx_mmforum_BeTools::getSubpart($template, '###USERS_LIST###'); $uTemplate = tx_mmforum_BeTools::getSubpart($template, '###USERS_LIST_ITEM###'); // Retrieve global variables global $LANG, $BACK_PATH, $BE_USER; /** @var $LANG \TYPO3\CMS\Lang\LanguageService */ // Generate SQL query $ug = $this->feGroups2Array(); $mmforum = GeneralUtility::_GP('mmforum'); if ($mmforum['no_filter']) { unset($mmforum['sword']); unset($mmforum['old_sword']); } if ($mmforum['old_sword'] && !$mmforum['sword']) { $mmforum['sword'] = $mmforum['old_sword']; } $gp = ''; if ($mmforum['sword']) { $gp = '&mmforum[sword]=' . $mmforum['sword']; } $groups = implode(',', array(intval($this->confArr['userGroup']), intval($this->confArr['modGroup']), intval($this->confArr['adminGroup']))); if ($sword = $mmforum['sword']) { $sword = $this->databaseHandle->escapeStrForLike($sword, 'fe_users'); $sword = $this->databaseHandle->fullQuoteStr($sword . '%', 'fe_users'); $filter = 'username like ' . $sword; } else { $filter = '1'; } // Determine sort order. The default is "ASC" order. switch (strtoupper(GeneralUtility::_GP('mmforum_style'))) { case 'DESC': $orderBy = 'DESC'; break; case 'ASC': default: $orderBy = 'ASC'; break; } if (GeneralUtility::_GP('mmforum_sort') == 'username') { $order = 'username ' . $orderBy . ''; $uOrder = $orderBy == 'ASC' ? 'DESC' : 'ASC'; $aOrder = 'ASC'; } elseif (GeneralUtility::_GP('mmforum_sort') == 'age') { $order = 'crdate ' . $orderBy . ''; $aOrder = $orderBy == 'ASC' ? 'DESC' : 'ASC'; $uOrder = 'ASC'; } else { $order = 'username ' . $orderBy . ''; $aOrder = 'ASC'; $uOrder = 'DESC'; } #$userGroup_query = "(".$this->confArr['userGroup']." IN (usergroup) OR ".$this->confArr['modGroup']." IN (usergroup) OR ".$this->confArr['adminGroup']." IN (usergroup))"; $userGroup_query = "(FIND_IN_SET('" . $this->confArr['userGroup'] . "',usergroup) OR FIND_IN_SET('" . $this->confArr['modGroup'] . "',usergroup) OR FIND_IN_SET('" . $this->confArr['adminGroup'] . "',usergroup))"; #$userGroup_query = "1"; $res = $this->databaseHandle->exec_SELECTquery('count(*)', 'fe_users', "{$filter} and pid='" . $this->confArr['userPID'] . "' and " . $userGroup_query . " and deleted=0"); $row = $this->databaseHandle->sql_fetch_row($res); $records = $row[0]; $pages = ceil($records / $this->confArr['recordsPerPage']); $offset = intval($mmforum['offset']); // Page navigation $pb = $LANG->getLL('page.page') . ' <a href="index.php?mmforum[offset]=0' . $gp . '">[' . $LANG->getLL('page.first') . ']</a> '; $end = $offset + 6 >= $pages ? $pages : $offset + 6; $start = $offset - 5; if ($start < 0) { $start = 0; } if ($start > 0) { $pb .= '... '; } for ($i = $start; $i < $end; $i++) { $pb .= '<a href="index.php?mmforum[offset]=' . $i . $gp . '">' . ($i == $offset ? '<b>' . ($i + 1) . '</b>' : $i + 1) . '</a> '; } if ($offset + 11 < $pages) { $pb .= ' ... <a href="index.php?mmforum[offset]=' . ($pages - 1) . $gp . '">[' . $LANG->getLL('page.last') . ']</a> '; } // Generate header table if ($records < $this->confArr['recordsPerPage']) { $mDisp = $records; } else { $mDisp = $offset * $this->confArr['recordsPerPage'] + $this->confArr['recordsPerPage']; } $userString = sprintf($LANG->getLL('useradmin.usercount'), $offset * $this->confArr['recordsPerPage'] + 1, $mDisp, $records); $out = '<table width="733"><tr>'; $out .= '<td width="420">' . $pb . '</td>'; $out .= '<td width="120" align="center"><b>' . $userString . '</b></td>'; $out .= '<td align="right">' . $LANG->getLL('useradmin.searchfor') . ': <input type="text" id="sword" size="20" name="mmforum[sword]" /></td>'; $out .= '</tr></table>'; if ($mmforum['sword'] || $mmforum['old_sword']) { $out .= '<p>' . $LANG->getLL('useradmin.filter') . ': ' . $mmforum['sword'] . '* <a href="index.php?mmforum[no_filter]=1&' . $this->linkParams($mmforum) . '">' . $LANG->getLL('useradmin.filter.clear') . '</a></p>'; $out .= '<input type="hidden" name="mmforum[old_sword]" value="' . $mmforum['sword'] . '" />'; } // Display userdata table // Execute database query $res = $this->databaseHandle->exec_SELECTquery('*', 'fe_users', "{$filter} and pid='" . $this->confArr['userPID'] . "' and deleted=0 AND " . $userGroup_query, '', $order, $offset * $this->confArr['recordsPerPage'] . "," . $this->confArr['recordsPerPage']); if ($res) { $marker = array('###USERS_LLL_TITLE###' => $LANG->getLL('users.title'), '###USERS_LLL_USERNAME###' => '<a href="index.php?mmforum_sort=username&mmforum_style=' . $uOrder . '">' . $LANG->getLL('useradmin.username') . '</a>', '###USERS_LLL_REGISTERED###' => '<a href="index.php?mmforum_sort=age&mmforum_style=' . $aOrder . '">' . $LANG->getLL('useradmin.age') . '</a>', '###USERS_LLL_GROUPS###' => $LANG->getLL('useradmin.usergroup'), '###USERS_LLL_OPTIONS###' => ' '); $i = 0; $uContent = ''; while ($row = $this->databaseHandle->sql_fetch_assoc($res)) { // Display user groups $g = explode(',', $row['usergroup']); $outg = ''; foreach ($g as $sg) { $outg .= $ug[$sg] . ', '; } $iconAltText = BackendUtility::getRecordIconAltText($row, $table); $elementTitle = BackendUtility::getRecordPath($row['uid'], '1=1', 0); $elementTitle = GeneralUtility::fixed_lgd_cs($elementTitle, -$BE_USER->uc['titleLen']); $elementIcon = IconUtility::getIconImage($table, $row, $BACK_PATH, 'class="c-recicon" title="' . $iconAltText . '"'); $params = '&edit[fe_users][' . $row['uid'] . ']=edit'; $editOnClick = BackendUtility::editOnClick($params, $BACK_PATH); // Generate row item $class_suffix = $i++ % 2 == 0 ? '2' : ''; $link = "index.php?mmforum[cid]=" . $row['uid']; $js = 'onmouseover="this.className=\'mm_forum-listrow_active\'; this.style.cursor=\'pointer\';" onmouseout="this.className=\'mm_forum-listrow' . $class_suffix . '\'" onclick="' . htmlspecialchars($editOnClick) . '"'; $icon = '<img src="../icon_tx_mmforum_forums.gif" />'; $hidden = $row['hidden'] == 1 ? '<span style="color:blue;">[' . $LANG->getLL('boardadmin.hidden') . ']</span> ' : ''; $uMarker = array('###USER_USERNAME###' => htmlspecialchars($row['username']), '###USER_REGISTERED###' => BackendUtility::dateTimeAge($row['crdate'], 1), '###USER_GROUPS###' => substr($outg, -2) == ', ' ? substr($outg, 0, strlen($outg) - 2) : $outg, '###USER_OPTIONS###' => '<img src="img/edit.png" onclick="' . htmlspecialchars($editOnClick) . '" style="cursor:pointer;" />'); $uContent .= tx_mmforum_BeTools::substituteMarkerArray($uTemplate, $uMarker); } $template = tx_mmforum_BeTools::substituteSubpart($template, '###USERS_LIST_ITEM###', $uContent); $template = tx_mmforum_BeTools::substituteMarkerArray($template, $marker); $out .= $template; } return $out; }
/** * Resolve page id to page path string (with automatic cropping to maximum given length). * * @param integer $pid Pid of the page * @param integer $titleLimit Limit of the page title * @return string Page path string */ public function render($pid, $titleLimit = 20) { return \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($pid, '', $titleLimit); }
/** * Generate the flashmessages for current pid * * @return string HTML content with flashmessages */ protected function getHeaderFlashMessagesForCurrentPid() { $content = ''; $lang = $this->getLanguageService(); $view = GeneralUtility::makeInstance(StandaloneView::class); $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/InfoBox.html')); // If page is a folder if ($this->pageinfo['doktype'] == PageRepository::DOKTYPE_SYSFOLDER) { $moduleLoader = GeneralUtility::makeInstance(ModuleLoader::class); $moduleLoader->load($GLOBALS['TBE_MODULES']); $modules = $moduleLoader->modules; if (is_array($modules['web']['sub']['list'])) { $title = $lang->getLL('goToListModule'); $message = '<p>' . $lang->getLL('goToListModuleMessage') . '</p>'; $message .= '<a class="btn btn-info" href="javascript:top.goToModule(\'web_list\',1);">' . $lang->getLL('goToListModule') . '</a>'; $view->assignMultiple(['title' => $title, 'message' => $message, 'state' => InfoboxViewHelper::STATE_INFO]); $content .= $view->render(); } } elseif ($this->pageinfo['doktype'] === PageRepository::DOKTYPE_SHORTCUT) { $shortcutMode = (int) $this->pageinfo['shortcut_mode']; $pageRepository = GeneralUtility::makeInstance(PageRepository::class); $targetPage = []; if ($this->pageinfo['shortcut'] || $shortcutMode) { switch ($shortcutMode) { case PageRepository::SHORTCUT_MODE_NONE: $targetPage = $pageRepository->getPage($this->pageinfo['shortcut']); break; case PageRepository::SHORTCUT_MODE_FIRST_SUBPAGE: $targetPage = reset($pageRepository->getMenu($this->pageinfo['shortcut'] ?: $this->pageinfo['uid'])); break; case PageRepository::SHORTCUT_MODE_PARENT_PAGE: $targetPage = $pageRepository->getPage($this->pageinfo['pid']); break; } $message = ''; if ($shortcutMode === PageRepository::SHORTCUT_MODE_RANDOM_SUBPAGE) { $message .= sprintf($lang->getLL('pageIsRandomInternalLinkMessage')); } else { $linkToPid = $this->local_linkThisScript(['id' => $targetPage['uid']]); $path = BackendUtility::getRecordPath($targetPage['uid'], $this->getBackendUser()->getPagePermsClause(Permission::PAGE_SHOW), 1000); $linkedPath = '<a href="' . $linkToPid . '">' . htmlspecialchars($path) . '</a>'; $message .= sprintf($lang->getLL('pageIsInternalLinkMessage'), $linkedPath); } $message .= ' (' . htmlspecialchars($lang->sL(BackendUtility::getLabelFromItemlist('pages', 'shortcut_mode', $shortcutMode))) . ')'; $view->assignMultiple(['title' => $this->pageinfo['title'], 'message' => $message, 'state' => InfoboxViewHelper::STATE_INFO]); $content .= $view->render(); } else { if (empty($targetPage) && $shortcutMode !== PageRepository::SHORTCUT_MODE_RANDOM_SUBPAGE) { $view->assignMultiple(['title' => $this->pageinfo['title'], 'message' => $lang->getLL('pageIsMisconfiguredInternalLinkMessage'), 'state' => InfoboxViewHelper::STATE_ERROR]); $content .= $view->render(); } } } elseif ($this->pageinfo['doktype'] === PageRepository::DOKTYPE_LINK) { if (empty($this->pageinfo['url'])) { $view->assignMultiple(['title' => $this->pageinfo['title'], 'message' => $lang->getLL('pageIsMisconfiguredExternalLinkMessage'), 'state' => InfoboxViewHelper::STATE_ERROR]); $content .= $view->render(); } else { $externalUrl = htmlspecialchars(GeneralUtility::makeInstance(PageRepository::class)->getExtURL($this->pageinfo)); if ($externalUrl !== false) { $externalUrlHtml = '<a href="' . $externalUrl . '" target="_blank" rel="noopener">' . $externalUrl . '</a>'; $view->assignMultiple(['title' => $this->pageinfo['title'], 'message' => sprintf($lang->getLL('pageIsExternalLinkMessage'), $externalUrlHtml), 'state' => InfoboxViewHelper::STATE_INFO]); $content .= $view->render(); } } } // If content from different pid is displayed if ($this->pageinfo['content_from_pid']) { $contentPage = BackendUtility::getRecord('pages', (int) $this->pageinfo['content_from_pid']); $linkToPid = $this->local_linkThisScript(['id' => $this->pageinfo['content_from_pid']]); $title = BackendUtility::getRecordTitle('pages', $contentPage); $link = '<a href="' . $linkToPid . '">' . htmlspecialchars($title) . ' (PID ' . (int) $this->pageinfo['content_from_pid'] . ')</a>'; $message = sprintf($lang->getLL('content_from_pid_title'), $link); $view->assignMultiple(['title' => $title, 'message' => $message, 'state' => InfoboxViewHelper::STATE_INFO]); $content .= $view->render(); } return $content; }
/** * shows user's info and categories * * @return string HTML showing user's info and the categories */ function cmd_displayUserInfo() { $uid = intval(GeneralUtility::_GP('uid')); $indata = GeneralUtility::_GP('indata'); $table = GeneralUtility::_GP('table'); $mm_table = $GLOBALS["TCA"][$table]['columns']['module_sys_dmail_category']['config']['MM']; if (GeneralUtility::_GP('submit')) { $indata = GeneralUtility::_GP('indata'); if (!$indata) { $indata['html'] = 0; } } switch ($table) { case 'tt_address': case 'fe_users': if (is_array($indata)) { $data = array(); if (is_array($indata['categories'])) { reset($indata['categories']); foreach ($indata["categories"] as $recValues) { $enabled = array(); while (list($k, $b) = each($recValues)) { if ($b) { $enabled[] = $k; } } $data[$table][$uid]['module_sys_dmail_category'] = implode(',', $enabled); } } $data[$table][$uid]['module_sys_dmail_html'] = $indata['html'] ? 1 : 0; /** @var $tce \TYPO3\CMS\Core\DataHandling\DataHandler */ $tce = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler'); $tce->stripslashes_values = 0; $tce->start($data, array()); $tce->process_datamap(); } break; } switch ($table) { case 'tt_address': $res = $GLOBALS["TYPO3_DB"]->exec_SELECTquery('tt_address.*', 'tt_address LEFT JOIN pages ON pages.uid=tt_address.pid', 'tt_address.uid=' . intval($uid) . ' AND ' . $this->perms_clause . BackendUtility::deleteClause('pages') . BackendUtility::BEenableFields('tt_address') . BackendUtility::deleteClause('tt_address')); break; case 'fe_users': $res = $GLOBALS["TYPO3_DB"]->exec_SELECTquery('fe_users.*', 'fe_users LEFT JOIN pages ON pages.uid=fe_users.pid', 'fe_users.uid=' . intval($uid) . ' AND ' . $this->perms_clause . BackendUtility::deleteClause('pages') . BackendUtility::BEenableFields('fe_users') . BackendUtility::deleteClause('fe_users')); break; } $row = array(); if ($res) { $row = $GLOBALS["TYPO3_DB"]->sql_fetch_assoc($res); $GLOBALS["TYPO3_DB"]->sql_free_result($res); } $theOutput = ""; if (is_array($row)) { $row_categories = ''; $resCat = $GLOBALS["TYPO3_DB"]->exec_SELECTquery('uid_foreign', $mm_table, 'uid_local=' . $row['uid']); while ($rowCat = $GLOBALS["TYPO3_DB"]->sql_fetch_assoc($resCat)) { $row_categories .= $rowCat['uid_foreign'] . ','; } $row_categories = rtrim($row_categories, ","); $GLOBALS["TYPO3_DB"]->sql_free_result($resCat); $Eparams = '&edit[' . $table . '][' . $row['uid'] . ']=edit'; $out = ''; $out .= IconUtility::getSpriteIconForRecord($table, $row, array('title' => BackendUtility::getRecordPath($row['pid'], $this->perms_clause, 40))) . htmlspecialchars($row['name'] . ' <' . $row['email'] . '>'); $out .= ' <a href="#" onClick="' . BackendUtility::editOnClick($Eparams, $GLOBALS["BACK_PATH"], '') . '"><img' . IconUtility::skinImg($GLOBALS["BACK_PATH"], 'gfx/edit2.gif', 'width="12" height="12"') . ' alt="' . $GLOBALS["LANG"]->getLL("dmail_edit") . '" width="12" height="12" style="margin: 2px 3px; vertical-align:top;" title="' . $GLOBALS["LANG"]->getLL("dmail_edit") . '" /><b>' . $GLOBALS["LANG"]->getLL('dmail_edit') . '</b></a>'; $theOutput = $this->doc->section($GLOBALS["LANG"]->getLL('subscriber_info'), $out); $out = ''; $out_check = ''; $this->categories = DirectMailUtility::makeCategories($table, $row, $this->sys_language_uid); foreach ($this->categories as $pKey => $pVal) { $out_check .= '<input type="hidden" name="indata[categories][' . $row['uid'] . '][' . $pKey . ']" value="0" /><input type="checkbox" name="indata[categories][' . $row['uid'] . '][' . $pKey . ']" value="1"' . (GeneralUtility::inList($row_categories, $pKey) ? ' checked="checked"' : '') . ' /> ' . htmlspecialchars($pVal) . '<br />'; } $out_check .= '<br /><br /><input type="checkbox" name="indata[html]" value="1"' . ($row['module_sys_dmail_html'] ? ' checked="checked"' : '') . ' /> '; $out_check .= $GLOBALS["LANG"]->getLL('subscriber_profile_htmlemail') . '<br />'; $out .= $out_check; $out .= '<input type="hidden" name="table" value="' . $table . '" /><input type="hidden" name="uid" value="' . $uid . '" /><input type="hidden" name="CMD" value="' . $this->CMD . '" /><br /><input type="submit" name="submit" value="' . htmlspecialchars($GLOBALS["LANG"]->getLL('subscriber_profile_update')) . '" />'; $theOutput .= $this->doc->spacer(20); $theOutput .= $this->doc->section($GLOBALS["LANG"]->getLL('subscriber_profile'), $GLOBALS["LANG"]->getLL('subscriber_profile_instructions') . '<br /><br />' . $out); } return $theOutput; }
/** * @param array $arr * @param string $depthData * @param array $keyArray * @param int $first * @return array */ public function ext_getTemplateHierarchyArr($arr, $depthData, $keyArray, $first = 0) { $keyArr = []; foreach ($arr as $key => $value) { $key = preg_replace('/\\.$/', '', $key); if (substr($key, -1) != '.') { $keyArr[$key] = 1; } } $a = 0; $c = count($keyArr); /** @var IconFactory $iconFactory */ $iconFactory = GeneralUtility::makeInstance(IconFactory::class); foreach ($keyArr as $key => $value) { $HTML = ''; $a++; $deeper = is_array($arr[$key . '.']); $row = $arr[$key]; $LN = $a == $c ? 'blank' : 'line'; $BTM = $a == $c ? 'top' : ''; $HTML .= $depthData; $alttext = '[' . $row['templateID'] . ']'; $alttext .= $row['pid'] ? ' - ' . BackendUtility::getRecordPath($row['pid'], $GLOBALS['SOBE']->perms_clause, 20) : ''; $icon = substr($row['templateID'], 0, 3) === 'sys' ? '<span title="' . htmlspecialchars($alttext) . '">' . $iconFactory->getIconForRecord('sys_template', $row, Icon::SIZE_SMALL)->render() . '</span>' : '<span title="' . htmlspecialchars($alttext) . '">' . $iconFactory->getIcon('mimetypes-x-content-template-static', Icon::SIZE_SMALL)->render() . '</span>'; if (in_array($row['templateID'], $this->clearList_const) || in_array($row['templateID'], $this->clearList_setup)) { $urlParameters = ['id' => $GLOBALS['SOBE']->id, 'template' => $row['templateID']]; $aHref = BackendUtility::getModuleUrl('web_ts', $urlParameters); $A_B = '<a href="' . htmlspecialchars($aHref) . '">'; $A_E = '</a>'; if (GeneralUtility::_GP('template') == $row['templateID']) { $A_B = '<strong>' . $A_B; $A_E .= '</strong>'; } } else { $A_B = ''; $A_E = ''; } $HTML .= ($first ? '' : '<span class="treeline-icon treeline-icon-join' . $BTM . '"></span>') . $icon . ' ' . $A_B . htmlspecialchars(GeneralUtility::fixed_lgd_cs($row['title'], $GLOBALS['BE_USER']->uc['titleLen'])) . $A_E . ' '; $RL = $this->ext_getRootlineNumber($row['pid']); $statusCheckedIcon = $iconFactory->getIcon('status-status-checked', Icon::SIZE_SMALL)->render(); $keyArray[] = '<tr> <td nowrap="nowrap">' . $HTML . '</td> <td align="center">' . ($row['root'] ? $statusCheckedIcon : '') . '</td> <td align="center">' . ($row['clConf'] ? $statusCheckedIcon : '') . '</td> <td align="center">' . ($row['clConst'] ? $statusCheckedIcon : '') . '</td> <td align="center">' . ($row['pid'] ?: '') . '</td> <td align="center">' . ($RL >= 0 ? $RL : '') . '</td> <td>' . ($row['next'] ? $row['next'] : '') . '</td> </tr>'; if ($deeper) { $keyArray = $this->ext_getTemplateHierarchyArr($arr[$key . '.'], $depthData . ($first ? '' : '<span class="treeline-icon treeline-icon-' . $LN . '"></span>'), $keyArray); } } return $keyArray; }
/** * @param array $arguments * @param \Closure $renderChildrenClosure * @param RenderingContextInterface $renderingContext * * @return string */ public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext) { return BackendUtility::getRecordPath($arguments['pid'], '', $arguments['titleLimit']); }
/** * Return record path (visually formatted, using BackendUtility::getRecordPath() ) * * @param string $table Table name * @param array $rec Record array * @return string The record path. * @see BackendUtility::getRecordPath() * @todo Define visibility */ public function getRecordPath($table, $rec) { BackendUtility::fixVersioningPid($table, $rec); list($tscPID, $thePidValue) = $this->getTSCpid($table, $rec['uid'], $rec['pid']); if ($thePidValue >= 0) { return BackendUtility::getRecordPath($tscPID, $this->readPerms(), 15); } return ''; }
/** * Fetch further information to current selected workspace record. * * @param \stdClass $parameter * @return array $data */ public function getRowDetails($parameter) { $diffReturnArray = []; $liveReturnArray = []; $diffUtility = $this->getDifferenceHandler(); /** @var $parseObj RteHtmlParser */ $parseObj = GeneralUtility::makeInstance(RteHtmlParser::class); $liveRecord = BackendUtility::getRecord($parameter->table, $parameter->t3ver_oid); $versionRecord = BackendUtility::getRecord($parameter->table, $parameter->uid); $iconFactory = GeneralUtility::makeInstance(IconFactory::class); $icon_Live = $iconFactory->getIconForRecord($parameter->table, $liveRecord, Icon::SIZE_SMALL)->render(); $icon_Workspace = $iconFactory->getIconForRecord($parameter->table, $versionRecord, Icon::SIZE_SMALL)->render(); $stagesService = $this->getStagesService(); $stagePosition = $stagesService->getPositionOfCurrentStage($parameter->stage); $fieldsOfRecords = array_keys($liveRecord); if ($GLOBALS['TCA'][$parameter->table]) { if ($GLOBALS['TCA'][$parameter->table]['interface']['showRecordFieldList']) { $fieldsOfRecords = $GLOBALS['TCA'][$parameter->table]['interface']['showRecordFieldList']; $fieldsOfRecords = GeneralUtility::trimExplode(',', $fieldsOfRecords, true); } } foreach ($fieldsOfRecords as $fieldName) { if (empty($GLOBALS['TCA'][$parameter->table]['columns'][$fieldName]['config'])) { continue; } // Get the field's label. If not available, use the field name $fieldTitle = $this->getLanguageService()->sL(BackendUtility::getItemLabel($parameter->table, $fieldName)); if (empty($fieldTitle)) { $fieldTitle = $fieldName; } // Gets the TCA configuration for the current field $configuration = $GLOBALS['TCA'][$parameter->table]['columns'][$fieldName]['config']; // check for exclude fields if ($this->getBackendUser()->isAdmin() || $GLOBALS['TCA'][$parameter->table]['columns'][$fieldName]['exclude'] == 0 || GeneralUtility::inList($this->getBackendUser()->groupData['non_exclude_fields'], $parameter->table . ':' . $fieldName)) { // call diff class only if there is a difference if ($configuration['type'] === 'inline' && $configuration['foreign_table'] === 'sys_file_reference') { $useThumbnails = false; if (!empty($configuration['foreign_selector_fieldTcaOverride']['config']['appearance']['elementBrowserAllowed']) && !empty($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'])) { $fileExtensions = GeneralUtility::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], true); $allowedExtensions = GeneralUtility::trimExplode(',', $configuration['foreign_selector_fieldTcaOverride']['config']['appearance']['elementBrowserAllowed'], true); $differentExtensions = array_diff($allowedExtensions, $fileExtensions); $useThumbnails = empty($differentExtensions); } $liveFileReferences = BackendUtility::resolveFileReferences($parameter->table, $fieldName, $liveRecord, 0); $versionFileReferences = BackendUtility::resolveFileReferences($parameter->table, $fieldName, $versionRecord, $this->getCurrentWorkspace()); $fileReferenceDifferences = $this->prepareFileReferenceDifferences($liveFileReferences, $versionFileReferences, $useThumbnails); if ($fileReferenceDifferences === null) { continue; } $diffReturnArray[] = ['field' => $fieldName, 'label' => $fieldTitle, 'content' => $fileReferenceDifferences['differences']]; $liveReturnArray[] = ['field' => $fieldName, 'label' => $fieldTitle, 'content' => $fileReferenceDifferences['live']]; } elseif ((string) $liveRecord[$fieldName] !== (string) $versionRecord[$fieldName]) { // Select the human readable values before diff $liveRecord[$fieldName] = BackendUtility::getProcessedValue($parameter->table, $fieldName, $liveRecord[$fieldName], 0, 1, false, $liveRecord['uid']); $versionRecord[$fieldName] = BackendUtility::getProcessedValue($parameter->table, $fieldName, $versionRecord[$fieldName], 0, 1, false, $versionRecord['uid']); if ($configuration['type'] == 'group' && $configuration['internal_type'] == 'file') { $versionThumb = BackendUtility::thumbCode($versionRecord, $parameter->table, $fieldName, ''); $liveThumb = BackendUtility::thumbCode($liveRecord, $parameter->table, $fieldName, ''); $diffReturnArray[] = ['field' => $fieldName, 'label' => $fieldTitle, 'content' => $versionThumb]; $liveReturnArray[] = ['field' => $fieldName, 'label' => $fieldTitle, 'content' => $liveThumb]; } else { $diffReturnArray[] = ['field' => $fieldName, 'label' => $fieldTitle, 'content' => $diffUtility->makeDiffDisplay($liveRecord[$fieldName], $versionRecord[$fieldName])]; $liveReturnArray[] = ['field' => $fieldName, 'label' => $fieldTitle, 'content' => $parseObj->TS_images_rte($liveRecord[$fieldName])]; } } } } // Hook for modifying the difference and live arrays // (this may be used by custom or dynamically-defined fields) if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['workspaces']['modifyDifferenceArray'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['workspaces']['modifyDifferenceArray'] as $className) { $hookObject = GeneralUtility::getUserObj($className); if (method_exists($hookObject, 'modifyDifferenceArray')) { $hookObject->modifyDifferenceArray($parameter, $diffReturnArray, $liveReturnArray, $diffUtility); } } } $commentsForRecord = $this->getCommentsForRecord($parameter->uid, $parameter->table); /** @var $historyService HistoryService */ $historyService = GeneralUtility::makeInstance(HistoryService::class); $history = $historyService->getHistory($parameter->table, $parameter->t3ver_oid); $prevStage = $stagesService->getPrevStage($parameter->stage); $nextStage = $stagesService->getNextStage($parameter->stage); if (isset($prevStage[0])) { $prevStage = current($prevStage); } if (isset($nextStage[0])) { $nextStage = current($nextStage); } return ['total' => 1, 'data' => [['diff' => $diffReturnArray, 'live_record' => $liveReturnArray, 'icon_Live' => $icon_Live, 'icon_Workspace' => $icon_Workspace, 'comments' => $commentsForRecord, 'path_Live' => htmlspecialchars(BackendUtility::getRecordPath($liveRecord['pid'], '', 999)), 'label_Stage' => htmlspecialchars($stagesService->getStageTitle($parameter->stage)), 'label_PrevStage' => $prevStage, 'label_NextStage' => $nextStage, 'stage_position' => (int) $stagePosition['position'], 'stage_count' => (int) $stagePosition['count'], 'parent' => ['table' => htmlspecialchars($parameter->table), 'uid' => (int) $parameter->uid], 'history' => ['data' => $history, 'total' => count($history)]]]]; }
/** * Deleting files and folders (action=4) * * @param array $cmds $cmds['data'] is the file/folder to delete * @return boolean Returns TRUE upon success * @todo Define visibility */ public function func_delete($cmds) { $result = FALSE; if (!$this->isInit) { return $result; } // Example indentifier for $cmds['data'] => "4:mypath/tomyfolder/myfile.jpg" // for backwards compatibility: the combined file identifier was the path+filename $fileObject = $this->getFileObject($cmds['data']); // @todo implement the recycler feature which has been removed from the original implementation // checks to delete the file if ($fileObject instanceof File) { // check if the file still has references // Exclude sys_file_metadata records as these are no use references $refIndexRecords = $this->getDatabaseConnection()->exec_SELECTgetRows('*', 'sys_refindex', 'deleted=0 AND ref_table="sys_file" AND ref_uid=' . (int) $fileObject->getUid() . ' AND tablename != "sys_file_metadata"'); if (count($refIndexRecords) > 0) { $shortcutContent = array(); foreach ($refIndexRecords as $fileReferenceRow) { if ($fileReferenceRow['tablename'] === 'sys_file_reference') { $row = $this->transformFileReferenceToRecordReference($fileReferenceRow); $shortcutRecord = BackendUtility::getRecord($row['tablename'], $row['recuid']); $icon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord($row['tablename'], $shortcutRecord); $onClick = 'Clickmenu.show("' . $row['tablename'] . '", "' . $row['recuid'] . '", "1", "+info,history,edit", "|", "");return false;'; $shortcutContent[] = '<a href="#" oncontextmenu="this.click();return false;" onclick="' . htmlspecialchars($onClick) . '">' . $icon . '</a>' . htmlspecialchars(BackendUtility::getRecordTitle($row['tablename'], $shortcutRecord) . ' [' . BackendUtility::getRecordPath($shortcutRecord['pid'], '', 80) . ']'); } } // render a message that the file could not be deleted $flashMessage = GeneralUtility::makeInstance('\\TYPO3\\CMS\\Core\\Messaging\\FlashMessage', sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.description.fileNotDeletedHasReferences'), $fileObject->getName()) . '<br />' . implode('<br />', $shortcutContent), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.header.fileNotDeletedHasReferences'), \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING, TRUE); $this->addFlashMessage($flashMessage); } else { try { $result = $fileObject->delete(); // show the user that the file was deleted $flashMessage = GeneralUtility::makeInstance('\\TYPO3\\CMS\\Core\\Messaging\\FlashMessage', sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.description.fileDeleted'), $fileObject->getName()), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.header.fileDeleted'), \TYPO3\CMS\Core\Messaging\FlashMessage::OK, TRUE); $this->addFlashMessage($flashMessage); // Log success $this->writelog(4, 0, 1, 'File "%s" deleted', array($fileObject->getIdentifier())); } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException $e) { $this->writelog(4, 1, 112, 'You are not allowed to access the file', array($fileObject->getIdentifier())); } catch (\TYPO3\CMS\Core\Resource\Exception\NotInMountPointException $e) { $this->writelog(4, 1, 111, 'Target was not within your mountpoints! T="%s"', array($fileObject->getIdentifier())); } catch (\RuntimeException $e) { $this->writelog(4, 1, 110, 'Could not delete file "%s". Write-permission problem?', array($fileObject->getIdentifier())); } } } else { try { /** @var $fileObject \TYPO3\CMS\Core\Resource\FolderInterface */ if ($fileObject->getFileCount() > 0) { // render a message that the folder could not be deleted because it still contains files $flashMessage = GeneralUtility::makeInstance('\\TYPO3\\CMS\\Core\\Messaging\\FlashMessage', sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.description.folderNotDeletedHasFiles'), $fileObject->getName()), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.header.folderNotDeletedHasFiles'), \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING, TRUE); $this->addFlashMessage($flashMessage); } else { $result = $fileObject->delete(TRUE); // notify the user that the folder was deleted $flashMessage = GeneralUtility::makeInstance('\\TYPO3\\CMS\\Core\\Messaging\\FlashMessage', sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.description.folderDeleted'), $fileObject->getName()), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.header.folderDeleted'), \TYPO3\CMS\Core\Messaging\FlashMessage::OK, TRUE); $this->addFlashMessage($flashMessage); // Log success $this->writelog(4, 0, 3, 'Directory "%s" deleted', array($fileObject->getIdentifier())); } } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException $e) { $this->writelog(4, 1, 123, 'You are not allowed to access the directory', array($fileObject->getIdentifier())); } catch (\TYPO3\CMS\Core\Resource\Exception\NotInMountPointException $e) { $this->writelog(4, 1, 121, 'Target was not within your mountpoints! T="%s"', array($fileObject->getIdentifier())); } catch (\RuntimeException $e) { $this->writelog(4, 1, 120, 'Could not delete directory! Write-permission problem? Is directory "%s" empty? (You are not allowed to delete directories recursively).', array($fileObject->getIdentifier())); } } return $result; }
/** * This will render a selector box into which elements from either * the file system or database can be inserted. Relations. * * @return array As defined in initializeResultArray() of AbstractNode */ public function render() { $table = $this->globalOptions['table']; $fieldName = $this->globalOptions['fieldName']; $row = $this->globalOptions['databaseRow']; $parameterArray = $this->globalOptions['parameterArray']; $config = $parameterArray['fieldConf']['config']; $show_thumbs = $config['show_thumbs']; $resultArray = $this->initializeResultArray(); $size = isset($config['size']) ? (int)$config['size'] : $this->minimumInputWidth; $maxitems = MathUtility::forceIntegerInRange($config['maxitems'], 0); if (!$maxitems) { $maxitems = 100000; } $minitems = MathUtility::forceIntegerInRange($config['minitems'], 0); $thumbnails = array(); $allowed = GeneralUtility::trimExplode(',', $config['allowed'], TRUE); $disallowed = GeneralUtility::trimExplode(',', $config['disallowed'], TRUE); $disabled = ($this->isGlobalReadonly() || $config['readOnly']); $info = array(); $parameterArray['itemFormElID_file'] = $parameterArray['itemFormElID'] . '_files'; // whether the list and delete controls should be disabled $noList = isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'list'); $noDelete = isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'delete'); // "Extra" configuration; Returns configuration for the field based on settings found in the "types" fieldlist. $specConf = BackendUtility::getSpecConfParts($parameterArray['fieldConf']['defaultExtras']); // Register properties in requiredElements $resultArray['requiredElements'][$parameterArray['itemFormElName']] = array( $minitems, $maxitems, 'imgName' => $table . '_' . $row['uid'] . '_' . $fieldName ); $tabAndInlineStack = $this->globalOptions['tabAndInlineStack']; if (!empty($tabAndInlineStack) && preg_match('/^(.+\\])\\[(\\w+)\\]$/', $parameterArray['itemFormElName'], $match)) { array_shift($match); $resultArray['requiredNested'][$parameterArray['itemFormElName']] = array( 'parts' => $match, 'level' => $tabAndInlineStack, ); } // If maxitems==1 then automatically replace the current item (in list and file selector) if ($maxitems === 1) { $resultArray['additionalJavaScriptPost'][] = 'TBE_EDITOR.clearBeforeSettingFormValueFromBrowseWin[' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName']) . '] = { itemFormElID_file: ' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElID_file']) . ' }'; $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = 'setFormValueManipulate(' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName']) . ', \'Remove\'); ' . $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged']; } elseif ($noList) { // If the list controls have been removed and the maximum number is reached, remove the first entry to avoid "write once" field $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged'] = 'setFormValueManipulate(' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName']) . ', \'RemoveFirstIfFull\', ' . GeneralUtility::quoteJSvalue($maxitems) . '); ' . $parameterArray['fieldChangeFunc']['TBE_EDITOR_fieldChanged']; } $html = '<input type="hidden" name="' . $parameterArray['itemFormElName'] . '_mul" value="' . ($config['multiple'] ? 1 : 0) . '"' . $disabled . ' />'; // Acting according to either "file" or "db" type: switch ((string)$config['internal_type']) { case 'file_reference': $config['uploadfolder'] = ''; // Fall through case 'file': // Creating string showing allowed types: if (!count($allowed)) { $allowed = array('*'); } // Making the array of file items: $itemArray = GeneralUtility::trimExplode(',', $parameterArray['itemFormElValue'], TRUE); $fileFactory = ResourceFactory::getInstance(); // Correct the filename for the FAL items foreach ($itemArray as &$fileItem) { list($fileUid, $fileLabel) = explode('|', $fileItem); if (MathUtility::canBeInterpretedAsInteger($fileUid)) { $fileObject = $fileFactory->getFileObject($fileUid); $fileLabel = $fileObject->getName(); } $fileItem = $fileUid . '|' . $fileLabel; } // Showing thumbnails: if ($show_thumbs) { foreach ($itemArray as $imgRead) { $imgP = explode('|', $imgRead); $imgPath = rawurldecode($imgP[0]); // FAL icon production if (MathUtility::canBeInterpretedAsInteger($imgP[0])) { $fileObject = $fileFactory->getFileObject($imgP[0]); if ($fileObject->isMissing()) { $thumbnails[] = array( 'message' => \TYPO3\CMS\Core\Resource\Utility\BackendUtility::getFlashMessageForMissingFile($fileObject)->render() ); } elseif (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileObject->getExtension())) { $thumbnails[] = array( 'name' => htmlspecialchars($fileObject->getName()), 'image' => $fileObject->process(ProcessedFile::CONTEXT_IMAGEPREVIEW, array())->getPublicUrl(TRUE) ); } else { // Icon $thumbnails[] = array( 'name' => htmlspecialchars($fileObject->getName()), 'image' => IconUtility::getSpriteIconForResource($fileObject, array('title' => $fileObject->getName())) ); } } else { $rowCopy = array(); $rowCopy[$fieldName] = $imgPath; try { $thumbnails[] = array( 'name' => $imgPath, 'image' => BackendUtility::thumbCode( $rowCopy, $table, $fieldName, '', '', $config['uploadfolder'], 0, ' align="middle"' ) ); } catch (\Exception $exception) { /** @var $flashMessage FlashMessage */ $message = $exception->getMessage(); $flashMessage = GeneralUtility::makeInstance( FlashMessage::class, htmlspecialchars($message), '', FlashMessage::ERROR, TRUE ); /** @var $flashMessageService FlashMessageService */ $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class); $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier(); $defaultFlashMessageQueue->enqueue($flashMessage); $logMessage = $message . ' (' . $table . ':' . $row['uid'] . ')'; GeneralUtility::sysLog($logMessage, 'core', GeneralUtility::SYSLOG_SEVERITY_WARNING); } } } } // Creating the element: $params = array( 'size' => $size, 'allowed' => $allowed, 'disallowed' => $disallowed, 'dontShowMoveIcons' => $maxitems <= 1, 'autoSizeMax' => MathUtility::forceIntegerInRange($config['autoSizeMax'], 0), 'maxitems' => $maxitems, 'style' => isset($config['selectedListStyle']) ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"' : '', 'thumbnails' => $thumbnails, 'readOnly' => $disabled, 'noBrowser' => $noList || isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'browser'), 'noList' => $noList, 'noDelete' => $noDelete ); $html .= $this->dbFileIcons( $parameterArray['itemFormElName'], 'file', implode(',', $allowed), $itemArray, '', $params, $parameterArray['onFocus'], '', '', '', $config); if (!$disabled && !(isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'upload'))) { // Adding the upload field: $isDirectFileUploadEnabled = (bool)$this->getBackendUserAuthentication()->uc['edit_docModuleUpload']; if ($isDirectFileUploadEnabled && $config['uploadfolder']) { // Insert the multiple attribute to enable HTML5 multiple file upload $multipleAttribute = ''; $multipleFilenameSuffix = ''; if (isset($config['maxitems']) && $config['maxitems'] > 1) { $multipleAttribute = ' multiple="multiple"'; $multipleFilenameSuffix = '[]'; } $html .= ' <div id="' . $parameterArray['itemFormElID_file'] . '"> <input type="file"' . $multipleAttribute . ' name="data_files' . $this->globalOptions['elementBaseName'] . $multipleFilenameSuffix . '" size="35" onchange="' . implode('', $parameterArray['fieldChangeFunc']) . '" /> </div>'; } } break; case 'folder': // If the element is of the internal type "folder": // Array of folder items: $itemArray = GeneralUtility::trimExplode(',', $parameterArray['itemFormElValue'], TRUE); // Creating the element: $params = array( 'size' => $size, 'dontShowMoveIcons' => $maxitems <= 1, 'autoSizeMax' => MathUtility::forceIntegerInRange($config['autoSizeMax'], 0), 'maxitems' => $maxitems, 'style' => isset($config['selectedListStyle']) ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"' : '', 'readOnly' => $disabled, 'noBrowser' => $noList || isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'browser'), 'noList' => $noList ); $html .= $this->dbFileIcons( $parameterArray['itemFormElName'], 'folder', '', $itemArray, '', $params, $parameterArray['onFocus'] ); break; case 'db': // If the element is of the internal type "db": // Creating string showing allowed types: $onlySingleTableAllowed = FALSE; $languageService = $this->getLanguageService(); $allowedTables = array(); if ($allowed[0] === '*') { $allowedTables = array( 'name' => htmlspecialchars($languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.allTables')) ); } elseif ($allowed) { $onlySingleTableAllowed = count($allowed) == 1; foreach ($allowed as $allowedTable) { $allowedTables[] = array( 'name' => htmlspecialchars($languageService->sL($GLOBALS['TCA'][$allowedTable]['ctrl']['title'])), 'icon' => IconUtility::getSpriteIconForRecord($allowedTable, array()), 'onClick' => 'setFormValueOpenBrowser(\'db\', ' . GeneralUtility::quoteJSvalue($parameterArray['itemFormElName'] . '|||' . $allowedTable) . '); return false;' ); } } $perms_clause = $this->getBackendUserAuthentication()->getPagePermsClause(1); $itemArray = array(); // Thumbnails: $temp_itemArray = GeneralUtility::trimExplode(',', $parameterArray['itemFormElValue'], TRUE); foreach ($temp_itemArray as $dbRead) { $recordParts = explode('|', $dbRead); list($this_table, $this_uid) = BackendUtility::splitTable_Uid($recordParts[0]); // For the case that no table was found and only a single table is defined to be allowed, use that one: if (!$this_table && $onlySingleTableAllowed) { $this_table = $allowed; } $itemArray[] = array('table' => $this_table, 'id' => $this_uid); if (!$disabled && $show_thumbs) { $rr = BackendUtility::getRecordWSOL($this_table, $this_uid); $thumbnails[] = array( 'name' => BackendUtility::getRecordTitle($this_table, $rr, TRUE), 'image' => IconUtility::getSpriteIconForRecord($this_table, $rr), 'path' => BackendUtility::getRecordPath($rr['pid'], $perms_clause, 15), 'uid' => $rr['uid'], 'table' => $this_table ); } } // Creating the element: $params = array( 'size' => $size, 'dontShowMoveIcons' => $maxitems <= 1, 'autoSizeMax' => MathUtility::forceIntegerInRange($config['autoSizeMax'], 0), 'maxitems' => $maxitems, 'style' => isset($config['selectedListStyle']) ? ' style="' . htmlspecialchars($config['selectedListStyle']) . '"' : '', 'info' => $info, 'allowedTables' => $allowedTables, 'thumbnails' => $thumbnails, 'readOnly' => $disabled, 'noBrowser' => $noList || isset($config['disable_controls']) && GeneralUtility::inList($config['disable_controls'], 'browser'), 'noList' => $noList ); $html .= $this->dbFileIcons( $parameterArray['itemFormElName'], 'db', implode(',', $allowed), $itemArray, '', $params, $parameterArray['onFocus'], $table, $fieldName, $row['uid'], $config ); break; } // Wizards: $altItem = '<input type="hidden" name="' . $parameterArray['itemFormElName'] . '" value="' . htmlspecialchars($parameterArray['itemFormElValue']) . '" />'; if (!$disabled) { $html = $this->renderWizards( array( $html, $altItem ), $config['wizards'], $table, $row, $fieldName, $parameterArray, $parameterArray['itemFormElName'], $specConf ); } $resultArray['html'] = $html; return $resultArray; }
public function readPageAccess($id, $perms_clause) { if ((string) $id != '') { $id = intval($id); if (!$id) { if ($GLOBALS['BE_USER']->isAdmin()) { $path = '/'; $pageinfo['_thePath'] = $path; return $pageinfo; } } else { $pageinfo = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord('pages', $id, '*', $perms_clause ? ' AND ' . $perms_clause : ''); if ($pageinfo['uid'] && $GLOBALS['BE_USER']->isInWebMount($id, $perms_clause)) { \TYPO3\CMS\Backend\Utility\BackendUtility::workspaceOL('pages', $pageinfo); \TYPO3\CMS\Backend\Utility\BackendUtility::fixVersioningPid('pages', $pageinfo); list($pageinfo['_thePath'], $pageinfo['_thePathFull']) = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath(intval($pageinfo['uid']), $perms_clause, 15, 1000); return $pageinfo; } } } return false; }
/** * Entry method * * @return array As defined in initializeResultArray() of AbstractNode */ public function render() { $languageService = $this->getLanguageService(); $backendUser = $this->getBackendUserAuthentication(); $table = $this->data['tableName']; $row = $this->data['databaseRow']; $options = $this->data; if (empty($this->data['fieldListToRender'])) { $options['renderType'] = 'fullRecordContainer'; } else { $options['renderType'] = 'listOfFieldsContainer'; } $result = $this->nodeFactory->create($options)->render(); $childHtml = $result['html']; $recordPath = ''; // @todo: what is this >= 0 check for? wsol cases?! if ($this->data['effectivePid'] >= 0) { $permissionsClause = $backendUser->getPagePermsClause(1); $recordPath = BackendUtility::getRecordPath($this->data['effectivePid'], $permissionsClause, 15); } $iconFactory = GeneralUtility::makeInstance(IconFactory::class); $icon = '<span title="' . htmlspecialchars($recordPath) . '">' . $iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render() . '</span>'; // @todo: Could this be done in a more clever way? Does it work at all? $tableTitle = $languageService->sL($this->data['processedTca']['ctrl']['title']); if ($this->data['command'] === 'new') { $newOrUid = ' <span class="typo3-TCEforms-newToken">' . $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.new', true) . '</span>'; // @todo: There is quite some stuff do to for WS overlays ... $workspacedPageRecord = BackendUtility::getRecordWSOL('pages', $this->data['effectivePid'], 'title'); $pageTitle = BackendUtility::getRecordTitle('pages', $workspacedPageRecord, true, false); if ($table === 'pages') { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.createNewPage', true); $pageTitle = sprintf($label, $tableTitle); } else { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.createNewRecord', true); if ($this->data['effectivePid'] === 0) { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.createNewRecordRootLevel', true); } $pageTitle = sprintf($label, $tableTitle, $pageTitle); } } else { $icon = BackendUtility::wrapClickMenuOnIcon($icon, $table, $row['uid'], 1, '', '+copy,info,edit,view'); $newOrUid = ' <span class="typo3-TCEforms-recUid">[' . htmlspecialchars($row['uid']) . ']</span>'; // @todo: getRecordTitlePrep applies an htmlspecialchars here $recordLabel = BackendUtility::getRecordTitlePrep($this->data['recordTitle']); if ($table === 'pages') { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.editPage', true); $pageTitle = sprintf($label, $tableTitle, $recordLabel); } else { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.editRecord', true); $workspacedPageRecord = BackendUtility::getRecordWSOL('pages', $row['pid'], 'uid,title'); $pageTitle = BackendUtility::getRecordTitle('pages', $workspacedPageRecord, true, false); if (empty($recordLabel)) { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.editRecordNoTitle', true); } if ($this->data['effectivePid'] === 0) { $label = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:labels.editRecordRootLevel', true); } if (!empty($recordLabel)) { // Use record title and prepend an edit label. $pageTitle = sprintf($label, $tableTitle, $recordLabel, $pageTitle); } else { // Leave out the record title since it is not set. $pageTitle = sprintf($label, $tableTitle, $pageTitle); } } } $view = GeneralUtility::makeInstance(StandaloneView::class); $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/OuterWrapContainer.html')); $descriptionColumn = !empty($this->data['processedTca']['ctrl']['descriptionColumn']) ? $this->data['processedTca']['ctrl']['descriptionColumn'] : null; if ($descriptionColumn !== null) { $title = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:labels.recordInformation'); $content = $this->data['databaseRow'][$descriptionColumn]; $view->assignMultiple(['infoBoxMessageTitle' => $title, 'infoBoxMessage' => $content]); } $view->assignMultiple(array('pageTitle' => $pageTitle, 'childHtml' => $childHtml, 'icon' => $icon, 'tableTitle' => $tableTitle, 'newOrUid' => $newOrUid)); $result['html'] = $view->render(); return $result; }
/** * Deleting files and folders (action=4) * * @param array $cmds $cmds['data'] is the file/folder to delete * @return boolean Returns TRUE upon success * @todo Define visibility */ public function func_delete($cmds) { $result = FALSE; if (!$this->isInit) { return $result; } // Example indentifier for $cmds['data'] => "4:mypath/tomyfolder/myfile.jpg" // for backwards compatibility: the combined file identifier was the path+filename $fileObject = $this->getFileObject($cmds['data']); // @todo implement the recycler feature which has been removed from the original implementation // checks to delete the file if ($fileObject instanceof \TYPO3\CMS\Core\Resource\File) { $refIndexRecords = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_refindex', 'deleted=0 AND ref_table="sys_file" AND ref_uid=' . intval($fileObject->getUid())); // check if the file still has references if (count($refIndexRecords) > 0) { $shortcutContent = array(); foreach ($refIndexRecords as $row) { $shortcutRecord = NULL; $shortcutRecord = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord($row['tablename'], $row['recuid']); if (is_array($shortcutRecord) && $row['tablename'] !== 'sys_file_reference') { $icon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord($row['tablename'], $shortcutRecord); $onClick = 'showClickmenu("' . $row['tablename'] . '", "' . $row['recuid'] . '", "1", "+info,history,edit,delete", "|", "");return false;'; $shortcutContent[] = '<a href="#" oncontextmenu="' . htmlspecialchars($onClick) . '" onclick="' . htmlspecialchars($onClick) . '">' . $icon . '</a>' . htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::getRecordTitle($row['tablename'], $shortcutRecord) . ' [' . \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($shortcutRecord['pid'], '', 80) . ']'); } } $out = '<p>The file cannot be deleted since it is still used at the following places:<br />' . implode('<br />', $shortcutContent) . '</p>'; $flashMessage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('t3lib_flashMessage', $out, 'File not deleted', \TYPO3\CMS\Core\Messaging\FlashMessage::WARNING, TRUE); \TYPO3\CMS\Core\Messaging\FlashMessageQueue::addMessage($flashMessage); return; } else { try { $result = $fileObject->delete(); } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException $e) { $this->writelog(4, 1, 112, 'You are not allowed to access the file', array($fileObject->getIdentifier())); } catch (\TYPO3\CMS\Core\Resource\Exception\NotInMountPointException $e) { $this->writelog(4, 1, 111, 'Target was not within your mountpoints! T="%s"', array($fileObject->getIdentifier())); } catch (\RuntimeException $e) { $this->writelog(4, 1, 110, 'Could not delete file "%s". Write-permission problem?', array($fileObject->getIdentifier())); } // Log success $this->writelog(4, 0, 1, 'File "%s" deleted', array($fileObject->getIdentifier())); } } else { try { /** @var $fileObject \TYPO3\CMS\Core\Resource\FolderInterface */ $result = $fileObject->delete(TRUE); } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException $e) { $this->writelog(4, 1, 123, 'You are not allowed to access the directory', array($fileObject->getIdentifier())); } catch (\TYPO3\CMS\Core\Resource\Exception\NotInMountPointException $e) { $this->writelog(4, 1, 121, 'Target was not within your mountpoints! T="%s"', array($fileObject->getIdentifier())); } catch (\RuntimeException $e) { $this->writelog(4, 1, 120, 'Could not delete directory! Write-permission problem? Is directory "%s" empty? (You are not allowed to delete directories recursively).', array($fileObject->getIdentifier())); } // Log success $this->writelog(4, 0, 3, 'Directory "%s" deleted', array($fileObject->getIdentifier())); } return $result; }
/** * Displays one line of the broken links table * * @param string $table Name of database table * @param array $row Record row to be processed * @param array $brokenLinksItemTemplate Markup of the template to be used * @return string HTML of the rendered row */ protected function renderTableRow($table, array $row, $brokenLinksItemTemplate) { $markerArray = array(); $fieldName = ''; // Restore the linktype object $hookObj = $this->hookObjectsArr[$row['link_type']]; // Construct link to edit the content element $requestUri = GeneralUtility::getIndpEnv('REQUEST_URI') . '&id=' . $this->pObj->id . '&search_levels=' . $this->searchLevel; $actionLink = '<a href="#" onclick="'; $actionLink .= htmlspecialchars(BackendUtility::editOnClick('&edit[' . $table . '][' . $row['record_uid'] . ']=edit', '', $requestUri)); $actionLink .= '" title="' . $this->getLanguageService()->getLL('list.edit') . '">'; $actionLink .= IconUtility::getSpriteIcon('actions-document-open'); $actionLink .= '</a>'; $elementHeadline = $row['headline']; if (empty($elementHeadline)) { $elementHeadline = '<i>' . $this->getLanguageService()->getLL('list.no.headline') . '</i>'; } // Get the language label for the field from TCA if ($GLOBALS['TCA'][$table]['columns'][$row['field']]['label']) { $fieldName = $this->getLanguageService()->sL($GLOBALS['TCA'][$table]['columns'][$row['field']]['label']); // Crop colon from end if present if (substr($fieldName, '-1', '1') === ':') { $fieldName = substr($fieldName, '0', strlen($fieldName) - 1); } } // Fallback, if there is no label $fieldName = !empty($fieldName) ? $fieldName : $row['field']; // column "Element" $element = IconUtility::getSpriteIconForRecord($table, $row, array('title' => $table . ':' . $row['record_uid'])); $element .= $elementHeadline; $element .= ' ' . sprintf($this->getLanguageService()->getLL('list.field'), $fieldName); $markerArray['actionlink'] = $actionLink; $markerArray['path'] = BackendUtility::getRecordPath($row['record_pid'], '', 0, 0); $markerArray['element'] = $element; $markerArray['headlink'] = $row['link_title']; $markerArray['linktarget'] = $hookObj->getBrokenUrl($row); $response = unserialize($row['url_response']); if ($response['valid']) { $linkMessage = '<span class="valid">' . $this->getLanguageService()->getLL('list.msg.ok') . '</span>'; } else { $linkMessage = '<span class="error">' . $hookObj->getErrorMessage($response['errorParams']) . '</span>'; } $markerArray['linkmessage'] = $linkMessage; $lastRunDate = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $row['last_check']); $lastRunTime = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'], $row['last_check']); $markerArray['lastcheck'] = sprintf($this->getLanguageService()->getLL('list.msg.lastRun'), $lastRunDate, $lastRunTime); // Return the table html code as string return HtmlParser::substituteMarkerArray($brokenLinksItemTemplate, $markerArray, '###|###', TRUE, TRUE); }
/** * Main Task center module * * @return string HTML content. */ public function main() { $content = ''; $id = (int) GeneralUtility::_GP('display'); // If a preset is found, it is rendered using an iframe if ($id > 0) { $url = BackendUtility::getModuleUrl('xMOD_tximpexp', array('tx_impexp[action]' => 'export', 'preset[load]' => 1, 'preset[select]' => $id)); return $this->taskObject->urlInIframe($url); } else { // Header $lang = $this->getLanguageService(); $content .= $this->taskObject->description($lang->getLL('.alttitle'), $lang->getLL('.description')); $clause = $this->getBackendUser()->getPagePermsClause(1); $usernames = BackendUtility::getUserNames(); // Create preset links: $presets = $this->getPresets(); // If any presets found if (is_array($presets) && !empty($presets)) { $lines = []; foreach ($presets as $key => $presetCfg) { $configuration = unserialize($presetCfg['preset_data']); $title = strlen($presetCfg['title']) ? $presetCfg['title'] : '[' . $presetCfg['uid'] . ']'; $icon = 'EXT:impexp/Resources/Public/Images/export.gif'; $description = array(); // Is public? if ($presetCfg['public']) { $description[] = $lang->getLL('task.public') . ': ' . $lang->sL('LLL:EXT:lang/locallang_common.xlf:yes'); } // Owner $description[] = $lang->getLL('task.owner') . ': ' . ($presetCfg['user_uid'] === $GLOBALS['BE_USER']->user['uid'] ? $lang->getLL('task.own') : '[' . htmlspecialchars($usernames[$presetCfg['user_uid']]['username']) . ']'); // Page & path if ($configuration['pagetree']['id']) { $description[] = $lang->getLL('task.page') . ': ' . $configuration['pagetree']['id']; $description[] = $lang->getLL('task.path') . ': ' . htmlspecialchars(BackendUtility::getRecordPath($configuration['pagetree']['id'], $clause, 20)); } else { $description[] = $lang->getLL('single-record'); } // Meta information if ($configuration['meta']['title'] || $configuration['meta']['description'] || $configuration['meta']['notes']) { $metaInformation = ''; if ($configuration['meta']['title']) { $metaInformation .= '<strong>' . htmlspecialchars($configuration['meta']['title']) . '</strong><br />'; } if ($configuration['meta']['description']) { $metaInformation .= htmlspecialchars($configuration['meta']['description']); } if ($configuration['meta']['notes']) { $metaInformation .= '<br /><br /> <strong>' . $lang->getLL('notes') . ': </strong> <em>' . htmlspecialchars($configuration['meta']['notes']) . '</em>'; } $description[] = '<br />' . $metaInformation; } // Collect all preset information $lines[$key] = array('icon' => $icon, 'title' => $title, 'descriptionHtml' => implode('<br />', $description), 'link' => BackendUtility::getModuleUrl('user_task') . '&SET[function]=impexp.TYPO3\\CMS\\Impexp\\Task\\ImportExportTask&display=' . $presetCfg['uid']); } // Render preset list $content .= $this->taskObject->renderListMenu($lines); } else { // No presets found $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $lang->getLL('no-presets'), $lang->getLL('.alttitle'), FlashMessage::NOTICE); /** @var $flashMessageService \TYPO3\CMS\Core\Messaging\FlashMessageService */ $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class); /** @var $defaultFlashMessageQueue \TYPO3\CMS\Core\Messaging\FlashMessageQueue */ $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier(); $defaultFlashMessageQueue->enqueue($flashMessage); } } return $content; }
/** * Returns the page title path of a PID value. Results are cached internally * * @param integer $pid Record PID to check * @return string The path for the input PID * @todo Define visibility */ public function getRecordPath($pid) { if (!isset($this->cache_getRecordPath[$pid])) { $clause = $GLOBALS['BE_USER']->getPagePermsClause(1); $this->cache_getRecordPath[$pid] = (string) \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($pid, $clause, 20); } return $this->cache_getRecordPath[$pid]; }
/** * If "editPage" value is sent to script and it points to an accessible page, the internal var $this->theEditRec is set to the page record which should be loaded. * Returns void * * @return void * @todo Define visibility */ public function editPageIdFunc() { if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('cms')) { return; } // EDIT page: $this->editPage = trim($GLOBALS['LANG']->csConvObj->conv_case($GLOBALS['LANG']->charSet, $this->editPage, 'toLower')); $this->editError = ''; $this->theEditRec = ''; $this->searchFor = ''; if ($this->editPage) { // First, test alternative value consisting of [table]:[uid] and if not found, proceed with traditional page ID resolve: $this->alternativeTableUid = explode(':', $this->editPage); // We restrict it to admins only just because I'm not really sure if alt_doc.php properly // checks permissions of passed records for editing. If alt_doc.php does that, then we can remove this. if (!(count($this->alternativeTableUid) == 2 && $GLOBALS['BE_USER']->isAdmin())) { $where = ' AND (' . $GLOBALS['BE_USER']->getPagePermsClause(2) . ' OR ' . $GLOBALS['BE_USER']->getPagePermsClause(16) . ')'; if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($this->editPage)) { $this->theEditRec = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordWSOL('pages', $this->editPage, '*', $where); } else { $records = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordsByField('pages', 'alias', $this->editPage, $where); if (is_array($records)) { $this->theEditRec = reset($records); \TYPO3\CMS\Backend\Utility\BackendUtility::workspaceOL('pages', $this->theEditRec); } } if (!is_array($this->theEditRec)) { unset($this->theEditRec); $this->searchFor = $this->editPage; } elseif (!$GLOBALS['BE_USER']->isInWebMount($this->theEditRec['uid'])) { unset($this->theEditRec); $this->editError = $GLOBALS['LANG']->getLL('bookmark_notEditable'); } else { // Visual path set: $perms_clause = $GLOBALS['BE_USER']->getPagePermsClause(1); $this->editPath = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($this->theEditRec['pid'], $perms_clause, 30); if (!$GLOBALS['BE_USER']->getTSConfigVal('options.bookmark_onEditId_dontSetPageTree')) { $bookmarkKeepExpanded = $GLOBALS['BE_USER']->getTSConfigVal('options.bookmark_onEditId_keepExistingExpanded'); // Expanding page tree: \TYPO3\CMS\Backend\Utility\BackendUtility::openPageTree($this->theEditRec['pid'], !$bookmarkKeepExpanded); } } } } }
/** * Main Task center module * * @return string HTML content. */ public function main() { $content = ''; $id = intval(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('display')); // If a preset is found, it is rendered using an iframe if ($id > 0) { $url = $GLOBALS['BACK_PATH'] . \TYPO3\CMS\Core\Extension\ExtensionManager::extRelPath('impexp') . 'app/index.php?tx_impexp[action]=export&preset[load]=1&preset[select]=' . $id; return $this->taskObject->urlInIframe($url, 1); } else { // Header $content .= $this->taskObject->description($GLOBALS['LANG']->getLL('.alttitle'), $GLOBALS['LANG']->getLL('.description')); $thumbnails = $lines = array(); // Thumbnail folder and files: $tempDir = $this->userTempFolder(); if ($tempDir) { $thumbnails = \TYPO3\CMS\Core\Utility\GeneralUtility::getFilesInDir($tempDir, 'png,gif,jpg', 1); } $clause = $GLOBALS['BE_USER']->getPagePermsClause(1); $usernames = \TYPO3\CMS\Backend\Utility\BackendUtility::getUserNames(); // Create preset links: $presets = $this->getPresets(); // If any presets found if (is_array($presets)) { foreach ($presets as $key => $presetCfg) { $configuration = unserialize($presetCfg['preset_data']); $thumbnailFile = $thumbnails[$configuration['meta']['thumbnail']]; $title = strlen($presetCfg['title']) ? $presetCfg['title'] : '[' . $presetCfg['uid'] . ']'; $icon = 'EXT:impexp/export.gif'; $description = array(); // Is public? if ($presetCfg['public']) { $description[] = $GLOBALS['LANG']->getLL('task.public') . ': ' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:yes'); } // Owner $description[] = $GLOBALS['LANG']->getLL('task.owner') . ': ' . ($presetCfg['user_uid'] === $GLOBALS['BE_USER']->user['uid'] ? $GLOBALS['LANG']->getLL('task.own') : '[' . htmlspecialchars($usernames[$presetCfg['user_uid']]['username']) . ']'); // Page & path if ($configuration['pagetree']['id']) { $description[] = $GLOBALS['LANG']->getLL('task.page') . ': ' . $configuration['pagetree']['id']; $description[] = $GLOBALS['LANG']->getLL('task.path') . ': ' . htmlspecialchars(\TYPO3\CMS\Backend\Utility\BackendUtility::getRecordPath($configuration['pagetree']['id'], $clause, 20)); } else { $description[] = $GLOBALS['LANG']->getLL('single-record'); } // Meta information if ($configuration['meta']['title'] || $configuration['meta']['description'] || $configuration['meta']['notes']) { $metaInformation = ''; if ($configuration['meta']['title']) { $metaInformation .= '<strong>' . htmlspecialchars($configuration['meta']['title']) . '</strong><br />'; } if ($configuration['meta']['description']) { $metaInformation .= htmlspecialchars($configuration['meta']['description']); } if ($configuration['meta']['notes']) { $metaInformation .= '<br /><br /> <strong>' . $GLOBALS['LANG']->getLL('notes') . ': </strong> <em>' . htmlspecialchars($configuration['meta']['notes']) . '</em>'; } $description[] = '<br />' . $metaInformation; } // Collect all preset information $lines[$key] = array('icon' => $icon, 'title' => $title, 'descriptionHtml' => implode('<br />', $description), 'link' => 'mod.php?M=user_task&SET[function]=impexp.tx_impexp_task&display=' . $presetCfg['uid']); } // Render preset list $content .= $this->taskObject->renderListMenu($lines); } else { // No presets found $flashMessage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessage', $GLOBALS['LANG']->getLL('no-presets'), '', \TYPO3\CMS\Core\Messaging\FlashMessage::NOTICE); $content .= $flashMessage->render(); } } return $content; }
/** * Deleting files and folders (action=4) * * @param array $cmds $cmds['data'] is the file/folder to delete * @return bool Returns TRUE upon success */ public function func_delete(array $cmds) { $result = FALSE; if (!$this->isInit) { return $result; } // Example indentifier for $cmds['data'] => "4:mypath/tomyfolder/myfile.jpg" // for backwards compatibility: the combined file identifier was the path+filename try { $fileObject = $this->getFileObject($cmds['data']); } catch (ResourceDoesNotExistException $e) { $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.description.fileNotFound'), $cmds['data']), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.header.fileNotFound'), FlashMessage::ERROR, TRUE); $this->addFlashMessage($flashMessage); return FALSE; } // @todo implement the recycler feature which has been removed from the original implementation // checks to delete the file if ($fileObject instanceof File) { // check if the file still has references // Exclude sys_file_metadata records as these are no use references $databaseConnection = $this->getDatabaseConnection(); $table = 'sys_refindex'; $refIndexRecords = $databaseConnection->exec_SELECTgetRows('*', $table, 'deleted=0 AND ref_table=' . $databaseConnection->fullQuoteStr('sys_file', $table) . ' AND ref_uid=' . (int) $fileObject->getUid() . ' AND tablename != ' . $databaseConnection->fullQuoteStr('sys_file_metadata', $table)); $deleteFile = TRUE; if (!empty($refIndexRecords)) { $shortcutContent = array(); $brokenReferences = array(); foreach ($refIndexRecords as $fileReferenceRow) { if ($fileReferenceRow['tablename'] === 'sys_file_reference') { $row = $this->transformFileReferenceToRecordReference($fileReferenceRow); $shortcutRecord = BackendUtility::getRecord($row['tablename'], $row['recuid']); if ($shortcutRecord) { $icon = IconUtility::getSpriteIconForRecord($row['tablename'], $shortcutRecord); $tagParameters = array('class' => 't3-js-clickmenutrigger', 'data-table' => $row['tablename'], 'data-uid' => $row['recuid'], 'data-listframe' => 1, 'data-iteminfo' => '%2Binfo,history,edit'); $icon = '<a href="#" ' . GeneralUtility::implodeAttributes($tagParameters, TRUE) . '>' . $icon . '</a>'; $shortcutContent[] = $icon . htmlspecialchars(BackendUtility::getRecordTitle($row['tablename'], $shortcutRecord) . ' [' . BackendUtility::getRecordPath($shortcutRecord['pid'], '', 80) . ']'); } else { $brokenReferences[] = $fileReferenceRow['ref_uid']; } } } if (!empty($brokenReferences)) { // render a message that the file has broken references $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.description.fileHasBrokenReferences'), count($brokenReferences)), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.header.fileHasBrokenReferences'), FlashMessage::INFO, TRUE); $this->addFlashMessage($flashMessage); } if (!empty($shortcutContent)) { // render a message that the file could not be deleted $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.description.fileNotDeletedHasReferences'), $fileObject->getName()) . '<br />' . implode('<br />', $shortcutContent), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.header.fileNotDeletedHasReferences'), FlashMessage::WARNING, TRUE); $this->addFlashMessage($flashMessage); $deleteFile = FALSE; } } if ($deleteFile) { try { $result = $fileObject->delete(); // show the user that the file was deleted $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.description.fileDeleted'), $fileObject->getName()), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.header.fileDeleted'), FlashMessage::OK, TRUE); $this->addFlashMessage($flashMessage); // Log success $this->writelog(4, 0, 1, 'File "%s" deleted', array($fileObject->getIdentifier())); } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException $e) { $this->writelog(4, 1, 112, 'You are not allowed to access the file', array($fileObject->getIdentifier())); } catch (\TYPO3\CMS\Core\Resource\Exception\NotInMountPointException $e) { $this->writelog(4, 1, 111, 'Target was not within your mountpoints! T="%s"', array($fileObject->getIdentifier())); } catch (\RuntimeException $e) { $this->writelog(4, 1, 110, 'Could not delete file "%s". Write-permission problem?', array($fileObject->getIdentifier())); } } } else { /** @var Folder $fileObject */ if (!$this->folderHasFilesInUse($fileObject)) { try { $result = $fileObject->delete(TRUE); if ($result) { // notify the user that the folder was deleted /** @var FlashMessage $flashMessage */ $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.description.folderDeleted'), $fileObject->getName()), $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:message.header.folderDeleted'), FlashMessage::OK, TRUE); $this->addFlashMessage($flashMessage); // Log success $this->writelog(4, 0, 3, 'Directory "%s" deleted', array($fileObject->getIdentifier())); } } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientUserPermissionsException $e) { $this->writelog(4, 1, 120, 'Could not delete directory! Is directory "%s" empty? (You are not allowed to delete directories recursively).', array($fileObject->getIdentifier())); } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException $e) { $this->writelog(4, 1, 123, 'You are not allowed to access the directory', array($fileObject->getIdentifier())); } catch (\TYPO3\CMS\Core\Resource\Exception\NotInMountPointException $e) { $this->writelog(4, 1, 121, 'Target was not within your mountpoints! T="%s"', array($fileObject->getIdentifier())); } catch (\TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException $e) { $this->writelog(4, 1, 120, 'Could not delete directory "%s"! Write-permission problem?', array($fileObject->getIdentifier())); } } } return $result; }
/** * Returns the page title path of a PID value. Results are cached internally * * @param int $pid Record PID to check * @return string The path for the input PID */ public function getRecordPath($pid) { if (!isset($this->cache_getRecordPath[$pid])) { $clause = $this->getBackendUser()->getPagePermsClause(1); $this->cache_getRecordPath[$pid] = (string) BackendUtility::getRecordPath($pid, $clause, 20); } return $this->cache_getRecordPath[$pid]; }
/** * Generates and returns the content of the module * * @return string HTML to display */ protected function moduleContent() { $content = ''; $content .= $this->doc->header($GLOBALS['LANG']->getLL('general.title')); // Get the available configurations $l10nConfigurations = $this->getAllConfigurations(); // No configurations, issue a simple message if (count($l10nConfigurations) == 0) { $content .= $this->doc->section('', nl2br($GLOBALS['LANG']->getLL('general.no_date'))); // List all configurations } else { $content .= $this->doc->section('', nl2br($GLOBALS['LANG']->getLL('general.description.message'))); $content .= $this->doc->section($GLOBALS['LANG']->getLL('general.list.configuration.title'), ''); $content .= '<table class="typo3-dblist" border="0" cellpadding="0" cellspacing="0">'; // Assemble the header row $content .= '<thead>'; $content .= '<tr class="t3-row-header">'; $content .= '<td>' . $GLOBALS['LANG']->getLL('general.list.headline.info.title') . '</td>'; $content .= '<td>' . $GLOBALS['LANG']->getLL('general.list.headline.title.title') . '</td>'; $content .= '<td>' . $GLOBALS['LANG']->getLL('general.list.headline.path.title') . '</td>'; $content .= '<td>' . $GLOBALS['LANG']->getLL('general.list.headline.depth.title') . '</td>'; $content .= '<td>' . $GLOBALS['LANG']->getLL('general.list.headline.tables.title') . '</td>'; $content .= '<td>' . $GLOBALS['LANG']->getLL('general.list.headline.exclude.title') . '</td>'; $content .= '<td>' . $GLOBALS['LANG']->getLL('general.list.headline.include.title') . '</td>'; $content .= '<td>' . $GLOBALS['LANG']->getLL('general.list.headline.incfcewithdefaultlanguage.title') . '</td>'; $content .= '</tr>'; $content .= '</thead>'; $content .= '<tbody>'; $informationIcon = IconUtility::getSpriteIcon('actions-document-info', array()); foreach ($l10nConfigurations as $record) { $configurationDetails = '<a class="tooltip" href="#tooltip_' . $record['uid'] . '">' . $informationIcon . '</a>'; $configurationDetails .= '<div style="display:none;" id="tooltip_' . $record['uid'] . '" class="infotip">'; $configurationDetails .= $this->renderConfigurationDetails($record); $configurationDetails .= '</div>'; $content .= '<tr class="db_list_normal">'; $content .= '<td>' . $configurationDetails . '</td>'; $content .= '<td><a href="' . BackendUtility::getModuleUrl('xMOD_txl10nmgrCM1', array('id' => $record['uid'], 'srcPID' => (int) $this->id)) . '">' . $record['title'] . '</a>' . '</td>'; // Get the full page path // If very long, make sure to still display the full path $pagePath = BackendUtility::getRecordPath($record['pid'], '1', 20, 50); $path = is_array($pagePath) ? $pagePath[1] : $pagePath; $content .= '<td>' . $path . '</td>'; $content .= '<td>' . $record['depth'] . '</td>'; $content .= '<td>' . $record['tablelist'] . '</td>'; $content .= '<td>' . $record['exclude'] . '</td>'; $content .= '<td>' . $record['include'] . '</td>'; $content .= '<td>' . $record['incfcewithdefaultlanguage'] . '</td>'; $content .= '</tr>'; } $content .= '</tbody>'; } return $content; }