Last active
February 14, 2016 18:45
-
-
Save georgringer/aa5d5f347dd5ce5a5980 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace GeorgRinger\News\ViewHelpers; | |
/** | |
* This file is part of the TYPO3 CMS project. | |
* | |
* It is free software; you can redistribute it and/or modify it under | |
* the terms of the GNU General Public License, either version 2 | |
* of the License, or any later version. | |
* | |
* For the full copyright and license information, please read the | |
* LICENSE.txt file that was distributed with this source code. | |
* | |
* The TYPO3 project - inspiring people to share! | |
*/ | |
/** | |
* ViewHelper for a **simple** prev/next link. | |
* Only the pid is taken into account, nothing else! | |
* | |
* # Example: Basic example | |
* <code> | |
* | |
* <n:simplePrevNext pidList="{newsItem.pid}" news="{newsItem}" as="paginated" sortField="datetime"> | |
* <f:if condition="{paginated}"> | |
* <ul class="prev-next"> | |
* <f:if condition="{paginated.prev}"> | |
* <li class="previous"> | |
* <n:link newsItem="{paginated.prev}" settings="{settings}"> | |
* {paginated.prev.title} | |
* </n:link> | |
* </li> | |
* </f:if> | |
* <f:if condition="{paginated.next}"> | |
* <li class="next"> | |
* <n:link newsItem="{paginated.next}" settings="{settings}" class="next"> | |
* {paginated.next.title} | |
* </n:link> | |
* </li> | |
* </f:if> | |
* </ul> | |
* </f:if> | |
* </n:simplePrevNext> | |
* | |
* </code> | |
* <output> | |
* Menu with 2 li items with the link to the previous and next news item. | |
* </output> | |
* | |
*/ | |
class SimplePrevNextViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper | |
{ | |
/** @var \TYPO3\CMS\Core\Database\DatabaseConnection */ | |
protected $databaseConnection; | |
/* @var $dataMapper \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper */ | |
protected $dataMapper; | |
public function __construct() | |
{ | |
$this->databaseConnection = $GLOBALS['TYPO3_DB']; | |
} | |
/** | |
* Inject the DataMapper | |
* | |
* @param \TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper $dataMapper | |
* @return void | |
*/ | |
public function injectDataMapper(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper $dataMapper) | |
{ | |
$this->dataMapper = $dataMapper; | |
} | |
/** | |
* @param \GeorgRinger\News\Domain\Model\News $news | |
* @param string $pidList this is something | |
* @param string $sortField | |
* @param string $as | |
* @throws TYPO3\CMS\Fluid\Core\ViewHelper\Exception\InvalidVariableException | |
* @return string | |
*/ | |
public function render(\GeorgRinger\News\Domain\Model\News $news, $pidList = '', $sortField = 'datetime', $as) | |
{ | |
$neighbours = $this->getNeighbours($news, $pidList, $sortField); | |
$mapped = $this->mapResultToObjects($neighbours); | |
$this->templateVariableContainer->add($as, $mapped); | |
$output = $this->renderChildren(); | |
$this->templateVariableContainer->remove($as); | |
return $output; | |
} | |
/** | |
* Map the array from DB to an understandable output | |
* | |
* @param array $result | |
* @return array | |
*/ | |
protected function mapResultToObjects(array $result) | |
{ | |
$out = $tmp = []; | |
$count = count($result); | |
switch ($count) { | |
case 3: | |
$tmp['prev'] = $result[0]; | |
$tmp['next'] = $result[2]; | |
break; | |
case 2: | |
$tmp['prev'] = $result[0]; | |
break; | |
case 1: | |
$tmp['next'] = $result[0]; | |
break; | |
case 0: | |
// no next or prev news, shit happens.... | |
break; | |
default: | |
throw new \UnexpectedValueException(sprintf('Unexpected count of "%s" which is not implemented!', $count)); | |
} | |
foreach ($tmp as $_id => $single) { | |
$out[$_id] = $this->getObject($single['uid']); | |
} | |
return $out; | |
} | |
/** | |
* Get the news object from the given id | |
* | |
* @param int $id | |
* @return mixed|null | |
*/ | |
protected function getObject($id) | |
{ | |
$record = null; | |
$rawRecord = $this->databaseConnection->exec_SELECTgetSingleRow('*', 'tx_news_domain_model_news', | |
'uid=' . (int)$id); | |
if (is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->sys_language_content > 0) { | |
$overlay = $GLOBALS['TSFE']->sys_page->getRecordOverlay( | |
'tx_news_domain_model_news', | |
$rawRecord, | |
$GLOBALS['TSFE']->sys_language_content, | |
$GLOBALS['TSFE']->sys_language_contentOL | |
); | |
if (!is_null($overlay)) { | |
$rawRecord = $overlay; | |
} | |
} | |
if (is_array($rawRecord)) { | |
$className = 'GeorgRinger\\News\\Domain\\Model\\News'; | |
$records = $this->dataMapper->map($className, [$rawRecord]); | |
$record = array_shift($records); | |
} | |
return $record; | |
} | |
/** | |
* Returns where clause for the news table | |
* | |
* @return string | |
*/ | |
protected function getEnableFieldsWhereClauseForTable() | |
{ | |
$table = 'tx_news_domain_model_news'; | |
if (is_object($GLOBALS['TSFE']) && is_object($GLOBALS['TSFE']->sys_page)) { | |
return $GLOBALS['TSFE']->sys_page->enableFields($table); | |
} elseif (is_object($GLOBALS['BE_USER'])) { | |
return \TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause($table) . | |
\TYPO3\CMS\Backend\Utility\BackendUtility::BEenableFields($table) . | |
\TYPO3\CMS\Core\Resource\Utility\BackendUtility::getWorkspaceWhereClause($table); | |
} elseif (TYPO3_MODE === 'BE' && TYPO3_cliMode === true) { | |
return ''; | |
} elseif(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI) { | |
return ''; | |
} | |
throw new \UnexpectedValueException('No TSFE for frontend and no BE_USER for Backend defined, please report the issue!'); | |
} | |
/** | |
* @param \GeorgRinger\News\Domain\Model\News $news | |
* @param $pidList | |
* @param $sortField | |
* @return array | |
*/ | |
protected function getNeighbours(\GeorgRinger\News\Domain\Model\News $news, $pidList, $sortField) | |
{ | |
$pidList = empty($pidList) ? $news->getPid() : $pidList; | |
$select = 'SELECT tx_news_domain_model_news.uid,tx_news_domain_model_news.title '; | |
$from = 'FROM tx_news_domain_model_news'; | |
$whereClause = 'tx_news_domain_model_news.pid IN(' . $this->databaseConnection->cleanIntList($pidList) . ') ' | |
. $this->getEnableFieldsWhereClauseForTable(); | |
$query = $select . $from . ' | |
WHERE ' . $whereClause . ' && ' . $sortField . ' >= (SELECT MAX(' . $sortField . ') | |
' . $from . ' | |
WHERE ' . $whereClause . ' AND ' . $sortField . ' < (SELECT ' . $sortField . ' | |
FROM tx_news_domain_model_news | |
WHERE tx_news_domain_model_news.uid = ' . $news->getUid() . ')) | |
ORDER BY ' . $sortField . ' ASC | |
LIMIT 3'; | |
$query2 = $select . $from . ' | |
WHERE ' . $whereClause . ' AND ' . $sortField . '= (SELECT MIN(' . $sortField . ') | |
FROM tx_news_domain_model_news | |
WHERE ' . $whereClause . ' AND ' . $sortField . ' > | |
(SELECT ' . $sortField . ' | |
FROM tx_news_domain_model_news | |
WHERE tx_news_domain_model_news.uid = ' . $news->getUid() . ')) | |
'; | |
$res = $this->databaseConnection->sql_query($query); | |
$out = []; | |
while ($row = $this->databaseConnection->sql_fetch_assoc($res)) { | |
$out[] = $row; | |
} | |
$this->databaseConnection->sql_free_result($res); | |
if (count($out) === 0) { | |
$res = $this->databaseConnection->sql_query($query2); | |
while ($row = $this->databaseConnection->sql_fetch_assoc($res)) { | |
$out[] = $row; | |
} | |
$this->databaseConnection->sql_free_result($res); | |
return $out; | |
} | |
return $out; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment