Initial commit
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2007-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Generator;
|
||||
|
||||
use DmitryDulepov\DdGooglesitemap\Renderers\AbstractSitemapRenderer;
|
||||
use \TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class is a base for all sitemap generators.
|
||||
*
|
||||
* @author Dmitry Dulepov <support@snowflake.ch>
|
||||
*/
|
||||
abstract class AbstractSitemapGenerator {
|
||||
/**
|
||||
* cObject to generate links
|
||||
*
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
protected $cObj;
|
||||
|
||||
/**
|
||||
* Maximum number of items to show.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $limit;
|
||||
|
||||
/**
|
||||
* Offset to start outputting from.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $offset;
|
||||
|
||||
/**
|
||||
* A sitemap renderer
|
||||
*
|
||||
* @var AbstractSitemapRenderer
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/**
|
||||
* Class name to instantiate the renderer.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rendererClass = 'DmitryDulepov\\DdGooglesitemap\\Renderers\\StandardSitemapRenderer';
|
||||
|
||||
/**
|
||||
* Initializes the instance of this class. This constructir sets starting
|
||||
* point for the sitemap to the current page id
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
|
||||
$this->cObj->start(array());
|
||||
|
||||
$this->offset = max(0, (int)GeneralUtility::_GET('offset'));
|
||||
$this->limit = max(0, (int)GeneralUtility::_GET('limit'));
|
||||
if ($this->limit <= 0) {
|
||||
$this->limit = 50000;
|
||||
}
|
||||
|
||||
$this->createRenderer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes sitemap content to the output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function main() {
|
||||
header('Content-type: text/xml');
|
||||
if ($this->renderer) {
|
||||
echo $this->renderer->getStartTags();
|
||||
}
|
||||
$this->generateSitemapContent();
|
||||
if ($this->renderer) {
|
||||
echo $this->renderer->getEndTags();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the renderer using $this->rendererClass. Subclasses can use a
|
||||
* more flexible logic if just setting the class is not enough.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function createRenderer() {
|
||||
$this->renderer = GeneralUtility::makeInstance($this->rendererClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the sitemap and echoes it to the browser.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function generateSitemapContent();
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2007-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Generator;
|
||||
|
||||
use \TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class implements a Google sitemap.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
class EntryPoint {
|
||||
|
||||
const DEFAULT_SITEMAP_TYPE = 'pages';
|
||||
|
||||
public function __construct() {
|
||||
@set_time_limit(300);
|
||||
$this->initTSFE();
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function of the class. Outputs sitemap.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function main() {
|
||||
$sitemapType = $this->getSitemapType();
|
||||
if (isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dd_googlesitemap']['sitemap'][$sitemapType])) {
|
||||
$userFuncRef = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dd_googlesitemap']['sitemap'][$sitemapType];
|
||||
$params = array();
|
||||
GeneralUtility::callUserFunction($userFuncRef, $params, $this);
|
||||
}
|
||||
else {
|
||||
header('HTTP/1.0 400 Bad request', true, 400);
|
||||
header('Content-type: text/plain');
|
||||
echo 'No generator found for type \'' . $sitemapType . '\'';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines what sitemap we should send
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getSitemapType() {
|
||||
$type = GeneralUtility::_GP('sitemap');
|
||||
return ($type ?: self::DEFAULT_SITEMAP_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes TSFE and sets $GLOBALS['TSFE']
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function initTSFE() {
|
||||
$GLOBALS['TSFE'] = $tsfe = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController', $GLOBALS['TYPO3_CONF_VARS'], GeneralUtility::_GP('id'), '');
|
||||
/** @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $tsfe */
|
||||
$tsfe->connectToDB();
|
||||
$tsfe->initFEuser();
|
||||
\TYPO3\CMS\Frontend\Utility\EidUtility::initTCA();
|
||||
$tsfe->determineId();
|
||||
$tsfe->initTemplate();
|
||||
$tsfe->getConfigArray();
|
||||
|
||||
// Get linkVars, absRefPrefix, etc
|
||||
\TYPO3\CMS\Frontend\Page\PageGenerator::pagegenInit();
|
||||
}
|
||||
}
|
||||
|
||||
$generator = GeneralUtility::makeInstance('DmitryDulepov\\DdGooglesitemap\\Generator\\EntryPoint');
|
||||
/* @var EntryPoint $generator */
|
||||
$generator->main();
|
||||
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2007-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Generator;
|
||||
|
||||
use DmitryDulepov\DdGooglesitemap\Renderers\AbstractSitemapRenderer;
|
||||
use \TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class produces sitemap for pages
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
|
||||
class PagesSitemapGenerator extends AbstractSitemapGenerator {
|
||||
|
||||
/**
|
||||
* List of page uid values to generate entries for
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pageList = array();
|
||||
|
||||
/**
|
||||
* Number of generated items.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $generatedItemCount = 0;
|
||||
|
||||
/**
|
||||
* A sitemap renderer
|
||||
*
|
||||
* @var AbstractSitemapRenderer
|
||||
*/
|
||||
protected $renderer;
|
||||
|
||||
/** @var array */
|
||||
protected $excludedPageTypes = array(0, 3, 4, 5, 6, 7, 199, 254, 255);
|
||||
|
||||
/**
|
||||
* Hook objects for post-processing
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hookObjects;
|
||||
|
||||
/**
|
||||
* Initializes the instance of this class. This constructir sets starting
|
||||
* point for the sitemap to the current page id
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
$excludePageTypes = GeneralUtility::intExplode(',', $GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['excludePageType'], TRUE);
|
||||
if (count($excludePageTypes) > 0) {
|
||||
$this->excludedPageTypes = $excludePageTypes;
|
||||
}
|
||||
|
||||
$pid = intval($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['forceStartPid']);
|
||||
if ($pid === 0 || $pid == $GLOBALS['TSFE']->id) {
|
||||
$this->pageList[$GLOBALS['TSFE']->id] = array(
|
||||
'uid' => $GLOBALS['TSFE']->id,
|
||||
'SYS_LASTCHANGED' => $GLOBALS['TSFE']->page['SYS_LASTCHANGED'],
|
||||
'tx_ddgooglesitemap_lastmod' => $GLOBALS['TSFE']->page['tx_ddgooglesitemap_lastmod'],
|
||||
'tx_ddgooglesitemap_priority' => $GLOBALS['TSFE']->page['tx_ddgooglesitemap_priority'],
|
||||
'doktype' => $GLOBALS['TSFE']->page['doktype'],
|
||||
'no_search' => $GLOBALS['TSFE']->page['no_search']
|
||||
);
|
||||
}
|
||||
else {
|
||||
$page = $GLOBALS['TSFE']->sys_page->getPage($pid);
|
||||
$this->pageList[$page['uid']] = array(
|
||||
'uid' => $page['uid'],
|
||||
'SYS_LASTCHANGED' => $page['SYS_LASTCHANGED'],
|
||||
'tx_ddgooglesitemap_lastmod' => $page['tx_ddgooglesitemap_lastmod'],
|
||||
'tx_ddgooglesitemap_priority' => $page['tx_ddgooglesitemap_priority'],
|
||||
'doktype' => $page['doktype'],
|
||||
'no_search' => $page['no_search']
|
||||
);
|
||||
}
|
||||
|
||||
$this->renderer = GeneralUtility::makeInstance('DmitryDulepov\\DdGooglesitemap\\Renderers\\StandardSitemapRenderer');
|
||||
|
||||
// Prepare user defined objects (if any)
|
||||
$this->hookObjects = array();
|
||||
if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dd_googlesitemap']['generateSitemapForPagesClass'])) {
|
||||
foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['dd_googlesitemap']['generateSitemapForPagesClass'] as $classRef) {
|
||||
$this->hookObjects[] = GeneralUtility::getUserObj($classRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates sitemap for pages (<url> entries in the sitemap)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function generateSitemapContent() {
|
||||
// Workaround: we want the sysfolders back into the menu list!
|
||||
// We also exclude "Backend user section" pages.
|
||||
$GLOBALS['TSFE']->sys_page->where_hid_del = str_replace(
|
||||
'pages.doktype<200',
|
||||
'pages.doktype<>255 AND pages.doktype<>6',
|
||||
$GLOBALS['TSFE']->sys_page->where_hid_del
|
||||
);
|
||||
|
||||
while (!empty($this->pageList) && $this->generatedItemCount - $this->offset <= $this->limit) {
|
||||
$pageInfo = array_shift($this->pageList);
|
||||
if ($this->generatedItemCount >= $this->offset) {
|
||||
$this->writeSingleUrl($pageInfo);
|
||||
}
|
||||
$this->generatedItemCount++;
|
||||
|
||||
// Add subpages of this page to the end of the page list. This way
|
||||
// we get top level pages in the sitemap first, then subpages of the
|
||||
// first, second, etc pages of the top level pages and so on.
|
||||
//
|
||||
// Notice: no sorting (for speed)!
|
||||
$GLOBALS['TSFE']->sys_page->sys_language_uid = $GLOBALS['TSFE']->config['config']['sys_language_uid'];
|
||||
$morePages = $GLOBALS['TSFE']->sys_page->getMenu($pageInfo['uid'],
|
||||
'uid,doktype,no_search,l18n_cfg,SYS_LASTCHANGED,tx_ddgooglesitemap_lastmod,tx_ddgooglesitemap_priority',
|
||||
'', '', false);
|
||||
$this->removeNonTranslatedPages($morePages);
|
||||
$this->pageList = array_merge($this->pageList, array_values($morePages));
|
||||
unset($morePages);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the last modification date of the page.
|
||||
*
|
||||
* @param array $pageInfo
|
||||
* @return int
|
||||
*/
|
||||
protected function getLastMod(array $pageInfo) {
|
||||
$lastModDates = GeneralUtility::intExplode(',', $pageInfo['tx_ddgooglesitemap_lastmod']);
|
||||
$lastModDates[] = intval($pageInfo['SYS_LASTCHANGED']);
|
||||
rsort($lastModDates, SORT_NUMERIC);
|
||||
reset($lastModDates);
|
||||
|
||||
return current($lastModDates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exclude pages from given list
|
||||
*
|
||||
* @param array $pages
|
||||
* @return void
|
||||
*/
|
||||
protected function removeNonTranslatedPages(array &$pages) {
|
||||
$language = (int)$GLOBALS['TSFE']->config['config']['sys_language_uid'];
|
||||
foreach ($pages as $pageUid => $page) {
|
||||
// Hide page in default language
|
||||
if ($language === 0 && GeneralUtility::hideIfDefaultLanguage($page['l18n_cfg'])) {
|
||||
unset($pages[$pageUid]);
|
||||
}
|
||||
elseif ($language !== 0 && !isset($page['_PAGES_OVERLAY']) && GeneralUtility::hideIfNotTranslated($page['l18n_cfg'])) {
|
||||
// Hide page if no translation is set
|
||||
unset($pages[$pageUid]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the page should be included into the sitemap.
|
||||
*
|
||||
* @param array $pageInfo
|
||||
* @return bool
|
||||
*/
|
||||
protected function shouldIncludePageInSitemap(array $pageInfo) {
|
||||
return !$pageInfo['no_search'] && !in_array($pageInfo['doktype'], $this->excludedPageTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs information about single page
|
||||
*
|
||||
* @param array $pageInfo Page information (needs 'uid' and 'SYS_LASTCHANGED' columns)
|
||||
* @return void
|
||||
*/
|
||||
protected function writeSingleUrl(array $pageInfo) {
|
||||
if ($this->shouldIncludePageInSitemap($pageInfo) && ($url = $this->getPageLink($pageInfo['uid']))) {
|
||||
echo $this->renderer->renderEntry($url, $pageInfo['title'],
|
||||
$this->getLastMod($pageInfo),
|
||||
$this->getChangeFrequency($pageInfo), '', $pageInfo['tx_ddgooglesitemap_priority']);
|
||||
|
||||
// Post-process current page and possibly append data
|
||||
// @see http://forge.typo3.org/issues/45637
|
||||
foreach ($this->hookObjects as $hookObject) {
|
||||
if (is_callable(array($hookObject, 'postProcessPageInfo'))) {
|
||||
$parameters = array(
|
||||
'pageInfo' => &$pageInfo,
|
||||
'generatedItemCount' => &$this->generatedItemCount,
|
||||
'offset' => $this->offset,
|
||||
'limit' => $this->limit,
|
||||
'renderer' => $this->renderer,
|
||||
'pObj' => $this
|
||||
);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$hookObject->postProcessPageInfo($parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getChangeFrequency(array $pageInfo) {
|
||||
$timeValues = GeneralUtility::intExplode(',', $pageInfo['tx_ddgooglesitemap_lastmod']);
|
||||
// Remove zeros
|
||||
foreach ($timeValues as $k => $v) {
|
||||
if ($v == 0) {
|
||||
unset($timeValues[$k]);
|
||||
}
|
||||
}
|
||||
$timeValues[] = $pageInfo['SYS_LASTCHANGED'];
|
||||
$timeValues[] = time();
|
||||
sort($timeValues, SORT_NUMERIC);
|
||||
$sum = 0;
|
||||
for ($i = count($timeValues) - 1; $i > 0; $i--) {
|
||||
$sum += ($timeValues[$i] - $timeValues[$i - 1]);
|
||||
}
|
||||
$average = ($sum/(count($timeValues) - 1));
|
||||
return ($average >= 180*24*60*60 ? 'yearly' :
|
||||
($average <= 24*60*60 ? 'daily' :
|
||||
($average <= 60*60 ? 'hourly' :
|
||||
($average <= 14*24*60*60 ? 'weekly' : 'monthly'))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a link to a single page
|
||||
*
|
||||
* @param array $pageId Page ID
|
||||
* @return string Full URL of the page including host name (escaped)
|
||||
*/
|
||||
protected function getPageLink($pageId) {
|
||||
$conf = array(
|
||||
'parameter' => $pageId,
|
||||
'returnLast' => 'url',
|
||||
);
|
||||
$link = htmlspecialchars($this->cObj->typoLink('', $conf));
|
||||
return GeneralUtility::locationHeaderUrl($link);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2007-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Generator;
|
||||
|
||||
use \TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use \TYPO3\CMS\Core\Utility\MathUtility;
|
||||
|
||||
/**
|
||||
* This class implements news sitemap
|
||||
* (http://www.google.com/support/webmasters/bin/answer.py?hl=en-nz&answer=42738)
|
||||
* for Google.
|
||||
*
|
||||
* The following URL parameters are expected:
|
||||
* - sitemap=news
|
||||
* - singlePid=<uid of the "single" tt_news view>
|
||||
* - pidList=<comma-separated list of storage pids>
|
||||
* All pids must be in the rootline of the current pid. The safest way is to call
|
||||
* this site map from the root page of the site:
|
||||
* http://example.com/?eID=dd_googlesitemap&sitemap=news&singlePid=100&pidList=101,102,115
|
||||
*
|
||||
* If you need to show news on different single view pages, make several sitemaps
|
||||
* (it is possible with Google).
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
class TtNewsSitemapGenerator extends AbstractSitemapGenerator {
|
||||
|
||||
/**
|
||||
* List of storage pages where news items are located
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pidList = array();
|
||||
|
||||
/**
|
||||
* Indicates sitemap type
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $isNewsSitemap;
|
||||
|
||||
/**
|
||||
* Single view page
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $singlePid;
|
||||
|
||||
/**
|
||||
* If true, try to get the single pid for a news item from its (first) category with fallback to $this->singlePid
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $useCategorySinglePid;
|
||||
|
||||
/**
|
||||
* Creates an instance of this class
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->isNewsSitemap = (GeneralUtility::_GET('type') === 'news');
|
||||
if ($this->isNewsSitemap) {
|
||||
$this->rendererClass = 'DmitryDulepov\\DdGooglesitemap\\Renderers\\NewsSitemapRenderer';
|
||||
}
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$singlePid = intval(GeneralUtility::_GP('singlePid'));
|
||||
$this->singlePid = $singlePid && $this->isInRootline($singlePid) ? $singlePid : $GLOBALS['TSFE']->id;
|
||||
$this->useCategorySinglePid = (bool) GeneralUtility::_GP('useCategorySinglePid');
|
||||
|
||||
$this->validateAndcreatePageList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates news site map.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function generateSitemapContent() {
|
||||
if (count($this->pidList) > 0) {
|
||||
$languageCondition = '';
|
||||
$language = GeneralUtility::_GP('L');
|
||||
if (MathUtility::canBeInterpretedAsInteger($language)) {
|
||||
$languageCondition = ' AND sys_language_uid=' . $language;
|
||||
}
|
||||
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*',
|
||||
'tt_news', 'pid IN (' . implode(',', $this->pidList) . ')' .
|
||||
($this->isNewsSitemap ? ' AND crdate>=' . (time() - 48*60*60) : '') .
|
||||
$languageCondition .
|
||||
$this->cObj->enableFields('tt_news'), '', 'datetime DESC',
|
||||
$this->offset . ',' . $this->limit
|
||||
);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$rowCount = $GLOBALS['TYPO3_DB']->sql_num_rows($res);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
while (false !== ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))) {
|
||||
$forceSinglePid = NULL;
|
||||
if ($row['category'] && $this->useCategorySinglePid) {
|
||||
$forceSinglePid = $this->getSinglePidFromCategory($row['uid']);
|
||||
}
|
||||
if (($url = $this->getNewsItemUrl($row, $forceSinglePid))) {
|
||||
echo $this->renderer->renderEntry($url, $row['title'], $row['datetime'],
|
||||
'', $row['keywords']);
|
||||
}
|
||||
}
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$GLOBALS['TYPO3_DB']->sql_free_result($res);
|
||||
|
||||
if ($rowCount === 0) {
|
||||
echo '<!-- It appears that there are no tt_news entries. If your ' .
|
||||
'news storage sysfolder is outside of the rootline, you may ' .
|
||||
'want to use the dd_googlesitemap.skipRootlineCheck=1 TS ' .
|
||||
'setup option. Beware: it is insecure and may cause certain ' .
|
||||
'undesired effects! Better move your news sysfolder ' .
|
||||
'inside the rootline! -->';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a pid for the single view from the category.
|
||||
*
|
||||
* @param int $newsId
|
||||
* @return int|null
|
||||
*/
|
||||
protected function getSinglePidFromCategory($newsId) {
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$res = $GLOBALS['TYPO3_DB']->exec_SELECT_mm_query(
|
||||
'tt_news_cat.single_pid',
|
||||
'tt_news',
|
||||
'tt_news_cat_mm',
|
||||
'tt_news_cat',
|
||||
' AND tt_news_cat_mm.uid_local = ' . intval($newsId)
|
||||
);
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$categoryRecord = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
|
||||
|
||||
return $categoryRecord['single_pid'] ?: NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a link to the news item
|
||||
*
|
||||
* @param array $newsRow News item
|
||||
* @param int $forceSinglePid Single View page for this news item
|
||||
* @return string
|
||||
*/
|
||||
protected function getNewsItemUrl($newsRow, $forceSinglePid = NULL) {
|
||||
$link = '';
|
||||
if (is_string($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['newsLink']) && is_array($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['newsLink'])) {
|
||||
$cObj = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
|
||||
/** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj */
|
||||
$cObj->start($newsRow, 'tt_news');
|
||||
$cObj->setCurrentVal($forceSinglePid ?: $this->singlePid);
|
||||
$link = $cObj->cObjGetSingle($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['newsLink'], $GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['newsLink']);
|
||||
unset($cObj);
|
||||
}
|
||||
if ($link == '') {
|
||||
$conf = array(
|
||||
'additionalParams' => '&tx_ttnews[tt_news]=' . $newsRow['uid'],
|
||||
'forceAbsoluteUrl' => 1,
|
||||
'parameter' => $forceSinglePid ?: $this->singlePid,
|
||||
'returnLast' => 'url',
|
||||
'useCacheHash' => true,
|
||||
);
|
||||
$link = htmlspecialchars($this->cObj->typoLink('', $conf));
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that page list is in the rootline of the current page and excludes
|
||||
* pages that are outside of the rootline.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function validateAndcreatePageList() {
|
||||
// Get pages
|
||||
$pidList = GeneralUtility::intExplode(',', GeneralUtility::_GP('pidList'));
|
||||
// Check pages
|
||||
foreach ($pidList as $pid) {
|
||||
if ($pid && $this->isInRootline($pid)) {
|
||||
$this->pidList[$pid] = $pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if supplied page id and current page are in the same root line
|
||||
*
|
||||
* @param int $pid Page id to check
|
||||
* @return boolean true if page is in the root line
|
||||
*/
|
||||
protected function isInRootline($pid) {
|
||||
if (isset($GLOBALS['TSFE']->config['config']['tx_ddgooglesitemap_skipRootlineCheck'])) {
|
||||
$skipRootlineCheck = $GLOBALS['TSFE']->config['config']['tx_ddgooglesitemap_skipRootlineCheck'];
|
||||
}
|
||||
else {
|
||||
$skipRootlineCheck = $GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['skipRootlineCheck'];
|
||||
}
|
||||
if ($skipRootlineCheck) {
|
||||
$result = true;
|
||||
}
|
||||
else {
|
||||
$result = false;
|
||||
$rootPid = intval($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['forceStartPid']);
|
||||
if ($rootPid == 0) {
|
||||
$rootPid = $GLOBALS['TSFE']->id;
|
||||
}
|
||||
$rootline = $GLOBALS['TSFE']->sys_page->getRootLine($pid);
|
||||
foreach ($rootline as $row) {
|
||||
if ($row['uid'] == $rootPid) {
|
||||
$result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
140
typo3conf/ext/dd_googlesitemap/Classes/Hooks/TceMain.php
Normal file
140
typo3conf/ext/dd_googlesitemap/Classes/Hooks/TceMain.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2008-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Hooks;
|
||||
|
||||
use \TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use \TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use \TYPO3\CMS\Core\Utility\MathUtility;
|
||||
|
||||
/**
|
||||
* Page and content manipulation watch.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
class TceMain {
|
||||
|
||||
/**
|
||||
* If > 1 than we are in the recursive call to ourselves and we do not do anything
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lock = 0;
|
||||
|
||||
/**
|
||||
* Maximum number of timestamps to save
|
||||
*
|
||||
*/
|
||||
const MAX_ENTRIES = 5;
|
||||
|
||||
/** @var int[] */
|
||||
static protected $recordedPages = array();
|
||||
|
||||
/**
|
||||
* Hooks to data change procedure to watch modified data. This hook is called
|
||||
* after data is written to the database, so all paths are modified paths.
|
||||
*
|
||||
* @param string $status Record status (new or update)
|
||||
* @param string $table Table name
|
||||
* @param int $id Record ID
|
||||
* @param array $fieldArray Modified fields
|
||||
* @param \TYPO3\CMS\Core\DataHandling\DataHandler $pObj Reference to TCEmain
|
||||
*/
|
||||
public function processDatamap_afterDatabaseOperations(/** @noinspection PhpUnusedParameterInspection */ $status, $table, $id, array $fieldArray, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {
|
||||
// Only for LIVE records!
|
||||
if ($pObj->BE_USER->workspace == 0 && !$this->lock) {
|
||||
$this->lock++;
|
||||
$this->recordPageChange($table, $id, $fieldArray, $pObj);
|
||||
$this->lock--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Records page change time in our own field
|
||||
*
|
||||
* @param string $table Table name
|
||||
* @param int $id ID of the record
|
||||
* @param array $fieldArray Field array
|
||||
* @param \TYPO3\CMS\Core\DataHandling\DataHandler $pObj Reference to TCEmain
|
||||
* @return void
|
||||
*/
|
||||
protected function recordPageChange($table, $id, array $fieldArray, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {
|
||||
if (($pid = $this->getPid($table, $id, $fieldArray, $pObj)) && !isset(self::$recordedPages[$pid])) {
|
||||
self::$recordedPages[$pid] = 1;
|
||||
|
||||
$record = BackendUtility::getRecord('pages', $pid, 'tx_ddgooglesitemap_lastmod');
|
||||
$elements = $record['tx_ddgooglesitemap_lastmod'] == '' ? array() : GeneralUtility::trimExplode(',', $record['tx_ddgooglesitemap_lastmod']);
|
||||
$time = time();
|
||||
// We must check if this time stamp is already in the list. This
|
||||
// happens with many independent updates of the page during a
|
||||
// single TCEmain action
|
||||
if (!in_array($time, $elements)) {
|
||||
$elements[] = $time;
|
||||
if (count($elements) > self::MAX_ENTRIES) {
|
||||
$elements = array_slice($elements, -self::MAX_ENTRIES);
|
||||
}
|
||||
|
||||
$datamap = array(
|
||||
'pages' => array(
|
||||
$pid => array(
|
||||
'tx_ddgooglesitemap_lastmod' => implode(',', $elements),
|
||||
),
|
||||
),
|
||||
);
|
||||
$tce = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler');
|
||||
/* @var $tce \TYPO3\CMS\Core\DataHandling\DataHandler */
|
||||
$tce->start($datamap, NULL);
|
||||
$tce->enableLogging = FALSE;
|
||||
$tce->process_datamap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains page id from the arguments
|
||||
*
|
||||
* @param string $table Table name
|
||||
* @param int $id ID of the record
|
||||
* @param array $fieldArray Field array
|
||||
* @param \TYPO3\CMS\Core\DataHandling\DataHandler $pObj Reference to TCEmain
|
||||
* @return int
|
||||
*/
|
||||
protected function getPid($table, $id, array $fieldArray, \TYPO3\CMS\Core\DataHandling\DataHandler &$pObj) {
|
||||
if (!MathUtility::canBeInterpretedAsInteger($id)) {
|
||||
$id = $pObj->substNEWwithIDs[$id];
|
||||
}
|
||||
if ($table !== 'pages') {
|
||||
if (isset($fieldArray['pid']) && MathUtility::canBeInterpretedAsInteger($fieldArray['pid']) && $fieldArray['pid'] >= 0) {
|
||||
$id = $fieldArray['pid'];
|
||||
}
|
||||
else {
|
||||
$record = BackendUtility::getRecord($table, $id, 'pid');
|
||||
$id = $record['pid'];
|
||||
}
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2009-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Renderers;
|
||||
|
||||
/**
|
||||
* This class contains an abstract renderer for sitemaps.
|
||||
*
|
||||
* NOTE: interface is internal and it is not stable. Any XCLASS is not guarantied
|
||||
* to work!
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
abstract class AbstractSitemapRenderer {
|
||||
|
||||
/**
|
||||
* Creates start XML tags (including XML prologue) for the sitemap.
|
||||
*
|
||||
* @return string Start tags
|
||||
*/
|
||||
abstract public function getStartTags();
|
||||
|
||||
/**
|
||||
* Renders one single entry according to the format of this sitemap.
|
||||
*
|
||||
* @param string $url URL of the entry
|
||||
* @param string $title Title of the entry
|
||||
* @param int $lastModification News publication time (Unix timestamp)
|
||||
* @param string $changeFrequency Unused for news
|
||||
* @param string $keywords Keywords for this entry
|
||||
* @param mixed $priority Priority (numeric, 1-10, if passed)
|
||||
* @return string Generated entry content
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::renderEntry()
|
||||
*/
|
||||
abstract public function renderEntry($url, $title, $lastModification = 0, $changeFrequency = '', $keywords = '', $priority = '');
|
||||
|
||||
/**
|
||||
* Creates end XML tags for this sitemap.
|
||||
*
|
||||
* @return string End XML tags
|
||||
*/
|
||||
abstract public function getEndTags();
|
||||
|
||||
}
|
||||
|
||||
/** @noinspection PhpUndefinedVariableInspection */
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_abstract_renderer.php']) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_abstract_renderer.php']);
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2009-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Renderers;
|
||||
|
||||
/**
|
||||
* This class contains a renderer for the 'news' sitemap.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
class NewsSitemapRenderer extends AbstractSitemapRenderer {
|
||||
|
||||
/**
|
||||
* Contains google news site name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sitename;
|
||||
|
||||
/**
|
||||
* Creates an instance of this class
|
||||
*/
|
||||
public function __construct() {
|
||||
if ($GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['google_news_site_name']) {
|
||||
$this->sitename = $GLOBALS['TSFE']->tmpl->setup['tx_ddgooglesitemap.']['google_news_site_name'];
|
||||
}
|
||||
else {
|
||||
$this->sitename = $GLOBALS['TSFE']->tmpl->setup['sitetitle'];
|
||||
}
|
||||
$this->sitename = htmlspecialchars($this->sitename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates end tags for this sitemap.
|
||||
*
|
||||
* @return string End XML tags
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::getEndTags()
|
||||
*/
|
||||
public function getEndTags() {
|
||||
return '</urlset>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates start tags for this sitemap.
|
||||
*
|
||||
* @return string Start tags
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::getStartTags()
|
||||
*/
|
||||
public function getStartTags() {
|
||||
return '<?xml version="1.0" encoding="UTF-8"?>' . chr(10) .
|
||||
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" ' .
|
||||
'xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"' .
|
||||
'>' . chr(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single entry as a news entry.
|
||||
*
|
||||
* @param string $url URL of the entry
|
||||
* @param string $title Title of the entry
|
||||
* @param int $lastModification News publication time (Unix timestamp)
|
||||
* @param string $changeFrequency Unused for news
|
||||
* @param string $keywords Keywords for this entry
|
||||
* @param mixed $priority Priority (numeric, 1-10, if passed)
|
||||
* @return string Generated entry content
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::renderEntry()
|
||||
*/
|
||||
public function renderEntry($url, $title, $lastModification = 0, $changeFrequency = '', $keywords = '', $priority = '') {
|
||||
$content = '<url>';
|
||||
$content .= '<loc>' . $url . '</loc>';
|
||||
// News must have a publication date, so we put this unconditionally!
|
||||
$content .= '<news:news>';
|
||||
$content .= '<news:publication>';
|
||||
$content .= '<news:name>' . $this->sitename . '</news:name>';
|
||||
$content .= '<news:language>' . htmlspecialchars($GLOBALS['TSFE']->lang) . '</news:language>';
|
||||
$content .= '</news:publication>';
|
||||
$content .= '<news:publication_date>' . date('c', $lastModification) . '</news:publication_date>';
|
||||
$content .= '<news:title>' . htmlspecialchars($title) . '</news:title>';
|
||||
if ($keywords) {
|
||||
$content .= '<news:keywords>' . htmlspecialchars($keywords) . '</news:keywords>';
|
||||
}
|
||||
$content .= '</news:news>';
|
||||
$content .= '</url>';
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
/** @noinspection PhpUndefinedVariableInspection */
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_news_renderer.php']) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_news_renderer.php']);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2009-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Renderers;
|
||||
|
||||
/**
|
||||
* This class contains a renderer for the 'normal' (not 'news') sitemap.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @package TYPO3
|
||||
* @subpackage tx_ddgooglesitemap
|
||||
*/
|
||||
class StandardSitemapRenderer extends AbstractSitemapRenderer {
|
||||
|
||||
/**
|
||||
* Creates end tags for this sitemap.
|
||||
*
|
||||
* @return string End XML tags
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::getEndTags()
|
||||
*/
|
||||
public function getEndTags() {
|
||||
return '</urlset>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates start tags for this sitemap.
|
||||
*
|
||||
* @return string Start tags
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::getStartTags()
|
||||
*/
|
||||
public function getStartTags() {
|
||||
return '<?xml version="1.0" encoding="UTF-8"?>' . chr(10) .
|
||||
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . chr(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a single entry as a normal sitemap entry.
|
||||
*
|
||||
* @param string $url URL of the entry
|
||||
* @param string $title Title of the entry
|
||||
* @param int $lastModification News publication time (Unix timestamp)
|
||||
* @param string $changeFrequency Unused for news
|
||||
* @param string $keywords Keywords for this entry
|
||||
* @param mixed $priority Priority (numeric, 1-10, if passed)
|
||||
* @return string Generated entry content
|
||||
* @see tx_ddgooglesitemap_abstract_renderer::renderEntry()
|
||||
*/
|
||||
public function renderEntry($url, $title, $lastModification = 0, $changeFrequency = '', $keywords = '', $priority = '') {
|
||||
$content = '<url>';
|
||||
$content .= '<loc>' . $url . '</loc>';
|
||||
if ($lastModification) {
|
||||
$content .= '<lastmod>' . date('c', $lastModification) . '</lastmod>';
|
||||
}
|
||||
if ($changeFrequency) {
|
||||
$content .= '<changefreq>' . $changeFrequency . '</changefreq>';
|
||||
}
|
||||
if ($priority != '') {
|
||||
$content .= '<priority>' . sprintf('%0.1F', $priority/10) . '</priority>';
|
||||
}
|
||||
$content .= '</url>';
|
||||
|
||||
return $content;
|
||||
}
|
||||
}
|
||||
|
||||
/** @noinspection PhpUndefinedVariableInspection */
|
||||
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_normal_renderer.php']) {
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dd_googlesitemap/renderers/class.tx_ddgooglesitemap_normal_renderer.php']);
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2013-2014 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Scheduler;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class provides information about additional fields for the scheduler
|
||||
* task of this extension. Additional fields are:
|
||||
* - the URL of the eID script (users can use different parameters for the script!)
|
||||
* - index file path (users will submit that to Google)
|
||||
* - maximum number of URLs in the sitemap (to prevent out of memory errors)
|
||||
*
|
||||
* WARNING! Due to incompatible TYPO3 6.2 changes this class now shows PHP errors
|
||||
* in TYPO3 4.5 and TYPO3 6.2 in the PhpStorm. These errors however do not happen
|
||||
* at runtime.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
*/
|
||||
class AdditionalFieldsProvider implements \TYPO3\CMS\Scheduler\AdditionalFieldProviderInterface {
|
||||
|
||||
/**
|
||||
* Gets additional fields to render in the form to add/edit a task
|
||||
*
|
||||
* @param array $taskInfo Values of the fields from the add/edit task form
|
||||
* @param \TYPO3\CMS\Scheduler\Task\AbstractTask $task The task object being edited. Null when adding a task!
|
||||
* @param \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule Reference to the scheduler backend module
|
||||
* @return array A two dimensional array, array('Identifier' => array('fieldId' => array('code' => '', 'label' => '', 'cshKey' => '', 'cshLabel' => ''))
|
||||
*/
|
||||
public function getAdditionalFields(array &$taskInfo, $task, \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule) {
|
||||
/** @var \DmitryDulepov\DdGooglesitemap\Scheduler\Task $task */
|
||||
$additionalFields = array();
|
||||
|
||||
if (!$task) {
|
||||
$url = GeneralUtility::locationHeaderUrl('/index.php?eID=dd_googlesitemap');
|
||||
$task = GeneralUtility::makeInstance('DmitryDulepov\\DdGooglesitemap\\Scheduler\\Task');
|
||||
}
|
||||
else {
|
||||
$url = $task->getEIdScriptUrl();
|
||||
}
|
||||
$indexFilePath = $task->getIndexFilePath();
|
||||
$maxUrlsPerSitemap = $task->getMaxUrlsPerSitemap();
|
||||
|
||||
$additionalFields['eIdUrl'] = array(
|
||||
'code' => '<textarea style="width:350px;height:200px" name="tx_scheduler[eIdUrl]" wrap="off">' . htmlspecialchars($url) . '</textarea>',
|
||||
'label' => 'LLL:EXT:dd_googlesitemap/locallang.xml:scheduler.eIDFieldLabel',
|
||||
'cshKey' => '',
|
||||
'cshLabel' => ''
|
||||
);
|
||||
$additionalFields['indexFilePath'] = array(
|
||||
'code' => '<input class="wide" type="text" name="tx_scheduler[indexFilePath]" value="' . htmlspecialchars($indexFilePath) . '" />',
|
||||
'label' => 'LLL:EXT:dd_googlesitemap/locallang.xml:scheduler.indexFieldLabel',
|
||||
'cshKey' => '',
|
||||
'cshLabel' => ''
|
||||
);
|
||||
$additionalFields['maxUrlsPerSitemap'] = array(
|
||||
'code' => '<input type="text" name="tx_scheduler[maxUrlsPerSitemap]" value="' . $maxUrlsPerSitemap . '" />',
|
||||
'label' => 'LLL:EXT:dd_googlesitemap/locallang.xml:scheduler.maxUrlsPerSitemapLabel',
|
||||
'cshKey' => '',
|
||||
'cshLabel' => ''
|
||||
);
|
||||
|
||||
return $additionalFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the additional fields' values
|
||||
*
|
||||
* @param array $submittedData An array containing the data submitted by the add/edit task form
|
||||
* @param \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule Reference to the scheduler backend module
|
||||
* @return boolean TRUE if validation was ok (or selected class is not relevant), FALSE otherwise
|
||||
*/
|
||||
public function validateAdditionalFields(array &$submittedData, \TYPO3\CMS\Scheduler\Controller\SchedulerModuleController $schedulerModule) {
|
||||
$errors = array();
|
||||
|
||||
$this->validateEIdUrl($submittedData, $errors);
|
||||
$this->validateMaxUrlsPerSitemap($submittedData, $errors);
|
||||
$this->validateIndexFilePath($submittedData, $errors);
|
||||
|
||||
foreach ($errors as $error) {
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$error = $GLOBALS['LANG']->sL('LLL:EXT:dd_googlesitemap/locallang.xml:' . $error);
|
||||
$this->addErrorMessage($error);
|
||||
}
|
||||
|
||||
return count($errors) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes care of saving the additional fields' values in the task's object
|
||||
*
|
||||
* @param array $submittedData An array containing the data submitted by the add/edit task form
|
||||
* @param \TYPO3\CMS\Scheduler\Task\AbstractTask $task Reference to the scheduler backend module
|
||||
* @return void
|
||||
*/
|
||||
public function saveAdditionalFields(array $submittedData, \TYPO3\CMS\Scheduler\Task\AbstractTask $task) {
|
||||
/** @var \DmitryDulepov\DdGooglesitemap\Scheduler\Task $task */
|
||||
$task->setEIdScriptUrl($submittedData['eIdUrl']);
|
||||
$task->setMaxUrlsPerSitemap($submittedData['maxUrlsPerSitemap']);
|
||||
$task->setIndexFilePath($submittedData['indexFilePath']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a error message as a flash message.
|
||||
*
|
||||
* @param string $message
|
||||
* @return void
|
||||
*/
|
||||
protected function addErrorMessage($message) {
|
||||
$flashMessage = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessage',
|
||||
$message, '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR
|
||||
);
|
||||
/** @var \TYPO3\CMS\Core\Messaging\FlashMessage $flashMessage */
|
||||
$flashMessageService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Messaging\\FlashMessageService');
|
||||
/** @var \TYPO3\CMS\Core\Messaging\FlashMessageService $flashMessageService */
|
||||
$flashMessageService->getMessageQueueByIdentifier()->enqueue($flashMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the number of urls per sitemap.
|
||||
*
|
||||
* @param array $submittedData
|
||||
* @param array $errors
|
||||
* @return void
|
||||
*/
|
||||
protected function validateMaxUrlsPerSitemap(array &$submittedData, array &$errors) {
|
||||
$submittedData['maxUrlsPerSitemap'] = intval($submittedData['maxUrlsPerSitemap']);
|
||||
if ($submittedData['maxUrlsPerSitemap'] <= 0) {
|
||||
$errors[] = 'scheduler.error.badNumberOfUrls';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates index file path.
|
||||
*
|
||||
* @param array $submittedData
|
||||
* @param array $errors
|
||||
* @return void
|
||||
*/
|
||||
protected function validateIndexFilePath(array &$submittedData, array &$errors) {
|
||||
if (GeneralUtility::isAbsPath($submittedData['indexFilePath'])) {
|
||||
$errors[] = 'scheduler.error.badIndexFilePath';
|
||||
}
|
||||
else {
|
||||
$testPath = GeneralUtility::getFileAbsFileName($submittedData['indexFilePath'], TRUE);
|
||||
if (!file_exists($testPath)) {
|
||||
if (!@touch($testPath)) {
|
||||
$errors[] = 'scheduler.error.badIndexFilePath';
|
||||
}
|
||||
else {
|
||||
unlink($testPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Valies the URL of the eID script.
|
||||
*
|
||||
* @param array $submittedData
|
||||
* @param array $errors
|
||||
*/
|
||||
protected function validateEIdUrl(array &$submittedData, array &$errors) {
|
||||
foreach (GeneralUtility::trimExplode(chr(10), $submittedData['eIdUrl']) as $url) {
|
||||
if (FALSE !== ($urlParts = parse_url($url))) {
|
||||
if (!$urlParts['host']) {
|
||||
$errors[] = 'scheduler.error.missingHost';
|
||||
}
|
||||
else {
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
list($count) = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('COUNT(*) AS counter', 'sys_domain',
|
||||
'domainName=' . $GLOBALS['TYPO3_DB']->fullQuoteStr($urlParts['host'], 'sys_domain')
|
||||
);
|
||||
if ($count['counter'] == 0) {
|
||||
$errors[] = 'scheduler.error.missingHost';
|
||||
}
|
||||
}
|
||||
if (!preg_match('/(?:^|&)eID=dd_googlesitemap/', $urlParts['query'])) {
|
||||
$errors[] = 'scheduler.error.badPath';
|
||||
}
|
||||
if (preg_match('/(?:^|&)(?:offset|limit)=/', $urlParts['query'])) {
|
||||
$errors[] = 'scheduler.error.badParameters';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
300
typo3conf/ext/dd_googlesitemap/Classes/Scheduler/Task.php
Normal file
300
typo3conf/ext/dd_googlesitemap/Classes/Scheduler/Task.php
Normal file
@@ -0,0 +1,300 @@
|
||||
<?php
|
||||
/***************************************************************
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2013 Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* All rights reserved
|
||||
*
|
||||
* This script is part of the TYPO3 project. The TYPO3 project is
|
||||
* free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The GNU General Public License can be found at
|
||||
* http://www.gnu.org/copyleft/gpl.html.
|
||||
*
|
||||
* This script is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* This copyright notice MUST APPEAR in all copies of the script!
|
||||
***************************************************************/
|
||||
|
||||
namespace DmitryDulepov\DdGooglesitemap\Scheduler;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* This class provides a scheduler task to create sitemap index as required
|
||||
* by the Google sitemap protocol.
|
||||
*
|
||||
* @author Dmitry Dulepov <dmitry.dulepov@gmail.com>
|
||||
* @see http://support.google.com/webmasters/bin/answer.py?hl=en&answer=71453
|
||||
*/
|
||||
class Task extends \TYPO3\CMS\Scheduler\Task\AbstractTask {
|
||||
|
||||
const DEFAULT_FILE_PATH = 'typo3temp/dd_googlesitemap';
|
||||
|
||||
/** @var string */
|
||||
private $baseUrl;
|
||||
|
||||
/** @var string */
|
||||
protected $eIdScriptUrl;
|
||||
|
||||
/** @var string */
|
||||
protected $indexFilePath;
|
||||
|
||||
/** @var int */
|
||||
protected $maxUrlsPerSitemap = 50000;
|
||||
|
||||
/** @var string */
|
||||
private $sitemapFileFormat;
|
||||
|
||||
/** @var int */
|
||||
private $offset;
|
||||
|
||||
/**
|
||||
* Creates the instance of the class. This call initializes the index file
|
||||
* path to the random value. After the task is configured, the user may
|
||||
* change the file and the file name will be serialized with the task and
|
||||
* used later.
|
||||
*
|
||||
* @see __sleep
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->indexFilePath = self::DEFAULT_FILE_PATH . '/' . GeneralUtility::getRandomHexString(24) . '.xml';
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstructs some variables after the object is unserialized.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __wakeup() {
|
||||
$this->buildSitemapFileFormat();
|
||||
$this->buildBaseUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the main method that is called when a task is executed
|
||||
* It MUST be implemented by all classes inheriting from this one
|
||||
* Note that there is no error handling, errors and failures are expected
|
||||
* to be handled and logged by the client implementations.
|
||||
* Should return true on successful execution, false on error.
|
||||
*
|
||||
* @return boolean Returns true on successful execution, false on error
|
||||
*/
|
||||
public function execute() {
|
||||
$indexFilePathTemp = PATH_site . $this->indexFilePath . '.tmp';
|
||||
$indexFile = fopen($indexFilePathTemp, 'wt');
|
||||
fwrite($indexFile, '<?xml version="1.0" encoding="UTF-8"?>' . chr(10));
|
||||
fwrite($indexFile, '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . chr(10));
|
||||
|
||||
$eIDscripts = GeneralUtility::trimExplode(chr(10), $this->eIdScriptUrl);
|
||||
$eIdIndex = 1;
|
||||
foreach ($eIDscripts as $eIdScriptUrl) {
|
||||
$this->offset = 0;
|
||||
$currentFileNumber = 1;
|
||||
$lastFileHash = '';
|
||||
do {
|
||||
$sitemapFileName = sprintf($this->sitemapFileFormat, $eIdIndex, $currentFileNumber++);
|
||||
$this->buildSitemap($eIdScriptUrl, $sitemapFileName);
|
||||
|
||||
$isSitemapEmpty = $this->isSitemapEmpty($sitemapFileName);
|
||||
$currentFileHash = $isSitemapEmpty ? -1 : md5_file(PATH_site . $sitemapFileName);
|
||||
$stopLoop = $isSitemapEmpty || ($currentFileHash == $lastFileHash);
|
||||
|
||||
if ($stopLoop) {
|
||||
@unlink(PATH_site . $sitemapFileName);
|
||||
}
|
||||
else {
|
||||
fwrite($indexFile, '<sitemap><loc>' . htmlspecialchars($this->makeSitemapUrl($sitemapFileName)) . '</loc></sitemap>' . chr(10));
|
||||
$lastFileHash = $currentFileHash;
|
||||
}
|
||||
} while (!$stopLoop);
|
||||
$eIdIndex++;
|
||||
}
|
||||
|
||||
fwrite($indexFile, '</sitemapindex>' . chr(10));
|
||||
fclose($indexFile);
|
||||
|
||||
@unlink(PATH_site . $this->indexFilePath);
|
||||
rename($indexFilePathTemp, PATH_site . $this->indexFilePath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is designed to return some additional information about the task,
|
||||
* that may help to set it apart from other tasks from the same class
|
||||
* This additional information is used - for example - in the Scheduler's BE module
|
||||
* This method should be implemented in most task classes
|
||||
*
|
||||
* @return string Information to display
|
||||
*/
|
||||
public function getAdditionalInformation() {
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
$format = $GLOBALS['LANG']->sL('LLL:EXT:dd_googlesitemap/locallang.xml:scheduler.extra_info');
|
||||
return sprintf($format, $this->getIndexFileUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the url of the eID script. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @return string
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function getEIdScriptUrl() {
|
||||
return $this->eIdScriptUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index file path. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @return string
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function getIndexFilePath() {
|
||||
return $this->indexFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the number of urls per sitemap. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @return int
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function getMaxUrlsPerSitemap() {
|
||||
return $this->maxUrlsPerSitemap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URl of the eID script. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @param $url
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function setEIdScriptUrl($url) {
|
||||
$this->eIdScriptUrl = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the URL of the eID script. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @param string $path
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function setIndexFilePath($path) {
|
||||
$this->indexFilePath = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of URLs per sitemap. This is called from the task
|
||||
* configuration inside scheduler.
|
||||
*
|
||||
* @param int $maxUrlsPerSitemap
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
public function setMaxUrlsPerSitemap($maxUrlsPerSitemap) {
|
||||
$this->maxUrlsPerSitemap = $maxUrlsPerSitemap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a base url for sitemaps.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function buildBaseUrl() {
|
||||
$urlParts = parse_url($this->eIdScriptUrl);
|
||||
$this->baseUrl = $urlParts['scheme'] . '://';
|
||||
if ($urlParts['user']) {
|
||||
$this->baseUrl .= $urlParts['user'];
|
||||
if ($urlParts['pass']) {
|
||||
$this->baseUrl .= ':' . $urlParts['pass'];
|
||||
}
|
||||
$this->baseUrl .= '@';
|
||||
}
|
||||
$this->baseUrl .= $urlParts['host'];
|
||||
if ($urlParts['port']) {
|
||||
$this->baseUrl .= ':' . $urlParts['port'];
|
||||
}
|
||||
$this->baseUrl .= '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the sitemap.
|
||||
*
|
||||
* @param string $eIdScriptUrl
|
||||
* @param string $sitemapFileName
|
||||
* @see tx_ddgooglesitemap_additionalfieldsprovider
|
||||
*/
|
||||
protected function buildSitemap($eIdScriptUrl, $sitemapFileName) {
|
||||
$url = $eIdScriptUrl . sprintf('&offset=%d&limit=%d', $this->offset, $this->maxUrlsPerSitemap);
|
||||
|
||||
$content = GeneralUtility::getURL($url);
|
||||
if ($content) {
|
||||
file_put_contents(PATH_site . $sitemapFileName, $content);
|
||||
$this->offset += $this->maxUrlsPerSitemap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the format string for the sitemap files.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function buildSitemapFileFormat() {
|
||||
$fileParts = pathinfo($this->indexFilePath);
|
||||
$this->sitemapFileFormat = $fileParts['dirname'] . '/' . $fileParts['filename'] . '_sitemap_%05d_%05d.xml';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index file url.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getIndexFileUrl() {
|
||||
return $this->baseUrl . $this->indexFilePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current sitemap has no entries. The function reads a chunk
|
||||
* of the file, which is large enough to have a '<url>' token in it and
|
||||
* examines the chunk. If the token is not found, than the sitemap is either
|
||||
* empty or corrupt.
|
||||
*
|
||||
* @param string $sitemapFileName
|
||||
* @return bool
|
||||
*/
|
||||
protected function isSitemapEmpty($sitemapFileName) {
|
||||
$result = TRUE;
|
||||
|
||||
$fileDescriptor = @fopen(PATH_site . $sitemapFileName, 'rt');
|
||||
if ($fileDescriptor) {
|
||||
$chunkSizeToCheck = 10240;
|
||||
$testString = fread($fileDescriptor, $chunkSizeToCheck);
|
||||
fclose($fileDescriptor);
|
||||
$result = (strpos($testString, '<url>') === FALSE);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a url to the sitemap.
|
||||
*
|
||||
* @param string $siteMapPath
|
||||
* @return string
|
||||
*/
|
||||
protected function makeSitemapUrl($siteMapPath) {
|
||||
return $this->baseUrl . $siteMapPath;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user