/** * Wrapper for \TYPO3\CMS\Frontend\Page\PageRepository::getMenu() * Caution: different signature * * @param integer $pageUid * @param array $excludePages * @param string $where * @param boolean $showHiddenInMenu * @param boolean $checkShortcuts * @param array $allowedDoktypeList * @return array */ public function getMenu($pageUid = NULL, $excludePages = array(), $where = '', $showHiddenInMenu = FALSE, $checkShortcuts = FALSE, $allowedDoktypeList = array()) { if (NULL === $pageUid) { $pageUid = $GLOBALS['TSFE']->id; } $addWhere = self::$pageSelect->enableFields('pages', 0); if (0 < count($allowedDoktypeList)) { $addWhere .= ' AND doktype IN (' . implode(',', $allowedDoktypeList) . ')'; } else { $addWhere .= ' AND doktype != ' . PageRepository::DOKTYPE_SYSFOLDER; } if (0 < count($excludePages)) { $addWhere .= ' AND uid NOT IN (' . implode(',', $excludePages) . ')'; } if (FALSE === (bool) $showHiddenInMenu) { $addWhere .= ' AND nav_hide=0'; } if ('' !== $where) { $addWhere = $where . ' ' . $addWhere; } $key = md5(intval($showHiddenInMenu) . $pageUid . $addWhere . intval($checkShortcuts)); if (FALSE === isset(self::$cachedMenus[$key])) { self::$cachedMenus[$key] = self::$pageSelect->getMenu($pageUid, '*', 'sorting', $addWhere, $checkShortcuts); } return self::$cachedMenus[$key]; }
/** * @test */ public function enableFieldsDoesNotHideVersionedRecordsWhenCheckingVersionOverlays() { $table = $this->getUniqueId('aTable'); $GLOBALS['TCA'] = array($table => array('ctrl' => array('versioningWS' => 2))); $this->pageSelectObject->versioningPreview = TRUE; $this->pageSelectObject->init(FALSE); $conditions = $this->pageSelectObject->enableFields($table, -1, array(), TRUE); $this->assertThat($conditions, $this->logicalNot($this->stringContains(' AND ' . $table . '.t3ver_state<=0')), 'No versioning placeholders'); $this->assertThat($conditions, $this->logicalNot($this->stringContains(' AND ' . $table . '.pid<>-1')), 'No ecords from page -1'); }
/** * Wrapper function for \TYPO3\CMS\Frontend\Page\PageRepository::enableFields() since it is no * longer accessible statically. * * Returns a part of a WHERE clause which will filter out records with * start/end times or deleted/hidden/fe_groups fields set to values that * should de-select them according to the current time, preview settings or * user login. * Is using the $TCA arrays "ctrl" part where the key "enablefields" * determines for each table which of these features applies to that table. * * @param string $tableName * table name found in the $TCA array * @param int $showHidden * If $showHidden is set (0/1), any hidden-fields in records are * ignored. NOTICE: If you call this function, consider what to do * with the show_hidden parameter. * @param array $ignoreArray * Array you can pass where keys can be "disabled", "starttime", * "endtime", "fe_group" (keys from "enablefields" in TCA) and if set * they will make sure that part of the clause is not added. Thus * disables the specific part of the clause. For previewing etc. * @param bool $noVersionPreview * If set, enableFields will be applied regardless of any versioning * preview settings which might otherwise disable enableFields. * * @return string the WHERE clause starting like " AND ...=... AND ...=..." * * @throws InvalidArgumentException */ public static function enableFields($tableName, $showHidden = -1, array $ignoreArray = array(), $noVersionPreview = false) { if (!in_array($showHidden, array(-1, 0, 1))) { throw new InvalidArgumentException('$showHidden may only be -1, 0 or 1, but actually is ' . $showHidden, 1331315445); } // maps $showHidden (-1..1) to (0..2) which ensures valid array keys $showHiddenKey = $showHidden + 1; $ignoresKey = serialize($ignoreArray); $previewKey = (int) $noVersionPreview; if (!isset(self::$enableFieldsCache[$tableName][$showHiddenKey][$ignoresKey][$previewKey])) { self::retrievePageForEnableFields(); self::$enableFieldsCache[$tableName][$showHiddenKey][$ignoresKey][$previewKey] = self::$pageForEnableFields->enableFields($tableName, $showHidden, $ignoreArray, $noVersionPreview); } return self::$enableFieldsCache[$tableName][$showHiddenKey][$ignoresKey][$previewKey]; }
/** * Get alle images on the given pages * * @param array $pages * * @return array */ protected function getImagesByPages(array $pages) { $images = array(); if (!sizeof($pages)) { return $images; } $enabledFields = $this->pageRepository->enableFields('sys_file_reference'); $enabledFields .= $this->pageRepository->enableFields('tt_content'); $enabledFields .= $this->pageRepository->enableFields('pages'); $rows = $this->getDatabaseConnection()->exec_SELECTgetRows('sys_file_reference.*', 'sys_file_reference, tt_content, pages', 'sys_file_reference.tablenames = \'tt_content\' AND sys_file_reference.fieldname =\'image\' AND sys_file_reference.uid_foreign = tt_content.uid AND tt_content.pid = pages.uid AND pages.uid IN (' . implode(',', $pages) . ') ' . $enabledFields); foreach ($rows as $row) { $images[] = $this->resourceFactory->getFileReferenceObject($row['uid'], $row); } return $images; }
/** * Returns all accessible error pages from all websites. * * @return array<\R3H6\Error404page\Domain\Model\Page> */ protected function findAllByDoktype($doktype) { if (!isset($this->cachedPagesByDoktype[$doktype])) { $result = $this->getDatabaseConnection()->exec_SELECTquery('uid', 'pages', sprintf('doktype=%d', $doktype) . $this->pageRepository->enableFields('pages'), '', 'sorting'); $pages = array(); while ($record = $this->getDatabaseConnection()->sql_fetch_assoc($result)) { $page = $this->findByIdentifier($record['uid']); if ($page !== null) { $pages[] = $page; } } $this->getLogger()->debug(sprintf('Found "%d" pages for doktype "%d"', count($pages), $doktype)); $this->cachedPagesByDoktype[$doktype] = $pages; } return $this->cachedPagesByDoktype[$doktype]; }
/** * Find the minimum starttime or endtime value in the table and pid that is greater than the current time. * * @param string $tableDef Table definition (format tablename:pid) * @param integer $now "Now" time value * @return integer Value of the next start/stop time or PHP_INT_MAX if not found * @see tslib_fe::calculatePageCacheTimeout() */ protected function getFirstTimeValueForRecord($tableDef, $now) { $result = PHP_INT_MAX; list($tableName, $pid) = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(':', $tableDef); if (empty($tableName) || empty($pid)) { throw new \InvalidArgumentException('Unexpected value for parameter $tableDef. Expected <tablename>:<pid>, got \'' . htmlspecialchars($tableDef) . '\'.', 1307190365); } // Additional fields $showHidden = $tableName === 'pages' ? $this->showHiddenPage : $this->showHiddenRecords; $enableFields = $this->sys_page->enableFields($tableName, $showHidden, array('starttime' => TRUE, 'endtime' => TRUE)); // For each start or end time field, get the minimum value foreach (array('starttime', 'endtime') as $field) { // Note: there is no need to load TCA because we need only enable columns! if (isset($GLOBALS['TCA'][$tableName]['ctrl']['enablecolumns'][$field])) { $timeField = $GLOBALS['TCA'][$tableName]['ctrl']['enablecolumns'][$field]; $selectField = 'MIN(' . $timeField . ') AS ' . $field; $whereCondition = $timeField . ' > ' . $now; // Find the smallest timestamp which could influence the cache duration (but is larger than 0) $row = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow($selectField, $tableName, 'pid = ' . intval($pid) . ' AND ' . $whereCondition . $enableFields); if ($row && !is_null($row[$timeField])) { $result = min($result, $row[$timeField]); } } } return $result; }
/** * Fetches/returns the cached contents of the sys_domain database table. * * @return array Domain data */ protected function getSysDomainCache() { $entryIdentifier = 'core-database-sys_domain-complete'; /** @var $runtimeCache \TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend */ $runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime'); $sysDomainData = array(); if ($runtimeCache->has($entryIdentifier)) { $sysDomainData = $runtimeCache->get($entryIdentifier); } else { $domainRecords = $this->getDatabaseConnection()->exec_SELECTgetRows('uid, pid, domainName, forced', 'sys_domain', 'redirectTo=\'\' ' . $this->sys_page->enableFields('sys_domain', 0), '', 'sorting ASC'); foreach ($domainRecords as $row) { // if there is already an entry for this pid, check if we should overwrite it if (isset($sysDomainData[$row['pid']])) { // There is already a "forced" entry, which must not be overwritten if ($sysDomainData[$row['pid']]['forced']) { continue; } // The current domain record is also NOT-forced, keep the old unless the new one matches the current request if (!$row['forced'] && !$this->domainNameMatchesCurrentRequest($row['domainName'])) { continue; } } // as we passed all previous checks, we save this domain for the current pid $sysDomainData[$row['pid']] = array('uid' => $row['uid'], 'pid' => $row['pid'], 'domainName' => rtrim($row['domainName'], '/'), 'forced' => $row['forced']); } $runtimeCache->set($entryIdentifier, $sysDomainData); } return $sysDomainData; }
public function findByDomainName($domainName) { $domains = $this->getDatabaseConnection()->exec_SELECTgetRows('*', 'sys_domain', "redirectTo='' AND domainName=" . $this->getDatabaseConnection()->fullQuoteStr($domainName, 'sys_domain') . " " . $this->pageRepository->enableFields('sys_domain')); return (array) $domains; }
/** * @param int $startPageId * @return array */ private function getSubPages($startPageId) { return $this->pageRepo->getMenu($startPageId, '*', 'sorting', $this->pageRepo->enableFields('pages') . 'AND ' . UrlEntry::EXCLUDE_FROM_SITEMAP . '!=1'); }
public function purge($simulate) { $this->output->info('Purge deleted'); $this->purgeDeleted('sys_file_reference', $simulate); $this->db->exec_DELETEquery('sys_file_reference', 'tablenames = \'\' OR fieldname = \'\''); $delete = new PreparedStatement('DELETE FROM sys_file_reference WHERE uid = ?', 'sys_file_reference'); $this->output->info('Purge references pointing to deleted records'); $res = $this->db->exec_SELECTquery('*', 'sys_file_reference', ''); $pageTools = new PageRepository(); $pageTools->init(FALSE); while ($row = $this->db->sql_fetch_assoc($res)) { $cnt = $this->db->exec_SELECTcountRows('uid', $row['tablenames'], 'uid = ' . $row['uid_foreign'] . $pageTools->enableFields($row['tablenames'])); if (!$cnt) { if ($simulate) { $this->output->info('Would delete reference ' . $row['uid']); } else { $delete->execute(array($row['uid'])); $this->output->info('Deleted reference ' . $row['uid']); } } } $delete->free(); $this->output->info('Purge sys_file records with no references'); $delete = new PreparedStatement('DELETE FROM sys_file WHERE uid = ?', 'sys_file'); $res = $this->db->exec_SELECTquery('uid', 'sys_file', 'uid NOT IN (select uid_local from sys_file_reference group by uid_local)'); while ($row = $this->db->sql_fetch_assoc($res)) { if ($simulate) { $this->output->info('Would delete file record %s', array($row['uid'])); } else { $delete->execute(array($row['uid'])); $this->output->info('Deleted file record <b>%s</b>', array($row['uid'])); } } $this->output->info('Purge actual files with no record'); $prefixRegex = '/^' . preg_quote(PATH_site, '/') . '(fileadmin|uploads)/'; $files = new \RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(PATH_site, RecursiveDirectoryIterator::SKIP_DOTS | RecursiveDirectoryIterator::UNIX_PATHS), RecursiveIteratorIterator::LEAVES_ONLY | RecursiveIteratorIterator::CHILD_FIRST), $prefixRegex); $exists = new PreparedStatement('SELECT uid FROM sys_file WHERE identifier = ?', 'sys_file'); $fileSize = 0; foreach ($files as $file) { $filename = (string) $file; if (!is_file($filename)) { continue; } $fileId = preg_replace($prefixRegex, '', $filename); $exists->execute(array($fileId)); $result = $exists->fetchAll(); if (empty($result[0]['uid'])) { $fileSize += filesize($filename); if ($simulate) { $this->output->info('<i>Would delete file %s</i>', array($filename)); } else { unlink($filename); $this->output->info('Delete file %s', array($filename)); } } } $size = GeneralUtility::formatSize($fileSize); if ($simulate) { $this->output->info('Would delete %s of files', array($size)); $this->output->info('Would truncate table sys_file_processedfile'); } else { $this->output->info('Deleted %s of files', array($size)); $this->db->exec_TRUNCATEquery('sys_file_processedfile'); $this->output->info('Truncated table sys_file_processedfile'); } }