includeLLfile('EXT:realurl/modfunc1/locallang.xml'); if (version_compare(TYPO3_branch, '6.0', '<')) { /** @noinspection PhpDeprecationInspection */ class modfunc_base extends t3lib_extobjbase {} } else { class modfunc_base extends \TYPO3\CMS\Backend\Module\AbstractFunctionModule {} } /** * Speaking Url management extension * * @author Kasper Skaarhoj * @package TYPO3 * @subpackage tx_realurl */ class tx_realurl_modfunc1 extends modfunc_base { /** @var tx_realurl_apiwrapper */ protected $apiWrapper; /** @var t3lib_beUserAuth|\TYPO3\CMS\Core\Authentication\BackendUserAuthentication */ protected $beUser; /** @var t3lib_DB */ protected $database; /** @var language */ protected $language; // Internal, dynamic: var $searchResultCounter = 0; public function __construct() { $this->apiWrapper = tx_realurl_apiwrapper::getInstance(); $this->beUser = $GLOBALS['BE_USER']; $this->database = $GLOBALS['TYPO3_DB']; $this->language = $GLOBALS['LANG']; } /** * Returns the menu array * * @return array */ function modMenu() { $modMenu = array( 'depth' => array( 0 => $this->language->sL('LLL:EXT:lang/locallang_core.php:labels.depth_0'), 1 => $this->language->sL('LLL:EXT:lang/locallang_core.php:labels.depth_1'), 2 => $this->language->sL('LLL:EXT:lang/locallang_core.php:labels.depth_2'), 3 => $this->language->sL('LLL:EXT:lang/locallang_core.php:labels.depth_3'), 99 => $this->language->sL('LLL:EXT:lang/locallang_core.php:labels.depth_infi'), ), 'type' => array( 'pathcache' => 'ID-to-path mapping', 'decode' => 'Decode cache', 'encode' => 'Encode cache', 'uniqalias' => 'Unique Aliases', 'redirects' => 'Redirects', 'config' => 'Configuration', 'log' => 'Error Log' ) ); $modMenu['type'] = $this->apiWrapper->unsetMenuItems($this->pObj->modTSconfig['properties'], $modMenu['type'], 'menu.realurl_type'); return $modMenu; } /** * MAIN function for cache information * * @return string Output HTML for the module. */ function main() { if ($this->pObj->id) { $result = $this->createModuleContentForPage(); } else { $result = '

' . $this->language->getLL('no_page_id') . '

'; } return $result; } /** * Enter description here ... */ protected function createModuleContentForPage() { $this->addModuleStyles(); $result = $this->getFunctionMenu() . ' '; switch ($this->pObj->MOD_SETTINGS['type']) { case 'pathcache': $this->edit_save(); $result .= $this->getDepthSelector(); $moduleContent = $this->renderModule($this->initializeTree()); $result .= $this->renderSearchForm(); $result .= $moduleContent; break; case 'encode': $result .= $this->getDepthSelector(); $result .= $this->encodeView($this->initializeTree()); break; case 'decode': $result .= $this->getDepthSelector(); $result .= $this->decodeView($this->initializeTree()); break; case 'uniqalias': $this->edit_save_uniqAlias(); $result .= $this->uniqueAlias(); break; case 'config': $result .= $this->getDepthSelector(); $result .= $this->configView(); break; case 'redirects': $result .= $this->redirectView(); break; case 'log': $result .= $this->logView(); break; } return $result; } /** * Obtains function selection menu. * * @return string */ protected function getFunctionMenu() { return $this->language->getLL('function') . ' ' . $this->apiWrapper->getFuncMenu($this->pObj->id, 'SET[type]', $this->pObj->MOD_SETTINGS['type'], $this->pObj->MOD_MENU['type']); } /** * Adds module-specific styles to the output. * * @return void */ protected function addModuleStyles() { $this->pObj->doc->inDocStyles .= ' TABLE.c-list TR TD { white-space: nowrap; vertical-align: top; } TABLE#tx-realurl-pathcacheTable TD { vertical-align: top; } FIELDSET { border: none; padding: 16px 0; } FIELDSET DIV { clear: left; border-collapse: collapse; margin-bottom: 5px; } FIELDSET DIV LABEL { display: block; float: left; width: 100px; } ' . tx_realurl_pagebrowser::getInlineStyles(); } /** * Creates depth selector HTML for the page tree. * * @return string */ protected function getDepthSelector() { return $this->language->getLL('depth') . $this->apiWrapper->getFuncMenu($this->pObj->id, 'SET[depth]', $this->pObj->MOD_SETTINGS['depth'], $this->pObj->MOD_MENU['depth']); } /** * Initializes the page tree. * * @return t3lib_pageTree|\TYPO3\CMS\Backend\Tree\View\PageTreeView */ protected function initializeTree() { $tree = $this->apiWrapper->getPageTree(); $tree->addField('nav_title', TRUE); $tree->addField('alias', TRUE); $tree->addField('tx_realurl_pathsegment', TRUE); $tree->init('AND ' . $this->beUser->getPagePermsClause(1)); $treeStartingPoint = intval($this->pObj->id); $treeStartingRecord = $this->apiWrapper->getRecord('pages', $treeStartingPoint); $this->apiWrapper->workspaceOL('pages', $treeStartingRecord); // Creating top icon; the current page $tree->tree[] = array( 'row' => $treeStartingRecord, 'HTML' => $this->apiWrapper->getIconImage('pages', $treeStartingRecord, $GLOBALS['BACK_PATH'], 'align="top"') ); // Create the tree from starting point: if ($this->pObj->MOD_SETTINGS['depth'] > 0) { $tree->getTree($treeStartingPoint, $this->pObj->MOD_SETTINGS['depth'], ''); } return $tree; } /** * Rendering the information * * @param t3lib_pageTree|\TYPO3\CMS\Backend\Tree\View\PageTreeView The Page tree data * @return string HTML for the information table. */ function renderModule($tree) { // Initialize $searchPath = trim($this->apiWrapper->_GP('pathPrefixSearch')); $cmd = $this->apiWrapper->_GET('cmd'); $entry = $this->apiWrapper->_GET('entry'); $searchForm_replace = $this->apiWrapper->_POST('_replace'); $searchForm_delete = $this->apiWrapper->_POST('_delete'); $trackSameUrl = array(); $this->searchResultCounter = 0; // Traverse tree: $output = ''; $cc = 0; foreach ($tree->tree as $row) { // Get all pagepath entries for page: $pathCacheInfo = $this->getPathCache($row['row']['uid']); // Row title: $rowTitle = $row['HTML'] . $this->apiWrapper->getRecordTitle('pages', $row['row'], TRUE); $cellAttrib = ($row['row']['_CSSCLASS'] ? ' class="' . $row['row']['_CSSCLASS'] . '"' : ''); // Add at least one empty element: if (!count($pathCacheInfo)) { // Add title: $tCells = array(); $tCells[] = '' . $rowTitle . ''; // Empty row: $tCells[] = ' '; // Compile Row: $output .= ' ' . implode(' ', $tCells) . ' '; $cc++; } else { foreach ($pathCacheInfo as $c => $inf) { // Init: $deletedEntry = FALSE; $hash = $inf['pagepath'] . '|' . $inf['rootpage_id'] . '|' . $inf['language_id']; // MP is not a part of this because the path itself should be different simply because the MP makes a different path! (see tx_realurl_advanced::pagePathtoID()) // Add icon/title and ID: $tCells = array(); if (!$c) { $tCells[] = '' . $rowTitle . ''; $tCells[] = '' . $inf['page_id'] . ''; } // Add values from alternative field used to generate URL: $baseRow = $row['row']; // page row as base. $onClick = $this->apiWrapper->editOnClick('&edit[pages][' . $row['row']['uid'] . ']=edit&columnsOnly=title,nav_title,alias,tx_realurl_pathsegment', $this->pObj->doc->backPath); $editIcon = '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/edit2.gif', 'width="11" height="12"') . ' title="" alt="" />' . ''; $onClick = $this->apiWrapper->viewOnClick($row['row']['uid'], $this->pObj->doc->backPath, '', '', '', ''); $editIcon .= '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/zoom.gif', 'width="12" height="12"') . ' title="" alt="" />' . ''; if ($inf['language_id'] > 0) { // For alternative languages, show another list of fields, form page overlay record: $editIcon = ''; list($olRec) = $this->apiWrapper->getRecordsByField('pages_language_overlay', 'pid', $row['row']['uid'], ' AND sys_language_uid=' . intval($inf['language_id'])); if (is_array($olRec)) { $baseRow = array_merge($baseRow, $olRec); $onClick = $this->apiWrapper->editOnClick('&edit[pages_language_overlay][' . $olRec['uid'] . ']=edit&columnsOnly=title,nav_title', $this->pObj->doc->backPath); $editIcon = '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/edit2.gif', 'width="11" height="12"') . ' title="" alt="" />' . ''; $onClick = $this->apiWrapper->viewOnClick($row['row']['uid'], $this->pObj->doc->backPath, '', '', '', '&L=' . $olRec['sys_language_uid']); $editIcon .= '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/zoom.gif', 'width="12" height="12"') . ' title="" alt="" />' . ''; } else { $baseRow = array(); } } $tCells[] = '' . $editIcon . ''; // Sources for segment: $sources = count($baseRow) ? implode(' | ', array($baseRow['tx_realurl_pathsegment'], $baseRow['alias'], $baseRow['nav_title'], $baseRow['title'])) : ''; $tCells[] = '' . htmlspecialchars($sources) . ''; // Show page path: if (strcmp($searchPath, '') && $this->apiWrapper->isFirstPartOfStr($inf['pagepath'], $searchPath) && !$inf['expire']) { // Delete entry: if ($searchForm_delete) { $this->deletePathCacheEntry($inf['cache_id']); $deletedEntry = TRUE; $pagePath = '[DELETED]'; } elseif ($searchForm_replace) { $replacePart = trim($this->apiWrapper->_POST('pathPrefixReplace')); $this->editPathCacheEntry($inf['cache_id'], $replacePart . substr($inf['pagepath'], strlen($searchPath))); $pagePath = '' . htmlspecialchars($replacePart) . '' . htmlspecialchars(substr($inf['pagepath'], strlen($searchPath))); } else { $pagePath = '' . htmlspecialchars(substr($inf['pagepath'], 0, strlen($searchPath))) . '' . htmlspecialchars(substr($inf['pagepath'], strlen($searchPath))); $this->searchResultCounter++; } } else { // Delete entries: if ($cmd === 'edit' && (!strcmp($entry, $inf['cache_id']) || !strcmp($entry, 'ALL'))) { $pagePath = ''; if ($cmd === 'edit' && $entry != 'ALL') { $pagePath .= $this->saveCancelButtons(); } } else { $pagePath = htmlspecialchars($inf['pagepath']); } } $tCells[] = '' . $pagePath . ''; if ($deletedEntry) { $tCells[] = ' '; } else { $tCells[] = '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete" alt="" />' . '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/edit2.gif', 'width="11" height="12"') . ' title="Edit" alt="" />' . '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/napshot.gif', 'width="12" height="12"') . ' title="Use for search" alt="" />' . '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/clip_copy.gif', 'width="12" height="12"') . ' title="Copy entry" alt="" />' . '' . ''; } $tCells[] = '' . ($inf['expire'] ? htmlspecialchars($this->apiWrapper->dateTimeAge($inf['expire'], -1)) : '') . ($inf['expire'] ? '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/up.gif', 'width="14" height="14"') . ' title="Set expire time to 30 days" alt="" />' . '' : '') . ''; // Set error msg: $error = ''; if (!strcmp($inf['pagepath'], '')) { if ($row['row']['uid'] != $this->pObj->id) { // Show error of "Empty" only for levels under the root. Yes, we cannot know that the pObj->id is the true root of the site, but at least any SUB page should probably have a path string! $error = $this->pObj->doc->icons(2) . 'Empty'; } } elseif (isset($trackSameUrl[$hash])) { $error = $this->pObj->doc->icons(2) . 'Already used on page ID ' . $trackSameUrl[$hash]; } else { $error = ' '; } $tCells[] = '' . $error . ''; $tCells[] = '' . htmlspecialchars($inf['language_id']) . ''; $tCells[] = '' . htmlspecialchars($inf['mpvar']) . ''; $tCells[] = '' . htmlspecialchars($inf['rootpage_id']) . ''; #$tCells[]=''.htmlspecialchars($this->apiWrapper->datetime($inf['expire'])).' / '.htmlspecialchars($this->apiWrapper->calcAge($inf['expire']-time())).''; $trackSameUrl[$hash] = $inf['page_id']; // Compile Row: $rowClass = 'bgColor' . ($cc % 2 ? '-20' : '-10'); $output .= ' ' . implode(' ', $tCells) . ' '; $cc++; } } } // Create header: $tCells = array(); $tCells[] = 'Title:'; $tCells[] = 'ID:'; $tCells[] = ' '; $tCells[] = 'PathSegment | Alias | NavTitle | Title:'; $tCells[] = 'Pagepath:'; $tCells[] = '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' alt="" />' . '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/edit2.gif', 'width="11" height="12"') . ' title="" alt="" />' . '' . ''; $tCells[] = 'Expires:' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Flush all expired" alt="" />' . '' . ''; $tCells[] = 'Errors:'; $tCells[] = 'Lang:'; $tCells[] = '&MP:'; $tCells[] = 'RootPage ID:'; #$tCells[]='Expire:'; $output = ' ' . implode(' ', $tCells) . ' ' . $output; // Compile final table and return: $output = ' ' . $output . '
'; if ($cmd === 'edit' && $entry == 'ALL') { $output .= $this->saveCancelButtons(); } return $output; } /** * Fetch path caching information for page. * * @param int $pageId Page ID * @return array Path Cache records */ function getPathCache($pageId) { $showLanguage = $this->apiWrapper->_GP('showLanguage'); $cmd = $this->apiWrapper->_GET('cmd'); $entry = $this->apiWrapper->_GET('entry'); $res = $this->database->exec_SELECTquery( '*', 'tx_realurl_pathcache', 'page_id=' . intval($pageId) . ((string)$showLanguage !== '' ? ' AND language_id=' . intval($showLanguage) : ''), '', 'language_id,expire' ); // Traverse result: $output = array(); while (FALSE != ($row = $this->database->sql_fetch_assoc($res))) { // Delete entries: if ($cmd === 'delete' && (!strcmp($entry, $row['cache_id']) || !strcmp($entry, 'ALL'))) { $this->deletePathCacheEntry($row['cache_id']); // Raise expire times: } elseif ($cmd === 'raiseExpire' && !strcmp($entry, $row['cache_id'])) { $this->raiseExpirePathCacheEntry($row); $output[] = $row; } elseif ($cmd === 'flushExpired' && $row['expire'] && $row['expire'] < time()) { $this->deletePathCacheEntry($row['cache_id']); } elseif ($cmd === 'copy' && (!strcmp($entry, $row['cache_id']))) { $output[] = $this->copyPathCacheEntry($row); $output[] = $row; } else { // ... or add: $output[] = $row; } } $this->database->sql_free_result($res); return $output; } /** * Links to the module script and sets necessary parameters (only for pathcache display) * * @param string $addParams Additional GET vars * @return string script + query */ function linkSelf($addParams) { if (version_compare(TYPO3_branch, '6.2', '<')) { $result = htmlspecialchars('index.php?id=' . $this->pObj->id . '&showLanguage=' . rawurlencode($this->apiWrapper->_GP('showLanguage')) . $addParams); } else { $mainParams = array( 'id' => $this->pObj->id, 'showLanguage' => rawurlencode($this->apiWrapper->_GP('showLanguage')) ); $result = \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('M'), $mainParams) . $addParams; } return $result; } /** * Create search form * * @return string HTML */ function renderSearchForm() { $output = '
'; $output .= $this->getLanguageSelector(); $output .= '
' . $this->getSearchField() . '
'; $output .= $this->getReplaceAndDeleteFields(); $output .= ''; $output .= '
'; return $output; } /** * Obtains fields for replace/delete. * * @return string */ private function getReplaceAndDeleteFields() { $output = ''; if ($this->searchResultCounter && !$this->apiWrapper->_POST('_replace') && !$this->apiWrapper->_POST('_delete')) { $output .= '
'; $output .= ' or
'; $output .= '
' . sprintf('Found: %d result(s).', $this->searchResultCounter) . '
'; } return $output; } /** * @return string */ protected function getSearchField() { $output = ' ' . ''; return $output; } /** * Generates language selector. * * @return string */ protected function getLanguageSelector() { $languages = $this->getSystemLanguages(); $options = array(); $showLanguage = $this->apiWrapper->_GP('showLanguage'); foreach ($languages as $language) { $selected = $showLanguage === $language['uid'] ? ' selected="selected"' : ''; $options[] = ''; } return '
'; } /** * Obtains system languages. * * @return array */ protected function getSystemLanguages() { $languages = (array)$this->apiWrapper->getRecordsByField('sys_language', 'pid', 0, '', '', 'title'); $defaultLanguageLabel = $this->getDefaultLanguageName(); array_unshift($languages, array('uid' => 0, 'title' => $defaultLanguageLabel)); array_unshift($languages, array('uid' => '', 'title' => $this->language->getLL('all_languages'))); return $languages; } /** * Obtains the name of the default language. * * @return string */ protected function getDefaultLanguageName() { $tsConfig = $this->apiWrapper->getPagesTSconfig($this->pObj->id); if (isset($tsConfig['mod.']['SHARED.']['defaultLanguageLabel'])) { $label = $tsConfig['mod.']['SHARED.']['defaultLanguageLabel']; } else { $label = $this->language->getLL('default_language'); } return $label; } /** * Deletes an entry in pathcache table * * @param int $cacheId Path Cache id (cache_id) * @return void */ function deletePathCacheEntry($cacheId) { $this->database->exec_DELETEquery('tx_realurl_pathcache', 'cache_id=' . intval($cacheId)); } /** * Deletes an entry in pathcache table * * @param array $row * @return void */ function raiseExpirePathCacheEntry(&$row) { $row['expire'] = time() + 30 * 24 * 3600; $this->database->exec_UPDATEquery('tx_realurl_pathcache', 'expire>0 AND cache_id=' . intval($row['cache_id']), array('expire' => $row['expire'])); } /** * Copies an entry in pathcache table * * @param array $oEntry Record to copy, passed by reference, will be updated. * @return array New record. */ function copyPathCacheEntry(&$oEntry) { // Select old record: $cEntry = $oEntry; unset($cEntry['cache_id']); $this->database->exec_INSERTquery('tx_realurl_pathcache', $cEntry); $cEntry['cache_id'] = $this->database->sql_insert_id(); // Update the old record with expire time: if (!$oEntry['expire']) { $oEntry['expire'] = time() + 30 * 24 * 3600; $field_values = array( 'expire' => $oEntry['expire'], ); $this->database->exec_UPDATEquery('tx_realurl_pathcache', 'cache_id=' . intval($oEntry['cache_id']), $field_values); } return $cEntry; } /** * Changes the "pagepath" value of an entry in the pathcache table * * @param int $cacheId Path Cache id * @param string $value New value for the pagepath * @return void */ function editPathCacheEntry($cacheId, $value) { $field_values = array( 'pagepath' => $value ); $this->database->exec_UPDATEquery('tx_realurl_pathcache', 'cache_id=' . intval($cacheId), $field_values); // Look up the page id so we can clear the encodeCache entries: list($page_id_rec) = $this->database->exec_SELECTgetRows('page_id', 'tx_realurl_pathcache', 'cache_id=' . intval($cacheId)); $this->clearDEncodeCache('page_' . $page_id_rec['page_id']); // Encode cache $this->clearDEncodeCache('page_' . $page_id_rec['page_id'], TRUE); // Decode cache } /** * Will look for submitted pagepath cache entries to save * * @return void */ function edit_save() { if ($this->apiWrapper->_POST('_edit_save')) { $editArray = $this->apiWrapper->_POST('edit'); foreach ($editArray as $cache_id => $value) { $this->editPathCacheEntry($cache_id, trim($value)); } } } /** * Save / Cancel buttons * * @param string $extra Extra code. * @return string Form elements */ function saveCancelButtons($extra = '') { $output = ' '; $output .= ''; $output .= $extra; return $output; } /************************** * * Decode view * **************************/ /** * Rendering the decode-cache content * * @param t3lib_pageTree|\TYPO3\CMS\Backend\Tree\View\PageTreeView The Page tree data * @return string HTML for the information table. */ function decodeView($tree) { // Delete entries: $cmd = $this->apiWrapper->_GP('cmd'); $subcmd = ''; if ($cmd === 'deleteDC') { $subcmd = $this->apiWrapper->_GP('entry'); $this->clearDEncodeCache($subcmd, TRUE); } // Traverse tree: $output = ''; $cc = 0; $countDisplayed = 0; foreach ($tree->tree as $row) { // Select rows: $displayRows = $this->database->exec_SELECTgetRows('*', 'tx_realurl_urldecodecache', 'page_id=' . intval($row['row']['uid']), '', 'spurl'); // Row title: $rowTitle = $row['HTML'] . $this->apiWrapper->getRecordTitle('pages', $row['row'], TRUE); // Add at least one empty element: if (!count($displayRows) || $subcmd === 'displayed') { // Add title: $tCells = array(); $tCells[] = '' . $rowTitle . ''; // Empty row: $tCells[] = ' '; // Compile Row: $output .= ' ' . implode(' ', $tCells) . ' '; $cc++; if ($subcmd === 'displayed') { foreach ($displayRows as $c => $inf) { $this->clearDEncodeCache('urlhash_' . $inf['url_hash'], TRUE); } } } else { foreach ($displayRows as $c => $inf) { // Add icon/title and ID: $tCells = array(); if (!$c) { $tCells[] = '' . $rowTitle . ''; $tCells[] = '' . $row['row']['uid'] . ''; $tCells[] = '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete entries for page" alt="" />' . '' . ''; } // Path: $tCells[] = '' . htmlspecialchars($inf['spurl']) . ''; // Get vars: $queryValues = unserialize($inf['content']); $queryParams = '?id=' . $queryValues['id'] . (is_array($queryValues['GET_VARS']) ? $this->apiWrapper->implodeArrayForUrl('', $queryValues['GET_VARS']) : ''); $tCells[] = '' . htmlspecialchars($queryParams) . ''; // Delete: $tCells[] = '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete entry" alt="" />' . '' . ''; // Timestamp: $tCells[] = '' . htmlspecialchars($this->apiWrapper->datetime($inf['tstamp'])) . ' / ' . htmlspecialchars($this->apiWrapper->calcAge(time() - $inf['tstamp'])) . ''; // Compile Row: $output .= ' ' . implode(' ', $tCells) . ' '; $cc++; $countDisplayed++; } } } list($count_allInTable) = $this->database->exec_SELECTgetRows('count(*) AS count', 'tx_realurl_urldecodecache', ''); // Create header: $tCells = array(); $tCells[] = 'Title:'; $tCells[] = 'ID:'; $tCells[] = ' '; $tCells[] = 'Path:'; $tCells[] = 'GET variables:'; $tCells[] = ' '; $tCells[] = 'Timestamp:'; $output = ' ' . implode(' ', $tCells) . ' ' . $output; // Compile final table and return: $output = '

Displayed entries: ' . $countDisplayed . ' ' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete displayed entries" alt="" />' . '' . '
Total entries in decode cache: ' . $count_allInTable['count'] . ' ' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete WHOLE decode cache!" alt="" />' . '' . '
' . $output . '
'; return $output; } /************************** * * Encode view * **************************/ /** * Rendering the encode-cache content * * @param t3lib_pageTree|\TYPO3\CMS\Backend\Tree\View\PageTreeView The Page tree data * @return string HTML for the information table. */ function encodeView($tree) { // Delete entries: $cmd = $this->apiWrapper->_GP('cmd'); $subcmd = ''; if ($cmd === 'deleteEC') { $subcmd = $this->apiWrapper->_GP('entry'); $this->clearDEncodeCache($subcmd); } // Traverse tree: $cc = 0; $countDisplayed = 0; $output = ''; $duplicates = array(); foreach ($tree->tree as $row) { // Select rows: $displayRows = $this->database->exec_SELECTgetRows('*', 'tx_realurl_urlencodecache', 'page_id=' . intval($row['row']['uid']), '', 'content'); // Row title: $rowTitle = $row['HTML'] . $this->apiWrapper->getRecordTitle('pages', $row['row'], TRUE); // Add at least one empty element: if (!count($displayRows) || $subcmd === 'displayed') { // Add title: $tCells = array(); $tCells[] = '' . $rowTitle . ''; $tCells[] = ' '; // Empty row: $tCells[] = ' '; // Compile Row: $output .= ' ' . implode(' ', $tCells) . ' '; $cc++; if ($subcmd === 'displayed') { foreach ($displayRows as $c => $inf) { $this->clearDEncodeCache('urlhash_' . $inf['url_hash']); } } } else { foreach ($displayRows as $c => $inf) { // Add icon/title and ID: $tCells = array(); if (!$c) { $tCells[] = '' . $rowTitle . ''; $tCells[] = '' . $row['row']['uid'] . ''; $tCells[] = '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete entries for page" alt="" />' . '' . ''; } // Get vars: $tCells[] = '' . htmlspecialchars($this->apiWrapper->fixed_lgd_cs($inf['origparams'], 100)) . ''; // Internal Extras: $tCells[] = '' . ($inf['internalExtras'] ? $this->apiWrapper->arrayToLogString(unserialize($inf['internalExtras'])) : ' ') . ''; // Path: $tCells[] = '' . htmlspecialchars($this->apiWrapper->fixed_lgd_cs($inf['content'], 100)) . ''; // Delete: $tCells[] = '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete entry" alt="" />' . '' . ''; // Error: $eMsg = ($duplicates[$inf['content']] && $duplicates[$inf['content']] !== $row['row']['uid'] ? $this->pObj->doc->icons(2) . 'Already used on page ID ' . $duplicates[$inf['content']] . '
' : ''); if (count($this->database->exec_SELECTgetRows('url_hash', 'tx_realurl_redirects', 'url_hash=' . intval($this->apiWrapper->md5int($inf['content']))))) { $eMsg .= $this->pObj->doc->icons(3) . 'Also a redirect!'; } $tCells[] = '' . $eMsg . ''; // Timestamp: $tCells[] = '' . htmlspecialchars($this->apiWrapper->datetime($inf['tstamp'])) . ' / ' . htmlspecialchars($this->apiWrapper->calcAge(time() - $inf['tstamp'])) . ''; // Compile Row: $output .= ' ' . implode(' ', $tCells) . ' '; $cc++; $countDisplayed++; if (!isset($duplicates[$inf['content']])) { $duplicates[$inf['content']] = $row['row']['uid']; } } } } list($count_allInTable) = $this->database->exec_SELECTgetRows('count(*) AS count', 'tx_realurl_urlencodecache', ''); // Create header: $tCells = array(); $tCells[] = 'Title:'; $tCells[] = 'ID:'; $tCells[] = ' '; $tCells[] = 'Host | GET variables:'; $tCells[] = 'Internal Extras:'; $tCells[] = 'Path:'; $tCells[] = ' '; $tCells[] = 'Errors:'; $tCells[] = 'Timestamp:'; $output = ' ' . implode(' ', $tCells) . ' ' . $output; // Compile final table and return: $output = '

Displayed entries: ' . $countDisplayed . ' ' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete displayed entries" alt="" />' . '' . '
Total entries in encode cache: ' . $count_allInTable['count'] . ' ' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete WHOLE encode cache!" alt="" />' . '' . '
' . $output . '
'; return $output; } /** * @param string $cmd * @param bool $decodeCache */ function clearDEncodeCache($cmd, $decodeCache = FALSE) { $table = $decodeCache ? 'tx_realurl_urldecodecache' : 'tx_realurl_urlencodecache'; list($keyword, $id) = explode('_', $cmd); switch ((string)$keyword) { case 'all': $this->database->exec_DELETEquery($table, ''); break; case 'page': $this->database->exec_DELETEquery($table, 'page_id=' . intval($id)); break; case 'urlhash': $this->database->exec_DELETEquery($table, 'url_hash=' . $this->database->fullQuoteStr($id, $table)); break; default: break; } } /***************************** * * Unique Alias * *****************************/ /** * Shows the mapping between aliases and unique IDs of arbitrary tables * * @return string HTML */ function uniqueAlias() { $tableName = $this->apiWrapper->_GP('table'); $cmd = $this->apiWrapper->_GET('cmd'); $entry = $this->apiWrapper->_GET('entry'); $search = $this->apiWrapper->_POST('search'); // Select rows: $overviewRows = $this->database->exec_SELECTgetRows('tablename,count(*) as number_of_rows', 'tx_realurl_uniqalias', '', 'tablename', '', '', 'tablename'); if ($tableName && isset($overviewRows[$tableName])) { // Show listing of single table: // Some Commands: if ($cmd === 'delete') { if ($entry === 'ALL') { $this->database->exec_DELETEquery('tx_realurl_uniqalias', 'tablename=' . $this->database->fullQuoteStr($tableName, 'tx_realurl_uniqalias')); } else { $this->database->exec_DELETEquery('tx_realurl_uniqalias', 'tablename=' . $this->database->fullQuoteStr($tableName, 'tx_realurl_uniqalias') . ' AND uid=' . intval($entry)); } } if ($cmd === 'flushExpired') { $this->database->exec_DELETEquery('tx_realurl_uniqalias', 'tablename=' . $this->database->fullQuoteStr($tableName, 'tx_realurl_uniqalias') . ' AND expire>0 AND expire<' . intval(time())); } // Select rows: $tableContent = $this->database->exec_SELECTgetRows( '*', 'tx_realurl_uniqalias', 'tablename=' . $this->database->fullQuoteStr($tableName, 'tx_realurl_uniqalias') . ($search ? ' AND (value_id=' . $this->database->fullQuoteStr($search, $tableName) . ' OR value_alias LIKE \'%' . $this->database->quoteStr($search, $tableName) . '%\')' : ''), '', 'value_id, lang, expire' ); $cc = 0; $field_id = $field_alias = $output = ''; $duplicates = array(); foreach ($tableContent as $aliasRecord) { // Add data: $tCells = array(); $tCells[] = '' . htmlspecialchars($aliasRecord['value_id']) . ''; if ((string)$cmd === 'edit' && ($entry === 'ALL' || !strcmp($entry, $aliasRecord['uid']))) { $tCells[] = '' . '' . ($entry !== 'ALL' ? $this->saveCancelButtons('') : '') . ''; } else { $tCells[] = '' . htmlspecialchars($aliasRecord['value_alias']) . ''; } $tCells[] = '' . htmlspecialchars($aliasRecord['lang']) . ''; $tCells[] = '' . htmlspecialchars($this->apiWrapper->dateTimeAge($aliasRecord['expire'])) . ''; $tCells[] = '' . // Edit link: '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/edit2.gif', 'width="11" height="12"') . ' title="" alt="" />' . '' . // Delete link: '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="" alt="" />' . '' . ''; $keyForDuplicates = $aliasRecord['value_alias'] . ':::' . $aliasRecord['lang']; $tCells[] = '' . (isset($duplicates[$keyForDuplicates]) ? $this->pObj->doc->icons(2) . 'Already used by ID ' . $duplicates[$aliasRecord['value_alias']] : ' ') . ''; $field_id = $aliasRecord['field_id']; $field_alias = $aliasRecord['field_alias']; // Compile Row: $output .= ' ' . implode(' ', $tCells) . ' '; $cc++; $duplicates[$keyForDuplicates] = $aliasRecord['value_id']; } // Create header: $tCells = array(); $tCells[] = 'ID (Field: ' . $field_id . ')'; $tCells[] = 'Alias (Field: ' . $field_alias . '):'; $tCells[] = 'Lang:'; $tCells[] = 'Expire:' . (!$search ? '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Flush expired" alt="" />' . '' : '') . ''; $tCells[] = '' . (!$search ? '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/edit2.gif', 'width="11" height="12"') . ' title="Edit all" alt="" />' . '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete all" alt="" />' . '' : '') . ''; $tCells[] = 'Error:'; $output = ' ' . implode(' ', $tCells) . ' ' . $output; // Compile final table and return: $output = '
Table: ' . htmlspecialchars($tableName) . '
Aliases: ' . htmlspecialchars(count($tableContent)) . '
Search:

' . $output . '
'; if ($entry === 'ALL') { $output .= $this->saveCancelButtons(''); } } else { // Create overview: $cc = 0; $output = ''; if (count($overviewRows)) { foreach ($overviewRows as $aliasRecord) { // Add data: $tCells = array(); $tCells[] = '' . $aliasRecord['tablename'] . ''; $tCells[] = '' . $aliasRecord['number_of_rows'] . ''; // Compile Row: $output .= ' ' . implode(' ', $tCells) . ' '; $cc++; } // Create header: $tCells = array(); $tCells[] = 'Table:'; $tCells[] = 'Aliases:'; $output = ' ' . implode(' ', $tCells) . ' ' . $output; // Compile final table and return: $output = ' ' . $output . '
'; } } return $output; } /** * Changes the "alias" value of an entry in the unique alias table * * @param int $cache_id UID of unique alias * @param string $value New value for the alias * @return void */ function editUniqAliasEntry($cache_id, $value) { $field_values = array( 'value_alias' => $value ); $this->database->exec_UPDATEquery('tx_realurl_uniqalias', 'uid=' . intval($cache_id), $field_values); } /** * Will look for submitted unique alias entries to save * * @return void */ function edit_save_uniqAlias() { if ($this->apiWrapper->_POST('_edit_save')) { $editArray = $this->apiWrapper->_POST('edit'); foreach ($editArray as $cache_id => $value) { $this->editUniqAliasEntry($cache_id, trim($value)); } } } /***************************** * * Configuration view: * *****************************/ /** * Shows configuration of the extension. * * @return string HTML */ function configView() { global $TYPO3_CONF_VARS; // Initialize array browser: $arrayBrowser = $this->apiWrapper->getArrayBrowser(); $arrayBrowser->expAll = TRUE; $arrayBrowser->fixedLgd = FALSE; $arrayBrowser->dontLinkVar = TRUE; // Create the display code: $theVar = $TYPO3_CONF_VARS['EXTCONF']['realurl']; $tree = $arrayBrowser->tree($theVar, '', ''); $tree = '
$TYPO3_CONF_VARS[\'EXTCONF\'][\'realurl\']
' . $tree . ''; return $tree; } /***************************** * * Log view: * *****************************/ /** * View error log * * @return string HTML */ function logView() { $output = ''; $cmd = $this->apiWrapper->_GP('cmd'); if ($cmd === 'deleteAll') { $this->database->exec_DELETEquery( 'tx_realurl_errorlog', '' ); } $list = $this->database->exec_SELECTgetRows( '*', 'tx_realurl_errorlog', '', '', 'counter DESC, tstamp DESC', 100 ); if (is_array($list)) { $output = ''; $cc = 0; foreach ($list as $rec) { $host = ''; if ($rec['rootpage_id'] != 0) { if (isset($hostCacheName[$rec['rootpage_id']])) { $host = $hostCacheName[$rec['rootpage_id']]; } else { $hostCacheName[$rec['rootpage_id']] = $host = $this->getHostName($rec['rootpage_id']); } } // Add data: $tCells = array(); $tCells[] = '' . $rec['counter'] . ''; $tCells[] = '' . $this->apiWrapper->dateTimeAge($rec['tstamp']) . ''; $tCells[] = '' . ($host ? $host . '/' : '') . htmlspecialchars($rec['url']) . '' . ' ' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/napshot.gif', 'width="12" height="12"') . ' title="Set as redirect" alt="" />' . '' . ''; $tCells[] = '' . htmlspecialchars($rec['error']) . ''; $tCells[] = '' . ($rec['last_referer'] ? '' . htmlspecialchars($rec['last_referer']) . '' : ' ') . ''; $tCells[] = '' . $this->apiWrapper->datetime($rec['cr_date']) . ''; // Compile Row: $output .= ' ' . implode(' ', $tCells) . ' '; $cc++; } // Create header: $tCells = array(); $tCells[] = 'Counter:'; $tCells[] = 'Last time:'; $tCells[] = 'URL:'; $tCells[] = 'Error:'; $tCells[] = 'Last Referer:'; $tCells[] = 'First time:'; $output = ' ' . implode(' ', $tCells) . ' ' . $output; // Compile final table and return: $output = '
' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete All" alt="" />' . ' Flush log
' . $output . '
'; } return $output; } function getHostName($rootpage_id) { foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'] as $host => $config) { if ($host != '_DEFAULT') { $hostName = $host; while ($config !== FALSE && !is_array($config)) { $host = $config; $config = (isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'][$host]) ? $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'][$host] : FALSE); } if (is_array($config) && isset($config['pagePath']) && isset($config['pagePath']['rootpage_id']) && $config['pagePath']['rootpage_id'] == $rootpage_id) { return 'http://' . $hostName; } } } return ''; } /***************************** * * Redirect view: * *****************************/ /** * Redirect view * * @return string HTML */ function redirectView() { $output = $this->pObj->doc->spacer(12); $output .= $this->processRedirectActions(); list($sortingParameter, $sortingDirection) = $this->getRedirectViewSortingParameters(); $output .= $this->getRedirectsSearch(); $output .= $this->getRedirectViewHeader($sortingDirection); $output .= $this->getRedirectsTableContent($sortingParameter, $sortingDirection); return $output; } protected function getRedirectsSearch() { $result = $this->getSearchField(); if ($this->apiWrapper->_GP('pathPrefixSearch')) { $result .= ' '; } $result .= ''; return $result; } /** * Creates a list of redirect entries. * * @param string $sortingParameter * @param string $sortingDirection * @return string */ protected function getRedirectsTableContent($sortingParameter, $sortingDirection) { $itemCounter = 0; $page = max(1, intval($this->apiWrapper->_GP('page'))); $resultsPerPage = $this->getResultsPerPage('redirects'); $condition = ''; $seachPath = $this->apiWrapper->_GP('pathPrefixSearch'); if ($seachPath) { $seachPathDecoded = $this->database->quoteStr( $this->database->escapeStrForLike(rawurlencode($seachPath), 'tx_realurl_redirects'), 'tx_realurl_redirects'); $seachPath = $this->database->quoteStr( $this->database->escapeStrForLike($seachPath, 'tx_realurl_redirects'), 'tx_realurl_redirects'); $condition = 'url LIKE \'%' . $seachPathDecoded . '%\' OR ' . 'destination LIKE \'%' . $seachPath . '%\''; } $start = ($page - 1) * $resultsPerPage; if ($sortingParameter !== 'domain_limit') { $query = 'SELECT t1.* FROM tx_realurl_redirects t1' . ($condition ? ' WHERE ' . $condition : '') . ' ORDER BY ' . $sortingParameter . ' ' . $sortingDirection . ' LIMIT ' . $start . ',' . $resultsPerPage; } else { $query = 'SELECT t1.* FROM tx_realurl_redirects t1' . ' LEFT JOIN sys_domain t2 ON t1.domain_limit=t2.uid' . ($condition ? ' WHERE ' . $condition : '') . ' ORDER BY ' . $sortingParameter . ' ' . $sortingDirection . ' LIMIT ' . $start . ',' . $resultsPerPage; } $res = $this->database->sql_query($query); $output = ''; while (FALSE !== ($rec = $this->database->sql_fetch_assoc($res))) { $output .= '' . $this->generateSingleRedirectContent($rec, $page); $itemCounter++; } $this->database->sql_free_result($res); list($count) = $this->database->exec_SELECTgetRows( 'COUNT(*) AS t', 'tx_realurl_redirects', $condition); $totalResults = $count['t']; if ($totalResults > $resultsPerPage) { $pageBrowser = $this->apiWrapper->makeInstance('tx_realurl_pagebrowser'); /** @var tx_realurl_pagebrowser $pageBrowser */ $results = sprintf($this->language->getLL('displaying_results'), $start + 1, min($totalResults, ($start + $resultsPerPage)), $totalResults); $output .= '' . $results . '' . '' . $pageBrowser->getPageBrowser($totalResults, $resultsPerPage) . ''; } $output .= ''; return $output; } /** * Obtains amount of results per page for the given view. * * @param string $view * @return int */ protected function getResultsPerPage($view) { $tsConfig = $this->apiWrapper->getModTSconfig($this->pObj->id, 'tx_realurl.' . $view . '.pagebrowser.resultsPerPage'); $resultsPerPage = $tsConfig['value']; return is_numeric($resultsPerPage) ? intval($resultsPerPage) : tx_realurl_pagebrowser::RESULTS_PER_PAGE_DEFAULT; } /** * Creates an HTML table row for a single redirect record. * * @param array $rec * @param int $page * @return string */ protected function generateSingleRedirectContent(array $rec, $page) { $output = '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/edit2.gif', 'width="11" height="12"') . ' title="Edit entry" alt="" />' . '' . '' . 'apiWrapper->skinImg($this->pObj->doc->backPath, 'gfx/garbage.gif', 'width="11" height="12"') . ' title="Delete entry" alt="" />' . '' . ''; $output .= sprintf('/%s', htmlspecialchars($this->apiWrapper->getIndpEnv('TYPO3_SITE_URL') . $rec['url']), htmlspecialchars($rec['url'])); $destinationURL = $this->getDestinationRedirectURL($rec['destination']); $output .= sprintf('%2$s', htmlspecialchars($destinationURL), htmlspecialchars($this->apiWrapper->fixed_lgd_cs($destinationURL, 30))); $output .= '' . htmlspecialchars($this->getRedirectDomain($rec['domain_limit'])) . ''; $output .= '' . ($rec['has_moved'] ? '+' : ' ') . ''; $output .= '' . $rec['counter'] . ''; if ($rec['tstamp']) { $output .= '' . $this->apiWrapper->dateTimeAge($rec['tstamp']) . ''; } else { $output .= '—'; } if ($rec['last_referer']) { $lastRef = htmlspecialchars($rec['last_referer']); $output .= sprintf('%s', $lastRef, $lastRef, (strlen($rec['last_referer']) > 30) ? htmlspecialchars(substr($rec['last_referer'], 0, 30)) . '...' : $lastRef); } else { $output .= ' '; } // Error: $errorMessage = ''; $pagesWithURL = array_keys($this->database->exec_SELECTgetRows('page_id', 'tx_realurl_urlencodecache', 'content=' . $this->database->fullQuoteStr($rec['url'], 'tx_realurl_urlencodecache'), '', '', '', '', 'page_id')); if (count($pagesWithURL) > 0) { $errorMessage .= $this->pObj->doc->icons(3) . 'Also a page URL: ' . implode(',', array_unique($pagesWithURL)); } $output .= '' . $errorMessage . ''; return $output; } /** * Obtains domain name by its id. * * @param int $domainId * @return string */ protected function getRedirectDomain($domainId) { $result = ' '; if ($domainId != 0) { list($row) = $this->database->exec_SELECTgetRows('domainName', 'sys_domain', 'uid=' . intval($domainId) ); if (is_array($row)) { $result = $row['domainName']; } } return $result; } /** * Creates a header for the redirects table. * * @param string $sortingDirection * @return string */ protected function getRedirectViewHeader($sortingDirection) { $sortingDirection = ($sortingDirection == 'ASC' ? 'DESC' : 'ASC'); return '' . '' . '' . sprintf('', sprintf('index.php?id=%d&SET[type]=%s&SET[ob]=url&SET[obdir]=%s', $this->pObj->id, $this->pObj->MOD_SETTINGS['type'], $sortingDirection)) . sprintf('', sprintf('index.php?id=%d&SET[type]=%s&SET[ob]=destination&SET[obdir]=%s', $this->pObj->id, $this->pObj->MOD_SETTINGS['type'], $sortingDirection)) . sprintf('', sprintf('index.php?id=%d&SET[type]=%s&SET[ob]=domain_limit&SET[obdir]=%s', $this->pObj->id, $this->pObj->MOD_SETTINGS['type'], $sortingDirection)) . sprintf('', sprintf('index.php?id=%d&SET[type]=%s&SET[ob]=has_moved&SET[obdir]=%s', $this->pObj->id, $this->pObj->MOD_SETTINGS['type'], $sortingDirection)) . sprintf('', sprintf('index.php?id=%d&SET[type]=%s&SET[ob]=counter&SET[obdir]=%s', $this->pObj->id, $this->pObj->MOD_SETTINGS['type'], $sortingDirection)) . '' . sprintf('', sprintf('index.php?id=%d&SET[type]=%s&SET[ob]=last_referer&SET[obdir]=%s', $this->pObj->id, $this->pObj->MOD_SETTINGS['type'], $sortingDirection)) . ''; } /** * Creates sorting parameters for the redirect view. * * @return array */ protected function getRedirectViewSortingParameters() { session_start(); $gpVars = $this->apiWrapper->_GP('SET'); if (isset($gpVars['ob'])) { $sortingParameter = $gpVars['ob']; if (!$this->apiWrapper->inList('url,destination,domain_limit,has_moved,counter,last_referer', $sortingParameter)) { $sortingParameter = ''; $sortingDirection = ''; } else { $sortingDirection = strtoupper($gpVars['obdir']); if ($sortingDirection != 'DESC' && $sortingDirection != 'ASC') { $sortingDirection = ''; } } $_SESSION['realurl']['redirects_view']['sorting'] = array($sortingParameter, $sortingDirection); } elseif (!isset($_SESSION['realurl']['redirects_view']['sorting'])) { $_SESSION['realurl']['redirects_view']['sorting'] = array('url', 'ASC'); } return $_SESSION['realurl']['redirects_view']['sorting']; } /** * Processes redirect view actions according to request parameters. * * @return string */ protected function processRedirectActions() { switch ($this->apiWrapper->_GP('cmd')) { case 'new': case 'edit': $output = $this->getProcessForm(); break; case 'delete': $this->deleteRedirectEntry(); // Fall through default: $output = $this->getNewButton(); break; } return $output; } /** * Deletes a redirect entry. * * @return void */ protected function deleteRedirectEntry() { $uid = $this->apiWrapper->_GP('uid'); if ($uid) { $this->database->exec_DELETEquery('tx_realurl_redirects', 'uid=' . intval($uid) ); } } /** * Creates a code for 'Add new entries' button * * @return string */ protected function getNewButton() { $content = ''; return $content; } /** * Checks form submission for 'new' and 'edit' actions and performs whatever * is necessary to add or edit data. Returns the form if necessary. * * @return string HTML */ protected function getProcessForm() { $content = $error = ''; if (!$this->apiWrapper->_POST('_edit_cancel')) { if ($this->processRedirectSubmission($error)) { // Submission successful -- show "New" button $content = $this->getNewButton(); } else { // Submission error or no submission if ($error) { $error = '
Problem found! ' . $error . '
'; } $hint = '
' . 'Note: the exact source URL will match! Add a slash to the end ' . 'of the URL if necessary!
'; if (!$this->apiWrapper->_GP('uid')) { $content .= '

Add new redirects

' . $error . $hint . $this->getRedirectNewForm(); } else { $content .= '

Edit a redirect

' . $error . $hint . $this->getRedirectEditForm(); } $content .= ''; $content .= ''; } } return $content; } /** * Creates a form to edit an entry * * @return string Generated HTML */ protected function getRedirectEditForm() { $content = ''; $uid = $this->apiWrapper->_GP('uid'); list($row) = $this->database->exec_SELECTgetRows( 'url,url_hash,destination,has_moved,domain_limit', 'tx_realurl_redirects', 'uid=' . intval($uid)); if (is_array($row)) { $page = max(1, intval($this->apiWrapper->_GP('page'))); $content = '
 Source:Redirect to:Domain:Permanent:Hits:Last hit time:Last referer:Errors:
' . '' . '' . '' . '' . '' . '' . '' . '' . '' . '
Redirect from:/
Redirect to:
Domain:
Permanent redirect (send "301 Moved permanently" header)
' . $this->saveCancelButtons() . '
' . '' . '' . ''; } return $content; } /** * Creates a form for the new entries * * @return string Generated HTML */ protected function getRedirectNewForm() { $content = ''; // Show the form header $content .= ''; // Show fields $data = $this->apiWrapper->_GP('data'); $max = count($data); if (!is_array($data)) { $data = array(); $max = 10; } for ($i = 0; $i < $max; $i++) { $content .= '' . ''; } $content .= '' . '
Source URLDestination URL:Domain:Permanent:
' . '/' . '' . '' . '
' . $this->saveCancelButtons() . '
'; return $content; } /** * Creates a list of options for the domain selector box. * * @param int $selectedDomain * @return string */ protected function getRedirectDomainOptions($selectedDomain) { static $domainList = NULL; if (is_null($domainList)) { $domainList = $this->database->exec_SELECTgetRows('uid,domainName', 'sys_domain', 'redirectTo=\'\'', '', 'domainName' ); } $result = ''; foreach ($domainList as $domainRecord) { $result .= ''; } return $result; } /** * Processes submission * * @param string $error Error message * @return boolean true if successful */ protected function processRedirectSubmission(&$error) { $result = FALSE; $error = ''; if ($this->apiWrapper->_GP('_edit_save')) { $data = $this->apiWrapper->_GP('data'); $databaseUpdateData = array(); $databaseInsertData = array(); foreach ($data as $fields) { // // Validate // $fields['source'] = strtolower(trim($fields['source'])); $fields['target'] = trim($fields['target']); // Check empty or same if ($fields['source'] == $fields['target']) { // Either equal or empty, ignore the input continue; } // Check one field empty if (trim($fields['source']) == '' || trim($fields['target'] == '')) { $error = 'Please, fill in both source and destination URLs'; return FALSE; } // Check for duplicate source URLs $andWhere = ($fields['url_hash'] != '' ? ' AND url_hash<>' . intval($fields['url_hash']) : ''); list($row) = $this->database->exec_SELECTgetRows('COUNT(*) AS t', 'tx_realurl_redirects', 'url=' . $this->database->fullQuoteStr($fields['source'], 'tx_realurl_redirects') . ' AND domain_limit=' . intval($fields['domain_limit']) . $andWhere); if ($row['t'] > 0) { $error = 'Source URL \'/' . htmlspecialchars($fields['source']) . '\' already exists in the redirect list.'; return FALSE; } // Check for missing slash in destination $parse = @parse_url($fields['target']); if ($fields['target']{0} != '/' && ($parse === FALSE || !isset($parse['scheme']))) { $fields['target'] = '/' . $fields['target']; } // Process if ($fields['url_hash'] == '') { // New entry $databaseInsertData[] = array( 'url_hash' => $this->apiWrapper->md5int($fields['source']), 'url' => $fields['source'], 'destination' => $fields['target'], 'has_moved' => $fields['permanent'] ? 1 : 0, 'domain_limit' => intval($fields['domain_limit']) ); } else { // Existing entry $databaseUpdateData[$fields['uid']] = array( 'url_hash' => $this->apiWrapper->md5int($fields['source']), 'url' => $fields['source'], 'destination' => $fields['target'], 'has_moved' => $fields['permanent'] ? 1 : 0, 'domain_limit' => intval($fields['domain_limit']) ); } } // Add/update data foreach ($databaseInsertData as $data) { $this->database->exec_INSERTquery('tx_realurl_redirects', $data); } foreach ($databaseUpdateData as $uid => $data) { $this->database->exec_UPDATEquery('tx_realurl_redirects', 'uid=' . intval($uid), $data); } // Make sure we return success if the form is totally empty $result = TRUE; } return $result; } /** * Obtains destination URL for the redirect. * * @param string $url * @return string */ protected function getDestinationRedirectURL($url) { $parts = @parse_url($url); if (!is_array($parts) || empty($parts['scheme'])) { if ($url{0} != '/') { $url = '/' . $url; } } return $url; } } if (defined('TYPO3_MODE') && $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/realurl/modfunc1/class.tx_realurl_modfunc1.php']) { include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/realurl/modfunc1/class.tx_realurl_modfunc1.php']); }