/** * Overview About Sitemaps */ public function indexAction() { $pages = $this->getBasePages(); $providers = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $this->settings['provider'], TRUE); $nodes = array(); foreach ($providers as $provider) { $provider = Tx_GoogleServices_Service_SitemapProvider::getProvider($provider); $providerNodes = $provider->getRecords(intval($this->settings['startpoint']), $pages, $this); $nodes = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge($nodes, $providerNodes); } $this->prepareAndAssignNodes($nodes); }
/** * Actions for flex form element (move, delete) * * @param array &$valueArrayToRemoveFrom by reference * @param array $deleteCMDS * @return void * @todo Define visibility */ public function _ACTION_FLEX_FORMdata(&$valueArray, $actionCMDs) { if (is_array($valueArray) && is_array($actionCMDs)) { foreach ($actionCMDs as $key => $value) { if ($key == '_ACTION') { // First, check if there are "commands": if (current($actionCMDs[$key]) !== '') { asort($actionCMDs[$key]); $newValueArray = array(); foreach ($actionCMDs[$key] as $idx => $order) { if (substr($idx, 0, 3) == 'ID-') { $idx = $this->newIndexMap[$idx]; } // Just one reflection here: It is clear that when removing elements from a flexform, then we will get lost files unless we act on this delete operation by traversing and deleting files that were referred to. if ($order != 'DELETE') { $newValueArray[$idx] = $valueArray[$idx]; } unset($valueArray[$idx]); } $valueArray = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge($newValueArray, $valueArray); } } elseif (is_array($actionCMDs[$key]) && isset($valueArray[$key])) { $this->_ACTION_FLEX_FORMdata($valueArray[$key], $actionCMDs[$key]); } } } }
/** * Gets a collection of path configurations for content elements * based on each root TypoScript template in the provided array * of templates. Returns an array of paths indexed by the root * page UID. * * @param array $templates * @return array */ protected function getPathConfigurationsFromRootTypoScriptTemplates($templates) { $allTemplatePaths = array(); $registeredExtensionKeys = Core::getRegisteredProviderExtensionKeys('Content'); foreach ($templates as $templateRecord) { $pageUid = $templateRecord['pid']; /** @var \TYPO3\CMS\Core\TypoScript\ExtendedTemplateService $template */ $template = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\TypoScript\\ExtendedTemplateService'); $template->tt_track = 0; $template->init(); /** @var \TYPO3\CMS\Frontend\Page\PageRepository $sys_page */ $sys_page = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\PageRepository'); $rootLine = $sys_page->getRootLine($pageUid); $template->runThroughTemplates($rootLine); $template->generateConfig(); $oldTemplatePathLocation = (array) $template->setup['plugin.']['tx_fed.']['fce.']; $newTemplatePathLocation = (array) $template->setup['plugin.']['tx_fluidcontent.']['collections.']; $registeredPathCollections = array(); foreach ($registeredExtensionKeys as $registeredExtensionKey) { $nativeViewLocation = $this->getContentConfiguration($registeredExtensionKey); if (FALSE === isset($nativeViewLocation['extensionKey'])) { $nativeViewLocation['extensionKey'] = ExtensionNamingUtility::getExtensionKey($registeredExtensionKey); } $registeredPathCollections[$registeredExtensionKey] = $nativeViewLocation; } $merged = GeneralUtility::array_merge_recursive_overrule($oldTemplatePathLocation, $newTemplatePathLocation); $merged = GeneralUtility::removeDotsFromTS($merged); $merged = GeneralUtility::array_merge($merged, $registeredPathCollections); $allTemplatePaths[$pageUid] = $merged; } return $allTemplatePaths; }
/** * Search for a title in a certain PID * * @param int $searchPid Page id in which to search subpages matching title * @param string $title Title to search for * @return array First entry is uid, second entry is the row selected, including information about the page as a mount point. * @see findPageBySegment() */ protected function findPageBySegmentAndPid($searchPid, $title) { // List of "pages" fields to traverse for a "directory title" in the speaking URL (only from RootLine!!) $segTitleFieldList = $this->conf['segTitleFieldList'] ? $this->conf['segTitleFieldList'] : TX_REALURL_SEGTITLEFIELDLIST_DEFAULT; $selList = GeneralUtility::uniqueList('uid,pid,doktype,mount_pid,mount_pid_ol,tx_realurl_exclude,' . $segTitleFieldList); $segTitleFieldArray = GeneralUtility::trimExplode(',', $segTitleFieldList, 1); // page select object - used to analyse mount points. $sys_page = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\PageRepository'); /** @var \TYPO3\CMS\Frontend\Page\PageRepository $sys_page */ // Build an array with encoded values from the segTitleFieldArray of the subpages // First we find field values from the default language // Pages are selected in menu order and if duplicate titles are found the first takes precedence! $titles = array(); // array(title => uid); $exclude = array(); $uidTrack = array(); /** @noinspection PhpUndefinedMethodInspection */ $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selList, 'pages', 'pid=' . intval($searchPid) . ' AND deleted=0 AND doktype!=255', '', 'sorting'); /** @noinspection PhpUndefinedMethodInspection */ while (false != ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result))) { // Mount points $mount_info = $sys_page->getMountPointInfo($row['uid'], $row); if (is_array($mount_info)) { // There is a valid mount point. if ($mount_info['overlay']) { // Overlay mode: Substitute WHOLE record /** @noinspection PhpUndefinedMethodInspection */ $result2 = $GLOBALS['TYPO3_DB']->exec_SELECTquery($selList, 'pages', 'uid=' . intval($mount_info['mount_pid']) . ' AND deleted=0 AND doktype!=255'); /** @noinspection PhpUndefinedMethodInspection */ $mp_row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result2); if (is_array($mp_row)) { $row = $mp_row; } else { unset($row); // If the mount point could not be fetched, unset the row } } $row['_IS_MOUNTPOINT'] = $mount_info; } // Collect titles from selected row if (is_array($row)) { if ($row['tx_realurl_exclude']) { // segment is excluded $exclude[] = $row; } // Process titles. Note that excluded segments are also searched // otherwise they will never be found $uidTrack[$row['uid']] = $row; foreach ($segTitleFieldArray as $fieldName) { if ($row[$fieldName]) { $encodedTitle = $this->encodeTitle($row[$fieldName]); if (!isset($titles[$fieldName][$encodedTitle])) { $titles[$fieldName][$encodedTitle] = $row['uid']; } } } } } /** @noinspection PhpUndefinedMethodInspection */ $GLOBALS['TYPO3_DB']->sql_free_result($result); // We have to search the language overlay too, if: a) the language isn't the default (0), b) if it's not set (-1) $uidTrackKeys = array_keys($uidTrack); $language = $this->pObj->getDetectedLanguage(); if ($language != 0) { foreach ($uidTrackKeys as $l_id) { /** @noinspection PhpUndefinedMethodInspection */ $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery(TX_REALURL_SEGTITLEFIELDLIST_PLO, 'pages_language_overlay', 'pid=' . intval($l_id) . ' AND deleted=0' . ($language > 0 ? ' AND sys_language_uid=' . $language : '')); /** @noinspection PhpUndefinedMethodInspection */ while (false != ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result))) { foreach ($segTitleFieldArray as $fieldName) { if ($row[$fieldName]) { $encodedTitle = $this->encodeTitle($row[$fieldName]); if (!isset($titles[$fieldName][$encodedTitle])) { $titles[$fieldName][$encodedTitle] = $l_id; } } } } /** @noinspection PhpUndefinedMethodInspection */ $GLOBALS['TYPO3_DB']->sql_free_result($result); } } // Merge titles $segTitleFieldArray = array_reverse($segTitleFieldArray); // To observe the priority order... $allTitles = array(); foreach ($segTitleFieldArray as $fieldName) { if (is_array($titles[$fieldName])) { $allTitles = GeneralUtility::array_merge($allTitles, $titles[$fieldName]); } } // Return $encodedTitle = $this->encodeTitle($title); $possibleMatch = array(); if (isset($allTitles[$encodedTitle])) { if (!$uidTrack[$allTitles[$encodedTitle]]['tx_realurl_exclude']) { return array($allTitles[$encodedTitle], $uidTrack[$allTitles[$encodedTitle]], false, array()); } $possibleMatch = $uidTrack[$allTitles[$encodedTitle]]; } return array(false, false, $exclude, $possibleMatch); }
/** * @param string $fieldName * @param string $foreignTable * @param string $foreignField * @param string $foreignSortby * @param string $foreignTableField * @param array $foreignMatchFields * @param string $foreignLabel * @param string $foreignSelector * @param int $exclude * @param int $maxitems * @param int $minitems * @param string $label * @param array $overwriteConfig * @return array */ public function addReferenceField($fieldName, $foreignTable, $foreignField, $foreignSortby, $foreignTableField = null, $foreignMatchFields = array(), $foreignLabel = null, $foreignSelector = null, $exclude = 0, $maxitems = 999, $minitems = 0, $label = '', $overwriteConfig = array(), $displayCond = null) { if (empty($label)) { $label = $this->getFieldLabel($fieldName); } $config = array('type' => 'inline', 'maxitems' => $maxitems, 'minitems' => $minitems, 'foreign_table' => $foreignTable, 'foreign_field' => $foreignField, 'foreign_sortby' => $foreignSortby, 'foreign_table_field' => $foreignTableField, 'foreign_match_fields' => $foreignMatchFields, 'foreign_label' => $foreignLabel, 'foreign_selector' => $foreignSelector); $this->fields[$fieldName] = array('exclude' => $exclude, 'label' => $label, 'config' => GeneralUtility::array_merge($config, $overwriteConfig)); if (!empty($displayCond)) { $this->fields[$fieldName]['displayCond'] = $displayCond; } return array($fieldName => $this->fields[$fieldName]); }
/** * @param array $arr1 First array * @param array $arr2 Second array * @return array Merged result. */ public function array_merge(array $arr1, array $arr2) { return GeneralUtility::array_merge($arr1, $arr2); }
/** * Returns a select containing all the Backend users. * * @param array $options Current options of the field. * @return string The HTML code containing the <select> tag with filled options. */ public function getBackendUsersSelect($options) { $html = '<select name="' . $options['fieldName'] . '">'; $backendUserGroups = GeneralUtility::array_merge([0 => ['uid' => -1, 'title' => '']], Core::getDatabase()->exec_SELECTgetRows('uid, username', 'be_users', '1=1')); foreach ($backendUserGroups as $group) { $selected = $group['uid'] == $options['fieldValue'] ? ' selected="selected"' : ''; $uidLabel = $group['uid'] != -1 ? ' [' . $group['uid'] . ']' : ''; $html .= '<option value="' . $group['uid'] . '"' . $selected . '>' . $group['username'] . $uidLabel . '</option>'; } $html .= '</select>'; return $html; }
/** * Initialize Action of the widget controller * * @return void */ public function initializeAction() { $this->objects = $this->widgetConfiguration['objects']; if (version_compare(TYPO3_branch, '6.2', '<')) { $this->configuration = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($this->configuration, $this->widgetConfiguration['configuration'], TRUE); } else { if (version_compare(TYPO3_branch, '8.0', '<')) { $this->configuration = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge($this->configuration, $this->widgetConfiguration['configuration'], TRUE); } else { $this->configuration = array_merge($this->configuration, $this->widgetConfiguration['configuration']); } } }
/** * Send an email notification to users in workspace * * @param array $stat Workspace access array from \TYPO3\CMS\Core\Authentication\BackendUserAuthentication::checkWorkspace() * @param integer $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 integer $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)) { // 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'); $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 = GeneralUtility::array_merge($emails, $this->getEmailsForStageChangeNotification($dat['userid'], TRUE)); 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 = GeneralUtility::array_merge($emails, $this->getEmailsForStageChangeNotification($workspaceRec['reviewers'])); $emails = GeneralUtility::array_merge($emails, $this->getEmailsForStageChangeNotification($workspaceRec['members'])); 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'); // 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'); $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'); 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); } } }
/** * import CSV-Data in step-by-step mode * * @return string HTML form */ function cmd_displayImport() { $step = GeneralUtility::_GP('importStep'); $defaultConf = array('remove_existing' => 0, 'first_fieldname' => 0, 'valid_email' => 0, 'remove_dublette' => 0, 'update_unique' => 0); if (GeneralUtility::_GP('CSV_IMPORT')) { $importerConfig = GeneralUtility::_GP('CSV_IMPORT'); if ($step['next'] == 'mapping') { $this->indata = GeneralUtility::array_merge($defaultConf, $importerConfig); } else { $this->indata = $importerConfig; } } if (empty($this->indata)) { $this->indata = array(); } if (empty($this->params)) { $this->params = array(); } // merge it with inData, but inData has priority. $this->indata = GeneralUtility::array_merge($this->params, $this->indata); $currentFileInfo = BasicFileUtility::getTotalFileInfo($this->indata['newFile']); $currentFileName = $currentFileInfo['file']; $currentFileSize = GeneralUtility::formatSize($currentFileInfo['size']); $currentFileMessage = $currentFileName . ' (' . $currentFileSize . ')'; if (empty($this->indata['csv']) && !empty($_FILES['upload_1']['name'])) { $this->indata['newFile'] = $this->checkUpload(); // TYPO3 6.0 returns an object... if (is_object($this->indata['newFile'][0])) { $storageConfig = $this->indata['newFile'][0]->getStorage()->getConfiguration(); $this->indata['newFile'] = $storageConfig['basePath'] . ltrim($this->indata['newFile'][0]->getIdentifier(), '/'); } } elseif (!empty($this->indata['csv']) && empty($_FILES['upload_1']['name'])) { if ((strpos($currentFileInfo['file'], 'import') === false ? 0 : 1) && $currentFileInfo['realFileext'] === 'txt') { //do nothing } else { unset($this->indata['newFile']); } } if ($this->indata['back']) { $stepCurrent = $step['back']; } elseif ($this->indata['next']) { $stepCurrent = $step['next']; } elseif ($this->indata['update']) { $stepCurrent = 'mapping'; } if (strlen($this->indata['csv']) > 0) { $this->indata['mode'] = 'csv'; $this->indata['newFile'] = $this->writeTempFile(); } elseif (!empty($this->indata['newFile'])) { $this->indata['mode'] = 'file'; } else { unset($stepCurrent); } //check if "email" is mapped if ($stepCurrent === 'import') { $map = $this->indata['map']; $error = array(); //check noMap $newMap = GeneralUtility::removeArrayEntryByValue(array_unique($map), 'noMap'); if (empty($newMap)) { $error[] = 'noMap'; } elseif (!GeneralUtility::inArray($map, 'email')) { $error[] = 'email'; } if ($error) { $stepCurrent = 'mapping'; } } $out = ""; switch ($stepCurrent) { case 'conf': //get list of sysfolder //TODO: maybe only subtree von this->id?? $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,title', 'pages', 'doktype = 254 AND ' . $GLOBALS['BE_USER']->getPagePermsClause(3) . BackendUtility::deleteClause('pages') . BackendUtility::BEenableFields('pages'), '', 'uid'); $optStorage = array(); while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) { if (BackendUtility::readPageAccess($row['uid'], $GLOBALS['BE_USER']->getPagePermsClause(1))) { $optStorage[] = array($row['uid'], $row['title'] . ' [uid:' . $row['uid'] . ']'); } } $GLOBALS['TYPO3_DB']->sql_free_result($res); $optDelimiter = array(array('comma', $GLOBALS['LANG']->getLL('mailgroup_import_separator_comma')), array('semicolon', $GLOBALS['LANG']->getLL('mailgroup_import_separator_semicolon')), array('colon', $GLOBALS['LANG']->getLL('mailgroup_import_separator_colon')), array('tab', $GLOBALS['LANG']->getLL('mailgroup_import_separator_tab'))); $optEncap = array(array('doubleQuote', ' " '), array('singleQuote', " ' ")); //TODO: make it variable? $optUnique = array(array('email', 'email'), array('name', 'name')); $this->params['inputDisable'] == 1 ? $disableInput = 'disabled="disabled"' : ($disableInput = ''); //show configuration $out = '<hr /><h3>' . $GLOBALS['LANG']->getLL('mailgroup_import_header_conf') . '</h3>'; $tblLines = array(); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_storage'), $this->makeDropdown('CSV_IMPORT[storage]', $optStorage, $this->indata['storage'])); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_remove_existing'), '<input type="checkbox" name="CSV_IMPORT[remove_existing]" value="1"' . (!$this->indata['remove_existing'] ? '' : ' checked="checked"') . ' ' . $disableInput . '/> '); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_first_fieldnames'), '<input type="checkbox" name="CSV_IMPORT[first_fieldname]" value="1"' . (!$this->indata['first_fieldname'] ? '' : ' checked="checked"') . ' ' . $disableInput . '/> '); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_separator'), $this->makeDropdown('CSV_IMPORT[delimiter]', $optDelimiter, $this->indata['delimiter'], $disableInput)); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_encapsulation'), $this->makeDropdown('CSV_IMPORT[encapsulation]', $optEncap, $this->indata['encapsulation'], $disableInput)); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_csv_validemail-description'), '<input type="checkbox" name="CSV_IMPORT[valid_email]" value="1"' . (!$this->indata['valid_email'] ? '' : ' checked="checked"') . ' ' . $disableInput . '/> '); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_csv_dublette-description'), '<input type="checkbox" name="CSV_IMPORT[remove_dublette]" value="1"' . (!$this->indata['remove_dublette'] ? '' : ' checked="checked"') . ' ' . $disableInput . '/> '); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_update_unique'), '<input type="checkbox" name="CSV_IMPORT[update_unique]" value="1"' . (!$this->indata['update_unique'] ? '' : ' checked="checked"') . ' ' . $disableInput . '/>'); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_record_unique'), $this->makeDropdown('CSV_IMPORT[record_unique]', $optUnique, $this->indata['record_unique'], $disableInput)); $out .= $this->formatTable($tblLines, array('width=300', 'nowrap'), 0, array(0, 1)); $out .= '<br /><br />'; $out .= '<input type="submit" name="CSV_IMPORT[back]" value="' . $GLOBALS['LANG']->getLL('mailgroup_import_back') . '" /> <input type="submit" name="CSV_IMPORT[next]" value="' . $GLOBALS['LANG']->getLL('mailgroup_import_next') . '" />' . $this->makeHidden(array('CMD' => 'displayImport', 'importStep[next]' => 'mapping', 'importStep[back]' => 'upload', 'CSV_IMPORT[newFile]' => $this->indata['newFile'])); break; case 'mapping': //show charset selector $cs = array_unique(array_values($GLOBALS['LANG']->csConvObj->synonyms)); $charSets = array(); foreach ($cs as $charset) { $charSets[] = array($charset, $charset); } if (!isset($this->indata['charset'])) { $this->indata['charset'] = 'iso-8859-1'; } $out .= '<hr /><h3>' . $GLOBALS['LANG']->getLL('mailgroup_import_mapping_charset') . '</h3>'; $tblLines = array(); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_mapping_charset_choose'), $this->makeDropdown('CSV_IMPORT[charset]', $charSets, $this->indata['charset'])); $out .= $this->formatTable($tblLines, array('nowrap', 'nowrap'), 0, array(1, 1), 'border="0" cellpadding="0" cellspacing="0" class="typo3-dblist"'); $out .= '<input type="submit" name="CSV_IMPORT[update]" value="' . $GLOBALS['LANG']->getLL('mailgroup_import_update') . '"/>'; unset($tblLines); //show mapping form $out .= '<hr /><h3>' . $GLOBALS['LANG']->getLL('mailgroup_import_mapping_conf') . '</h3>'; if ($this->indata['first_fieldname']) { //read csv $csvData = $this->readExampleCSV(4); $csv_firstRow = $csvData[0]; $csvData = array_slice($csvData, 1); } else { //read csv $csvData = $this->readExampleCSV(3); $fieldsAmount = count($csvData[0]); $csv_firstRow = array(); for ($i = 0; $i < $fieldsAmount; $i++) { $csv_firstRow[] = 'field_' . $i; } } //read tt_address TCA $no_map = array('image'); $tt_address_fields = array_keys($GLOBALS['TCA']['tt_address']['columns']); foreach ($no_map as $v) { $tt_address_fields = GeneralUtility::removeArrayEntryByValue($tt_address_fields, $v); } $mapFields = array(); foreach ($tt_address_fields as $map) { $mapFields[] = array($map, str_replace(':', '', $GLOBALS['LANG']->sL($GLOBALS['TCA']['tt_address']['columns'][$map]['label']))); } //add 'no value' array_unshift($mapFields, array('noMap', $GLOBALS['LANG']->getLL('mailgroup_import_mapping_mapTo'))); $mapFields[] = array('cats', $GLOBALS['LANG']->getLL('mailgroup_import_mapping_categories')); reset($csv_firstRow); reset($csvData); $tblLines = array(); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_mapping_number'), $GLOBALS['LANG']->getLL('mailgroup_import_mapping_description'), $GLOBALS['LANG']->getLL('mailgroup_import_mapping_mapping'), $GLOBALS['LANG']->getLL('mailgroup_import_mapping_value')); for ($i = 0; $i < count($csv_firstRow); $i++) { //example CSV $exampleLines = array(); for ($j = 0; $j < count($csvData); $j++) { $exampleLines[] = array($csvData[$j][$i]); } $tblLines[] = array($i + 1, $csv_firstRow[$i], $this->makeDropdown('CSV_IMPORT[map][' . $i . ']', $mapFields, $this->indata['map'][$i]), $this->formatTable($exampleLines, array('nowrap'), 0, array(0), 'border="0" cellpadding="0" cellspacing="0" class="typo3-dblist" style="width:100%; border:0px; margin:0px;"')); } if ($error) { $out .= '<h3>' . $GLOBALS['LANG']->getLL('mailgroup_import_mapping_error') . '</h3>'; $out .= $GLOBALS['LANG']->getLL('mailgroup_import_mapping_error_detail') . '<br /><ul>'; foreach ($error as $errorDetail) { $out .= '<li>' . $GLOBALS['LANG']->getLL('mailgroup_import_mapping_error_' . $errorDetail) . '</li>'; } $out .= '</ul>'; } //additional options $tblLinesAdd = array(); //header $tblLinesAdd[] = array($GLOBALS['LANG']->getLL('mailgroup_import_mapping_all_html'), '<input type="checkbox" name="CSV_IMPORT[all_html]" value="1"' . (!$this->indata['all_html'] ? '' : ' checked="checked"') . '/> '); //get categories $temp = BackendUtility::getModTSconfig($this->parent->id, 'TCEFORM.sys_dmail_group.select_categories.PAGE_TSCONFIG_IDLIST'); if (is_numeric($temp['value'])) { $rowCat = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*', 'sys_dmail_category', 'pid IN (' . $temp['value'] . ')' . BackendUtility::deleteClause('sys_dmail_category') . BackendUtility::BEenableFields('sys_dmail_category')); if (!empty($rowCat)) { $tblLinesAdd[] = array($GLOBALS['LANG']->getLL('mailgroup_import_mapping_cats'), ''); if ($this->indata['update_unique']) { $tblLinesAdd[] = array($GLOBALS['LANG']->getLL('mailgroup_import_mapping_cats_add'), '<input type="checkbox" name="CSV_IMPORT[add_cat]" value="1"' . ($this->indata['add_cat'] ? ' checked="checked"' : '') . '/> '); } foreach ($rowCat as $k => $v) { $tblLinesAdd[] = array(' ' . htmlspecialchars($v['category']), '<input type="checkbox" name="CSV_IMPORT[cat][' . $k . ']" value="' . $v['uid'] . '"' . ($this->indata['cat'][$k] != $v['uid'] ? '' : ' checked="checked"') . '/> '); } } } $out .= $this->formatTable($tblLines, array('nowrap', 'nowrap', 'nowrap', 'nowrap'), 1, array(0, 0, 1, 1), 'border="0" cellpadding="0" cellspacing="0" class="typo3-dblist"'); $out .= '<br /><br />'; //additional options $out .= '<hr /><h3>' . $GLOBALS['LANG']->getLL('mailgroup_import_mapping_conf_add') . '</h3>'; $out .= $this->formatTable($tblLinesAdd, array('nowrap', 'nowrap'), 0, array(1, 1), 'border="0" cellpadding="0" cellspacing="0" class="typo3-dblist"'); $out .= '<br /><br />'; $out .= '<input type="submit" name="CSV_IMPORT[back]" value="' . $GLOBALS['LANG']->getLL('mailgroup_import_back') . '"/> <input type="submit" name="CSV_IMPORT[next]" value="' . $GLOBALS['LANG']->getLL('mailgroup_import_next') . '"/>' . $this->makeHidden(array('CMD' => 'displayImport', 'importStep[next]' => 'import', 'importStep[back]' => 'conf', 'CSV_IMPORT[newFile]' => $this->indata['newFile'], 'CSV_IMPORT[storage]' => $this->indata['storage'], 'CSV_IMPORT[remove_existing]' => $this->indata['remove_existing'], 'CSV_IMPORT[first_fieldname]' => $this->indata['first_fieldname'], 'CSV_IMPORT[delimiter]' => $this->indata['delimiter'], 'CSV_IMPORT[encapsulation]' => $this->indata['encapsulation'], 'CSV_IMPORT[valid_email]' => $this->indata['valid_email'], 'CSV_IMPORT[remove_dublette]' => $this->indata['remove_dublette'], 'CSV_IMPORT[update_unique]' => $this->indata['update_unique'], 'CSV_IMPORT[record_unique]' => $this->indata['record_unique'])); break; case 'import': //show import messages $out .= '<hr /><h3>' . $GLOBALS['LANG']->getLL('mailgroup_import_ready_import') . '</h3>'; $out .= $GLOBALS['LANG']->getLL('mailgroup_import_ready_import_label') . '<br /><br />'; $out .= '<input type="submit" name="CSV_IMPORT[back]" value="' . $GLOBALS['LANG']->getLL('mailgroup_import_back') . '" /> <input type="submit" name="CSV_IMPORT[next]" value="' . $GLOBALS['LANG']->getLL('mailgroup_import_import') . '" />' . $this->makeHidden(array('CMD' => 'displayImport', 'importStep[next]' => 'startImport', 'importStep[back]' => 'mapping', 'CSV_IMPORT[newFile]' => $this->indata['newFile'], 'CSV_IMPORT[storage]' => $this->indata['storage'], 'CSV_IMPORT[remove_existing]' => $this->indata['remove_existing'], 'CSV_IMPORT[first_fieldname]' => $this->indata['first_fieldname'], 'CSV_IMPORT[delimiter]' => $this->indata['delimiter'], 'CSV_IMPORT[encapsulation]' => $this->indata['encapsulation'], 'CSV_IMPORT[valid_email]' => $this->indata['valid_email'], 'CSV_IMPORT[remove_dublette]' => $this->indata['remove_dublette'], 'CSV_IMPORT[update_unique]' => $this->indata['update_unique'], 'CSV_IMPORT[record_unique]' => $this->indata['record_unique'], 'CSV_IMPORT[all_html]' => $this->indata['all_html'], 'CSV_IMPORT[add_cat]' => $this->indata['add_cat'], 'CSV_IMPORT[charset]' => $this->indata['charset'])); $hiddenMapped = array(); foreach ($this->indata['map'] as $fieldNr => $fieldMapped) { $hiddenMapped[] = $this->makeHidden('CSV_IMPORT[map][' . $fieldNr . ']', $fieldMapped); } if (is_array($this->indata['cat'])) { foreach ($this->indata['cat'] as $k => $catUID) { $hiddenMapped[] = $this->makeHidden('CSV_IMPORT[cat][' . $k . ']', $catUID); } } $out .= implode('', $hiddenMapped); break; case 'startImport': //starting import & show errors //read csv if ($this->indata['first_fieldname']) { //read csv $csvData = $this->readCSV(); $csvData = array_slice($csvData, 1); } else { //read csv $csvData = $this->readCSV(); } //show not imported record and reasons, $result = $this->doImport($csvData); $out = '<hr /><h3>' . $GLOBALS['LANG']->getLL('mailgroup_import_done') . '</h3>'; $defaultOrder = array('new', 'update', 'invalid_email', 'double'); if (!empty($this->params['resultOrder'])) { $resultOrder = GeneralUtility::trimExplode(',', $this->params['resultOrder']); } else { $resultOrder = array(); } $diffOrder = array_diff($defaultOrder, $resultOrder); $endOrder = array_merge($resultOrder, $diffOrder); foreach ($endOrder as $order) { $tblLines = array(); $tblLines[] = array($GLOBALS['LANG']->getLL('mailgroup_import_report_' . $order)); if (is_array($result[$order])) { foreach ($result[$order] as $k => $v) { $mapKeys = array_keys($v); $tblLines[] = array($k + 1, $v[$mapKeys[0]], $v['email']); } } $out .= $this->formatTable($tblLines, array('nowrap', 'first' => 'colspan="3"'), 1, array(1)); } //back button $out .= $this->makeHidden(array('CMD' => 'displayImport', 'importStep[back]' => 'import', 'CSV_IMPORT[newFile]' => $this->indata['newFile'], 'CSV_IMPORT[storage]' => $this->indata['storage'], 'CSV_IMPORT[remove_existing]' => $this->indata['remove_existing'], 'CSV_IMPORT[first_fieldname]' => $this->indata['first_fieldname'], 'CSV_IMPORT[delimiter]' => $this->indata['delimiter'], 'CSV_IMPORT[encapsulation]' => $this->indata['encapsulation'], 'CSV_IMPORT[valid_email]' => $this->indata['valid_email'], 'CSV_IMPORT[remove_dublette]' => $this->indata['remove_dublette'], 'CSV_IMPORT[update_unique]' => $this->indata['update_unique'], 'CSV_IMPORT[record_unique]' => $this->indata['record_unique'], 'CSV_IMPORT[all_html]' => $this->indata['all_html'], 'CSV_IMPORT[charset]' => $this->indata['charset'])); $hiddenMapped = array(); foreach ($this->indata['map'] as $fieldNr => $fieldMapped) { $hiddenMapped[] = $this->makeHidden('CSV_IMPORT[map][' . $fieldNr . ']', $fieldMapped); } if (is_array($this->indata['cat'])) { foreach ($this->indata['cat'] as $k => $catUID) { $hiddenMapped[] = $this->makeHidden('CSV_IMPORT[cat][' . $k . ']', $catUID); } } $out .= implode('', $hiddenMapped); break; case 'upload': default: //show upload file form $out = '<hr /><h3>' . $GLOBALS['LANG']->getLL('mailgroup_import_header_upload') . '</h3>'; $tempDir = $this->userTempFolder(); $tblLines[] = $GLOBALS['LANG']->getLL('mailgroup_import_upload_file') . '<input type="file" name="upload_1" size="30" />'; if ($this->indata['mode'] == 'file' && !((strpos($currentFileInfo['file'], 'import') === false ? 0 : 1) && $currentFileInfo['realFileext'] === 'txt')) { $tblLines[] = $GLOBALS['LANG']->getLL('mailgroup_import_current_file') . '<b>' . $currentFileMessage . '</b>'; } if ((strpos($currentFileInfo['file'], 'import') === false ? 0 : 1) && $currentFileInfo['realFileext'] === 'txt') { $handleCSV = fopen($this->indata['newFile'], 'r'); $this->indata['csv'] = fread($handleCSV, filesize($this->indata['newFile'])); fclose($handleCSV); } $tblLines[] = ''; $tblLines[] = '<b>' . $GLOBALS['LANG']->getLL('mailgroup_import_or') . '</b>'; $tblLines[] = ''; $tblLines[] = $GLOBALS['LANG']->getLL('mailgroup_import_paste_csv'); $tblLines[] = '<textarea name="CSV_IMPORT[csv]" rows="25" wrap="off"' . $this->parent->doc->formWidthText(48, '', 'off') . '>' . GeneralUtility::formatForTextarea($this->indata['csv']) . '</textarea>'; $tblLines[] = '<input type="submit" name="CSV_IMPORT[next]" value="' . $GLOBALS['LANG']->getLL('mailgroup_import_next') . '" />'; $out .= implode('<br />', $tblLines); $out .= '<input type="hidden" name="CMD" value="displayImport" /> <input type="hidden" name="importStep[next]" value="conf" /> <input type="hidden" name="file[upload][1][target]" value="' . htmlspecialchars($tempDir) . '" ' . ($_POST['importNow'] ? 'disabled' : '') . '/> <input type="hidden" name="file[upload][1][data]" value="1" /> <input type="hidden" name="CSV_IMPORT[newFile]" value ="' . $this->indata['newFile'] . '">'; break; } $theOutput = $this->parent->doc->section($GLOBALS['LANG']->getLL('mailgroup_import') . BackendUtility::cshItem($this->cshTable, 'mailgroup_import', $GLOBALS['BACK_PATH']), $out, 1, 1, 0, TRUE); /** * Hook for cmd_displayImport * use it to manipulate the steps in the import process */ if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['direct_mail/mod3/class.tx_directmail_recipient_list.php']['cmd_displayImport'])) { $hookObjectsArr = array(); foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['direct_mail/mod3/class.tx_directmail_recipient_list.php']['cmd_displayImport'] as $classRef) { $hookObjectsArr[] =& GeneralUtility::getUserObj($classRef); } } if (is_array($hookObjectsArr)) { foreach ($hookObjectsArr as $hookObj) { if (method_exists($hookObj, 'cmd_displayImport')) { $theOutput = ''; $theOutput = $hookObj->cmd_displayImport($this); } } } return $theOutput; }
/** * Ajax handler for the "suggest" feature in TCEforms. * * @param array $params The parameters from the AJAX call * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxObj The AJAX object representing the AJAX call * @return void */ public function processAjaxRequest($params, &$ajaxObj) { // Get parameters from $_GET/$_POST $search = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('value'); $table = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('table'); $field = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('field'); $uid = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('uid'); $pageId = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('pid'); \TYPO3\CMS\Core\Utility\GeneralUtility::loadTCA($table); // If the $uid is numeric, we have an already existing element, so get the // TSconfig of the page itself or the element container (for non-page elements) // otherwise it's a new element, so use given id of parent page (i.e., don't modify it here) if (is_numeric($uid)) { if ($table == 'pages') { $pageId = $uid; } else { $row = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecord($table, $uid); $pageId = $row['pid']; } } $TSconfig = \TYPO3\CMS\Backend\Utility\BackendUtility::getPagesTSconfig($pageId); $queryTables = array(); $foreign_table_where = ''; $fieldConfig = $GLOBALS['TCA'][$table]['columns'][$field]['config']; $parts = explode('|', $field); if ($GLOBALS['TCA'][$table]['columns'][$parts[0]]['config']['type'] === 'flex') { if (is_array($row) && count($row) > 0) { $flexfieldTCAConfig = $GLOBALS['TCA'][$table]['columns'][$parts[0]]['config']; $flexformDSArray = \TYPO3\CMS\Backend\Utility\BackendUtility::getFlexFormDS($flexfieldTCAConfig, $row, $table); $flexformDSArray = \TYPO3\CMS\Core\Utility\GeneralUtility::resolveAllSheetsInDS($flexformDSArray); $flexformElement = $parts[count($parts) - 2]; $continue = TRUE; foreach ($flexformDSArray as $sheet) { foreach ($sheet as $_ => $dataStructure) { if (isset($dataStructure['ROOT']['el'][$flexformElement]['TCEforms']['config'])) { $fieldConfig = $dataStructure['ROOT']['el'][$flexformElement]['TCEforms']['config']; $continue = FALSE; break; } } if (!$continue) { break; } } $field = str_replace('|', '][', $field); } } $wizardConfig = $fieldConfig['wizards']['suggest']; if (isset($fieldConfig['allowed'])) { $queryTables = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $fieldConfig['allowed']); } elseif (isset($fieldConfig['foreign_table'])) { $queryTables = array($fieldConfig['foreign_table']); $foreign_table_where = $fieldConfig['foreign_table_where']; // strip ORDER BY clause $foreign_table_where = trim(preg_replace('/ORDER[[:space:]]+BY.*/i', '', $foreign_table_where)); } $resultRows = array(); // fetch the records for each query table. A query table is a table from which records are allowed to // be added to the TCEForm selector, originally fetched from the "allowed" config option in the TCA foreach ($queryTables as $queryTable) { \TYPO3\CMS\Core\Utility\GeneralUtility::loadTCA($queryTable); // if the table does not exist, skip it if (!is_array($GLOBALS['TCA'][$queryTable]) || !count($GLOBALS['TCA'][$queryTable])) { continue; } $config = (array) $wizardConfig['default']; if (is_array($wizardConfig[$queryTable])) { $config = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($config, $wizardConfig[$queryTable]); } // merge the configurations of different "levels" to get the working configuration for this table and // field (i.e., go from the most general to the most special configuration) if (is_array($TSconfig['TCEFORM.']['suggest.']['default.'])) { $config = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.']['suggest.']['default.']); } if (is_array($TSconfig['TCEFORM.']['suggest.'][$queryTable . '.'])) { $config = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.']['suggest.'][$queryTable . '.']); } // use $table instead of $queryTable here because we overlay a config // for the input-field here, not for the queried table if (is_array($TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.']['default.'])) { $config = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.']['default.']); } if (is_array($TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.'][$queryTable . '.'])) { $config = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.'][$table . '.'][$field . '.']['suggest.'][$queryTable . '.']); } //process addWhere if (!isset($config['addWhere']) && $foreign_table_where) { $config['addWhere'] = $foreign_table_where; } if (isset($config['addWhere'])) { $config['addWhere'] = strtr(' ' . $config['addWhere'], array('###THIS_UID###' => intval($uid), '###CURRENT_PID###' => intval($pageId))); } // instantiate the class that should fetch the records for this $queryTable $receiverClassName = $config['receiverClass']; if (!class_exists($receiverClassName)) { $receiverClassName = 'TYPO3\\CMS\\Backend\\Form\\Element\\SuggestDefaultReceiver'; } $receiverObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($receiverClassName, $queryTable, $config); $params = array('value' => $search); $rows = $receiverObj->queryTable($params); if (empty($rows)) { continue; } $resultRows = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge($resultRows, $rows); unset($rows); } $listItems = array(); if (count($resultRows) > 0) { // traverse all found records and sort them $rowsSort = array(); foreach ($resultRows as $key => $row) { $rowsSort[$key] = $row['text']; } asort($rowsSort); $rowsSort = array_keys($rowsSort); // Limit the number of items in the result list $maxItems = $config['maxItemsInResultList'] ? $config['maxItemsInResultList'] : 10; $maxItems = min(count($resultRows), $maxItems); // put together the selector entry for ($i = 0; $i < $maxItems; $i++) { $row = $resultRows[$rowsSort[$i]]; $rowId = $row['table'] . '-' . $row['uid'] . '-' . $table . '-' . $uid . '-' . $field; $listItems[] = '<li' . ($row['class'] != '' ? ' class="' . $row['class'] . '"' : '') . ' id="' . $rowId . '" style="' . $row['style'] . '">' . $row['text'] . '</li>'; } } if (count($listItems) > 0) { $list = implode('', $listItems); } else { $list = '<li class="suggest-noresults"><i>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.noRecordFound') . '</i></li>'; } $list = '<ul class="' . $this->cssClass . '-resultlist">' . $list . '</ul>'; $ajaxObj->addContent(0, $list); }
/** * Build the mail content * * @param integer $curPage Id of the current page * @param string $pageList List of pages id * @param array $markerArray Array of markers * @param array $oldBrokenLink Marker array with the number of link found * @return string Content of the mail */ protected function buildMail($curPage, $pageList, array $markerArray, array $oldBrokenLink) { $pageSectionHtml = \TYPO3\CMS\Core\Html\HtmlParser::getSubpart($this->templateMail, '###PAGE_SECTION###'); // Hook if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['buildMailMarkers'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['linkvalidator']['buildMailMarkers'] as $userFunc) { $params = array('curPage' => $curPage, 'pageList' => $pageList, 'markerArray' => $markerArray, 'oldBrokenLink' => $oldBrokenLink, 'pObj' => &$this); $newMarkers = GeneralUtility::callUserFunction($userFunc, $params, $this); if (is_array($newMarkers)) { $markerArray = GeneralUtility::array_merge($markerArray, $newMarkers); } unset($params); } } if (is_array($markerArray)) { foreach ($markerArray as $markerKey => $markerValue) { if (empty($oldBrokenLink[$markerKey])) { $oldBrokenLink[$markerKey] = 0; } if ($markerValue != $oldBrokenLink[$markerKey]) { $this->isDifferentToLastRun = TRUE; } $markerArray[$markerKey . '_old'] = $oldBrokenLink[$markerKey]; } } $markerArray['title'] = BackendUtility::getRecordTitle('pages', BackendUtility::getRecord('pages', $curPage)); $content = ''; if ($markerArray['brokenlinkCount'] > 0) { $content = \TYPO3\CMS\Core\Html\HtmlParser::substituteMarkerArray($pageSectionHtml, $markerArray, '###|###', TRUE, TRUE); } return $content; }
/** * Test demonstrating array_merge. This is actually * a native PHP operator, therefore this test is mainly used to * show how this function can be used. * * @test */ public function arrayMergeKeepsIndexesAfterMerge() { $array1 = array(10 => 'FOO', '20' => 'BAR'); $array2 = array('5' => 'PLONK'); $expected = array('5' => 'PLONK', 10 => 'FOO', '20' => 'BAR'); $this->assertEquals($expected, Utility\GeneralUtility::array_merge($array1, $array2)); }
/** * Construct the unique reference identifier of the current page * * @param \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $fe Frontend engine * @return string Unique reference identifier */ public function _getPageReference(\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $fe) { $reference = array(); $parameters = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge(\TYPO3\CMS\Core\Utility\GeneralUtility::array_merge(array('id' => $fe->id, 'type' => $fe->type), $_GET), $_POST); $parameters['id'] = intval($parameters['id']); $parameters['type'] = intval($parameters['type']); foreach (self::indexConfig($fe, 'reference') as $key => $config) { $referenceVariable = $this->_getReferenceVariable($parameters, $key, $config); if ($referenceVariable != null) { $reference[$key] = $referenceVariable; } } ksort($reference); return serialize($reference); }
/** * Gets all "lang_ and label_" Marker for * substition with substituteMarkerArray. * * @return void */ public function generateLanguageMarker() { if (is_array($this->LOCAL_LANG[$this->getFrontendController()->tmpl->setup['config.']['language']]) && is_array($this->LOCAL_LANG['default'])) { $markerArr = GeneralUtility::array_merge($this->LOCAL_LANG['default'], $this->LOCAL_LANG[$this->getFrontendController()->tmpl->setup['config.']['language']]); } elseif (is_array($this->LOCAL_LANG['default'])) { $markerArr = $this->LOCAL_LANG['default']; } else { $markerArr = $this->LOCAL_LANG[$this->getFrontendController()->tmpl->setup['config.']['language']]; } foreach (array_keys($markerArr) as $languageKey) { if (stristr($languageKey, 'lang_') or stristr($languageKey, 'label_')) { $this->languageMarker['###' . strtoupper($languageKey) . '###'] = $this->pi_getLL($languageKey); } } }
/** * add localized page records to a cache/globalArray * This is much faster than requesting the DB for each tt_content-record * * @param array $pageRow * @return void */ public function addLocalizedPagesToCache($pageRow) { // create entry in cachedPageRecods for default language $this->cachedPageRecords[0][$pageRow['uid']] = $pageRow; // create entry in cachedPageRecods for additional languages, skip default language 0 foreach ($this->sysLanguages as $sysLang) { if ($sysLang[1] > 0) { list($pageOverlay) = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordsByField('pages_language_overlay', 'pid', $pageRow['uid'], 'AND sys_language_uid=' . intval($sysLang[1])); if ($pageOverlay) { $this->cachedPageRecords[$sysLang[1]][$pageRow['uid']] = \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge($pageRow, $pageOverlay); } } } }
/** * main method which controls the data flow and outputs the addresses * * @param string $content Content string, empty * @param array $conf Configuration array with TS configuration * @return string The processed addresses */ public function main($content, $conf) { $this->init($conf); $content = ''; $singleSelection = $this->getSingleRecords(); $groupSelection = $this->getRecordsFromGroups(); // merge both arrays so that we do not have any duplicates $addresses = GeneralUtility::array_merge($singleSelection, $groupSelection); $templateCode = $this->getTemplate(); // apply sorting if ($this->conf['sortByColumn'] === 'singleSelection' && count($groupSelection) === 0) { // we want to sort by single selection and only have single record selection $sortedAdressesUid = explode(',', $this->conf['singleSelection']); $sortedAddresses = array(); foreach ($sortedAdressesUid as $uid) { $sortedAddresses[] = $addresses[$uid]; } $addresses = $sortedAddresses; } else { // if sortByColumn was set to singleSelection, but we don't have a single selection, switch to default column "name" if ($this->conf['sortByColumn'] === 'singleSelection') { $this->conf['sortByColumn'] = 'name'; } // sorting the addresses by any other field $sortBy = array(); foreach ($addresses as $k => $v) { $sortBy[$k] = $this->normalizeSortingString($v[$this->conf['sortByColumn']]); } array_multisort($sortBy, $this->conf['sortOrder'], $addresses); } // limit output to max listMaxItems addresses if ((int) $this->conf['listMaxItems'] > 0) { $addresses = array_slice($addresses, 0, (int) $this->conf['listMaxItems']); } // output foreach ($addresses as $address) { if (!empty($address)) { $markerArray = $this->getItemMarkerArray($address); $subpartArray = $this->getSubpartArray($templateCode, $markerArray, $address); $addressContent = $this->cObj->substituteMarkerArrayCached($templateCode, $markerArray, $subpartArray); $wrap = $this->conf['templates.'][$this->conf['templateName'] . '.']['wrap']; $content .= $this->cObj->wrap($addressContent, $wrap); $content .= chr(10) . chr(10); } } $templateAllWrap = $this->conf['templates.'][$this->conf['templateName'] . '.']['allWrap']; $content = $this->cObj->wrap($content, $templateAllWrap); $overallWrap = $this->conf['wrap']; $content = $this->cObj->wrap($content, $overallWrap); return $this->pi_wrapInBaseClass($content); }
/** * action show * * @return void */ public function showAction() { // Assign multiple values $viewAssign = array(); $this->cObj = $this->configurationManager->getContentObject(); $this->data = $this->cObj->data; $viewAssign['uid'] = $this->data['uid']; switch ($this->settings['contenttype']) { case 'iframe': $viewAssign = GeneralUtility::array_merge($viewAssign, $this->iframe()); break; case 'reference': case 'inline': if ($this->settings['content']['procedure_reference'] == 'ajax' && !empty($this->settings['contenttype']) || $this->settings['content']['procedure_inline'] == 'ajax') { $viewAssign = GeneralUtility::array_merge($viewAssign, $this->ajax()); } elseif (($this->settings['content']['procedure_reference'] && !empty($this->settings['contenttype'])) == 'inline' || $this->settings['content']['procedure_inline'] == 'inline') { $viewAssign = GeneralUtility::array_merge($viewAssign, $this->inline()); } elseif ($this->settings['content']['procedure_reference'] == '' && $this->settings['content']['procedure_inline'] == '') { // Add error if no method (inline or ajax) has been selected $this->addFlashMessage('Please select the method (inline or ajax) to display Magnific Popup content', 'Select method', AbstractMessage::WARNING); } elseif ($this->settings['content']['procedure_reference'] != '' && empty($this->settings['contenttype'])) { // Add error if no content has been selected $this->addFlashMessage('Please select a content to display with Magnific Popup', 'Select content', AbstractMessage::WARNING); } break; default: // Add error if no "Display type" has been selected $this->addFlashMessage('Please select a "Display type" to use Magnific Popup', 'Select "Display type"', AbstractMessage::WARNING); } // Signal for show action (may be used to modify the array assigned to fluid-template) $this->signalSlotDispatcher->dispatch(__CLASS__, __FUNCTION__, array('data' => $this->data, 'settings' => $this->settings, 'viewAssign' => &$viewAssign)); // Assign array to fluid-template $this->view->assignMultiple($viewAssign); }
/** * Will select all fe_groups records that the current fe_user is member of * and which groups are also allowed in the current domain. * It also accumulates the TSconfig for the fe_user/fe_groups in ->TSdataArray * * @return integer Returns the number of usergroups for the frontend users (if the internal user record exists and the usergroup field contains a value) * @todo Define visibility */ public function fetchGroupData() { $this->TSdataArray = array(); $this->userTS = array(); $this->userTSUpdated = FALSE; $this->groupData = array('title' => array(), 'uid' => array(), 'pid' => array()); // Setting default configuration: $this->TSdataArray[] = $GLOBALS['TYPO3_CONF_VARS']['FE']['defaultUserTSconfig']; // Get the info data for auth services $authInfo = $this->getAuthInfoArray(); if ($this->writeDevLog) { if (is_array($this->user)) { GeneralUtility::devLog('Get usergroups for user: '******'TYPO3\\CMS\\Frontend\\Authentication\\FrontendUserAuthentication'); } else { GeneralUtility::devLog('Get usergroups for "anonymous" user', 'TYPO3\\CMS\\Frontend\\Authentication\\FrontendUserAuthentication'); } } $groupDataArr = array(); // Use 'auth' service to find the groups for the user $serviceChain = ''; $subType = 'getGroups' . $this->loginType; while (is_object($serviceObj = GeneralUtility::makeInstanceService('auth', $subType, $serviceChain))) { $serviceChain .= ',' . $serviceObj->getServiceKey(); $serviceObj->initAuth($subType, array(), $authInfo, $this); $groupData = $serviceObj->getGroups($this->user, $groupDataArr); if (is_array($groupData) && count($groupData)) { // Keys in $groupData should be unique ids of the groups (like "uid") so this function will override groups. $groupDataArr = GeneralUtility::array_merge($groupDataArr, $groupData); } unset($serviceObj); } if ($this->writeDevLog && $serviceChain) { GeneralUtility::devLog($subType . ' auth services called: ' . $serviceChain, 'TYPO3\\CMS\\Frontend\\Authentication\\FrontendUserAuthentication'); } if ($this->writeDevLog && !count($groupDataArr)) { GeneralUtility::devLog('No usergroups found by services', 'TYPO3\\CMS\\Frontend\\Authentication\\FrontendUserAuthentication'); } if ($this->writeDevLog && count($groupDataArr)) { GeneralUtility::devLog(count($groupDataArr) . ' usergroup records found by services', 'TYPO3\\CMS\\Frontend\\Authentication\\FrontendUserAuthentication'); } // Use 'auth' service to check the usergroups if they are really valid foreach ($groupDataArr as $groupData) { // By default a group is valid $validGroup = TRUE; $serviceChain = ''; $subType = 'authGroups' . $this->loginType; while (is_object($serviceObj = GeneralUtility::makeInstanceService('auth', $subType, $serviceChain))) { $serviceChain .= ',' . $serviceObj->getServiceKey(); $serviceObj->initAuth($subType, array(), $authInfo, $this); if (!$serviceObj->authGroup($this->user, $groupData)) { $validGroup = FALSE; if ($this->writeDevLog) { GeneralUtility::devLog($subType . ' auth service did not auth group: ' . GeneralUtility::arrayToLogString($groupData, 'uid,title'), 'TYPO3\\CMS\\Frontend\\Authentication\\FrontendUserAuthentication', 2); } break; } unset($serviceObj); } unset($serviceObj); if ($validGroup && (string) $groupData['uid'] !== '') { $this->groupData['title'][$groupData['uid']] = $groupData['title']; $this->groupData['uid'][$groupData['uid']] = $groupData['uid']; $this->groupData['pid'][$groupData['uid']] = $groupData['pid']; $this->groupData['TSconfig'][$groupData['uid']] = $groupData['TSconfig']; } } if (count($this->groupData) && count($this->groupData['TSconfig'])) { // TSconfig: collect it in the order it was collected foreach ($this->groupData['TSconfig'] as $TSdata) { $this->TSdataArray[] = $TSdata; } $this->TSdataArray[] = $this->user['TSconfig']; // Sort information ksort($this->groupData['title']); ksort($this->groupData['uid']); ksort($this->groupData['pid']); } return count($this->groupData['uid']) ?: 0; }