Initial commit
This commit is contained in:
123
typo3conf/ext/metaseo/Classes/Backend/Module/AbstractModule.php
Normal file
123
typo3conf/ext/metaseo/Classes/Backend/Module/AbstractModule.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Backend\Module;
|
||||
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
|
||||
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend module base
|
||||
*/
|
||||
abstract class AbstractModule extends ActionController
|
||||
{
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Backend Form Protection object
|
||||
*
|
||||
* @var \TYPO3\CMS\Core\FormProtection\BackendFormProtection
|
||||
*/
|
||||
protected $formProtection;
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Initializes the controller before invoking an action method.
|
||||
*
|
||||
* Override this method to solve tasks which all actions have in
|
||||
* common.
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
*/
|
||||
protected function initializeAction()
|
||||
{
|
||||
$this->formProtection = \TYPO3\CMS\Core\FormProtection\FormProtectionFactory::get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate list
|
||||
*
|
||||
* @param array $list Translation keys
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function translateList(array $list)
|
||||
{
|
||||
unset($token);
|
||||
foreach ($list as &$token) {
|
||||
if (!empty($token)) {
|
||||
if (is_array($token)) {
|
||||
$token = $this->translateList($token);
|
||||
} else {
|
||||
$token = $this->translate($token);
|
||||
}
|
||||
}
|
||||
}
|
||||
unset($token);
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate key
|
||||
*
|
||||
* @param string $key Translation key
|
||||
* @param null|array $arguments Arguments (vsprintf)
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected function translate($key, array $arguments = null)
|
||||
{
|
||||
$ret = LocalizationUtility::translate($key, $this->extensionName, $arguments);
|
||||
|
||||
// Not translated handling
|
||||
if ($ret === null) {
|
||||
$ret = '[-' . $key . '-]';
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create session token
|
||||
*
|
||||
* @param string $formName Form name/Session token name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function sessionToken($formName)
|
||||
{
|
||||
$token = $this->formProtection->generateToken($formName);
|
||||
|
||||
return $token;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Backend\Module;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend module standalone
|
||||
*/
|
||||
abstract class AbstractStandardModule extends AbstractModule
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Backend\Module;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend module tree
|
||||
*/
|
||||
abstract class AbstractTreeModule extends AbstractModule
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Backend\Validator;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend field validation: float
|
||||
*/
|
||||
class FloatValidator
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns JavaScript validation function body
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function returnFieldJS()
|
||||
{
|
||||
return '
|
||||
value = value.replace(/[^-0-9,.]/g,\'\');
|
||||
|
||||
var ret = 0;
|
||||
try {
|
||||
if (isNaN(value) ) {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
ret = parseFloat(value);
|
||||
} catch(e) {}
|
||||
|
||||
if (isNaN(ret) ) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate number on serverside
|
||||
*
|
||||
* @param string $value Value
|
||||
* @param mixed $is_in Is in value (config)
|
||||
* @param mixed $set Set
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function evaluateFieldValue($value, $is_in, &$set)
|
||||
{
|
||||
return (float)$value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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!
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Class tx_metaseo_backend_validation_float
|
||||
* (Used in TCA because of namespace issues)
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class tx_metaseo_backend_validation_float extends \Metaseo\Metaseo\Backend\Validator\FloatValidator
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Command;
|
||||
|
||||
use Metaseo\Metaseo\Utility\ConsoleUtility;
|
||||
use Metaseo\Metaseo\Utility\DatabaseUtility;
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
use Metaseo\Metaseo\Utility\RootPageUtility;
|
||||
use Metaseo\Metaseo\Utility\SitemapUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
|
||||
|
||||
/**
|
||||
* TYPO3 Command controller
|
||||
*/
|
||||
class MetaseoCommandController extends CommandController
|
||||
{
|
||||
|
||||
/**
|
||||
* Get whole list of sitemap entries
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function garbageCollectorCommand()
|
||||
{
|
||||
// Expire sitemap entries
|
||||
SitemapUtility::expire();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear sitemap for one root page
|
||||
*
|
||||
* @param string $rootPageId Site root page id or domain
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function clearSitemapCommand($rootPageId)
|
||||
{
|
||||
$rootPageId = $this->getRootPageIdFromId($rootPageId);
|
||||
|
||||
if ($rootPageId !== null) {
|
||||
$query = 'DELETE FROM tx_metaseo_sitemap
|
||||
WHERE page_rootpid = ' . DatabaseUtility::quote($rootPageId, 'tx_metaseo_sitemap') . '
|
||||
AND is_blacklisted = 0';
|
||||
DatabaseUtility::exec($query);
|
||||
|
||||
ConsoleUtility::writeLine('Sitemap cleared');
|
||||
} else {
|
||||
ConsoleUtility::writeErrorLine('No such root page found');
|
||||
ConsoleUtility::terminate(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get whole list of sitemap entries
|
||||
*
|
||||
* @param string $rootPageId Site root page id or domain
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sitemapCommand($rootPageId)
|
||||
{
|
||||
$rootPageId = $this->getRootPageIdFromId($rootPageId);
|
||||
|
||||
if ($rootPageId !== null) {
|
||||
$domain = RootPageUtility::getDomain($rootPageId);
|
||||
|
||||
$query = 'SELECT page_url
|
||||
FROM tx_metaseo_sitemap
|
||||
WHERE page_rootpid = ' . DatabaseUtility::quote($rootPageId, 'tx_metaseo_sitemap') . '
|
||||
AND is_blacklisted = 0';
|
||||
$urlList = DatabaseUtility::getCol($query);
|
||||
|
||||
foreach ($urlList as $url) {
|
||||
if ($domain) {
|
||||
$url = GeneralUtility::fullUrl($url, $domain);
|
||||
}
|
||||
|
||||
ConsoleUtility::writeLine($url);
|
||||
}
|
||||
} else {
|
||||
ConsoleUtility::writeErrorLine('No such root page found');
|
||||
ConsoleUtility::terminate(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detect root page from id (either PID or sys_domain)
|
||||
*
|
||||
* @param integer|string $var
|
||||
*
|
||||
* @return integer|null
|
||||
*/
|
||||
protected function getRootPageIdFromId($var)
|
||||
{
|
||||
if (is_numeric($var)) {
|
||||
// Passed variable is numeric
|
||||
$pageId = (int)$var;
|
||||
|
||||
/** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */
|
||||
$objectManager = Typo3GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Extbase\\Object\\ObjectManager'
|
||||
);
|
||||
|
||||
/** @var \TYPO3\CMS\Frontend\Page\PageRepository $pageRepo */
|
||||
$pageRepo = $objectManager->get('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
|
||||
|
||||
$page = $pageRepo->getPage($pageId);
|
||||
|
||||
if (empty($page['is_siteroot'])) {
|
||||
throw new \RuntimeException('MetaSEO: Page with UID "' . $pageId . '" is no valid root page');
|
||||
}
|
||||
|
||||
return $page['uid'];
|
||||
}
|
||||
|
||||
// Passed variable is domain name
|
||||
$query = 'SELECT pid
|
||||
FROM sys_domain
|
||||
WHERE domainName = ' . DatabaseUtility::quote($var, 'sys_domain') . '
|
||||
AND hidden = 0';
|
||||
$pid = DatabaseUtility::getOne($query);
|
||||
|
||||
if (empty($pid)) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $pid;
|
||||
}
|
||||
}
|
||||
232
typo3conf/ext/metaseo/Classes/Connector.php
Normal file
232
typo3conf/ext/metaseo/Classes/Connector.php
Normal file
@@ -0,0 +1,232 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo;
|
||||
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
|
||||
/**
|
||||
* Connector
|
||||
*/
|
||||
class Connector implements SingletonInterface
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Data store
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $store = array(
|
||||
'flag' => array(),
|
||||
'meta' => array(),
|
||||
'meta:og' => array(),
|
||||
'custom' => array(),
|
||||
'pagetitle' => array(),
|
||||
'sitemap' => array(),
|
||||
);
|
||||
|
||||
// ########################################################################
|
||||
// Page title methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Set page title
|
||||
*
|
||||
* @param string $value Page title
|
||||
* @param boolean $updateTsfe Update TSFE values
|
||||
*/
|
||||
public static function setPageTitle($value, $updateTsfe = true)
|
||||
{
|
||||
$value = (string)$value;
|
||||
|
||||
if ($updateTsfe && !empty($GLOBAL['TSFE'])) {
|
||||
$GLOBAL['TSFE']->page['title'] = $value;
|
||||
$GLOBAL['TSFE']->indexedDocTitle = $value;
|
||||
}
|
||||
|
||||
self::$store['pagetitle']['pagetitle.title'] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set page title suffix
|
||||
*
|
||||
* @param string $value Page title suffix
|
||||
*/
|
||||
public static function setPageTitleSuffix($value)
|
||||
{
|
||||
self::$store['pagetitle']['pagetitle.suffix'] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set page title prefix
|
||||
*
|
||||
* @param string $value Page title Prefix
|
||||
*/
|
||||
public static function setPageTitlePrefix($value)
|
||||
{
|
||||
self::$store['pagetitle']['pagetitle.prefix'] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set page title (absolute)
|
||||
*
|
||||
* @param string $value Page title
|
||||
* @param boolean $updateTsfe Update TSFE values
|
||||
*/
|
||||
public static function setPageTitleAbsolute($value, $updateTsfe = true)
|
||||
{
|
||||
if ($updateTsfe && !empty($GLOBALS['TSFE'])) {
|
||||
$GLOBALS['TSFE']->page['title'] = $value;
|
||||
$GLOBALS['TSFE']->indexedDocTitle = $value;
|
||||
}
|
||||
|
||||
self::$store['pagetitle']['pagetitle.absolute'] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set page title sitetitle
|
||||
*
|
||||
* @param string $value Page title
|
||||
*/
|
||||
public static function setPageTitleSitetitle($value)
|
||||
{
|
||||
self::$store['pagetitle']['pagetitle.sitetitle'] = $value;
|
||||
}
|
||||
|
||||
// ########################################################################
|
||||
// MetaTag methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Set meta tag
|
||||
*
|
||||
* @param string $key Metatag name
|
||||
* @param string $value Metatag value
|
||||
*/
|
||||
public static function setMetaTag($key, $value)
|
||||
{
|
||||
$key = (string)$key;
|
||||
$value = (string)$value;
|
||||
|
||||
if (strpos($key, 'og:') === 0) {
|
||||
self::setOpenGraphTag($key, $value);
|
||||
}
|
||||
|
||||
self::$store['meta'][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set opengraph tag
|
||||
*
|
||||
* @param string $key Metatag name
|
||||
* @param string $value Metatag value
|
||||
*/
|
||||
public static function setOpenGraphTag($key, $value)
|
||||
{
|
||||
$key = (string)$key;
|
||||
$value = (string)$value;
|
||||
|
||||
self::$store['flag']['meta:og:external'] = true;
|
||||
self::$store['meta:og'][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set meta tag
|
||||
*
|
||||
* @param string $key Metatag name
|
||||
* @param string $value Metatag value
|
||||
*/
|
||||
public static function setCustomMetaTag($key, $value)
|
||||
{
|
||||
$key = (string)$key;
|
||||
$value = (string)$value;
|
||||
|
||||
self::$store['custom'][$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable meta tag
|
||||
*
|
||||
* @param string $key Metatag name
|
||||
*/
|
||||
public static function disableMetaTag($key)
|
||||
{
|
||||
$key = (string)$key;
|
||||
|
||||
self::$store['meta'][$key] = null;
|
||||
}
|
||||
|
||||
// ########################################################################
|
||||
// Sitemap methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Set sitemap index expiration in days
|
||||
*
|
||||
* @param integer $days Entry expiration in days
|
||||
*/
|
||||
public static function setSitemapIndexExpiration($days)
|
||||
{
|
||||
self::$store['sitemap']['expiration'] = abs($days);
|
||||
}
|
||||
|
||||
// ########################################################################
|
||||
// Control methods
|
||||
// ########################################################################
|
||||
|
||||
// TODO
|
||||
|
||||
|
||||
// ########################################################################
|
||||
// General methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Get store
|
||||
*
|
||||
* @param string $key Store key (optional, if empty whole store is returned)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getStore($key = null)
|
||||
{
|
||||
$ret = null;
|
||||
|
||||
if ($key !== null) {
|
||||
if (isset(self::$store[$key])) {
|
||||
$ret = self::$store[$key];
|
||||
}
|
||||
} else {
|
||||
$ret = self::$store;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller;
|
||||
|
||||
use Exception;
|
||||
use Metaseo\Metaseo\DependencyInjection\Utility\HttpUtility;
|
||||
use Metaseo\Metaseo\Exception\Ajax\AjaxException;
|
||||
use TYPO3\CMS\Core\Http\AjaxRequestHandler;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Object\ObjectManager;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend ajax module base
|
||||
*/
|
||||
abstract class AbstractAjaxController
|
||||
{
|
||||
const CONTENT_FORMAT_JSON = 'json';
|
||||
|
||||
/**
|
||||
* Json status indicators
|
||||
*/
|
||||
const JSON_ERROR = 'error';
|
||||
const JSON_ERROR_NUMBER = 'errorNumber';
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* POST vars (transformed from json)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $postVar;
|
||||
|
||||
/**
|
||||
* Sorting field
|
||||
*/
|
||||
protected $sortField;
|
||||
|
||||
/**
|
||||
* Sorting dir
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sortDir;
|
||||
|
||||
/**
|
||||
* TYPO3 Object manager
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManager
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->postVar = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect and process POST vars and stores them into $this->postVars
|
||||
*/
|
||||
protected function fetchParams()
|
||||
{
|
||||
$rawPostVarList = GeneralUtility::_POST();
|
||||
foreach ($rawPostVarList as $key => $value) {
|
||||
$this->postVar[$key] = json_decode($value);
|
||||
}
|
||||
|
||||
// Sorting data
|
||||
if (!empty($rawPostVarList['sort'])) {
|
||||
$this->sortField = $this->escapeSortField((string)$rawPostVarList['sort']);
|
||||
}
|
||||
|
||||
if (!empty($rawPostVarList['dir'])) {
|
||||
switch (strtoupper($rawPostVarList['dir'])) {
|
||||
case 'ASC':
|
||||
$this->sortDir = 'ASC';
|
||||
break;
|
||||
case 'DESC':
|
||||
$this->sortDir = 'DESC';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape for sql sort fields
|
||||
*
|
||||
* @param string $value Sort value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function escapeSortField($value)
|
||||
{
|
||||
return preg_replace('[^_a-zA-Z]', '', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
$this->fetchParams();
|
||||
|
||||
// Include ajax local lang
|
||||
$this->getLanguageService()->includeLLFile('EXT:metaseo/Resources/Private/Language/locallang.xlf');
|
||||
|
||||
if (!isset($this->objectManager)) {
|
||||
$this->objectManager = GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Extbase\\Object\\ObjectManager'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getAjaxPrefix();
|
||||
|
||||
/**
|
||||
* Returns a json formatted error response with http error status specified in the Exception
|
||||
* The message is created with $ajaxObj->setContent instead of setError because $ajaxObj->setError
|
||||
* always sets http status 500 and does not respect content format.
|
||||
*
|
||||
* @param Exception $exception
|
||||
* @param AjaxRequestHandler $ajaxObj
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function ajaxExceptionHandler(Exception $exception, AjaxRequestHandler &$ajaxObj)
|
||||
{
|
||||
$responseArray = array();
|
||||
if ($exception instanceof AjaxException) {
|
||||
$responseArray[self::JSON_ERROR] = $this->translate($exception->getMessage());
|
||||
$this->getHttpUtility()->sendHttpHeader($exception->getHttpStatus());
|
||||
$errorCode = $exception->getCode();
|
||||
if (!empty($errorCode)) {
|
||||
$responseArray[self::JSON_ERROR_NUMBER] = $exception->getCode();
|
||||
}
|
||||
} else {
|
||||
$responseArray[self::JSON_ERROR] = $exception->getMessage();
|
||||
$this->getHttpUtility()->sendHttpHeader(HttpUtility::HTTP_STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
$ajaxObj->setContent($responseArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate a key to the current chosen language
|
||||
*
|
||||
* @param $messageKey string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function translate($messageKey)
|
||||
{
|
||||
return $this
|
||||
->getLanguageService()
|
||||
->getLL($messageKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the TYPO3 CMS LanguageService
|
||||
*
|
||||
* @return \TYPO3\CMS\Lang\LanguageService
|
||||
*/
|
||||
protected function getLanguageService()
|
||||
{
|
||||
return $GLOBALS['LANG'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUserAuthentication()
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HttpUtility
|
||||
*/
|
||||
protected function getHttpUtility()
|
||||
{
|
||||
return $this->objectManager->get('Metaseo\\Metaseo\\DependencyInjection\\Utility\\HttpUtility');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ObjectManager $objectManager
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setObjectManager(ObjectManager $objectManager)
|
||||
{
|
||||
$this->objectManager = $objectManager;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,412 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax;
|
||||
|
||||
use Exception;
|
||||
use Metaseo\Metaseo\Controller\AbstractAjaxController;
|
||||
use Metaseo\Metaseo\Controller\Ajax\PageSeo as PageSeo;
|
||||
use Metaseo\Metaseo\DependencyInjection\Utility\HttpUtility;
|
||||
use Metaseo\Metaseo\Exception\Ajax\AjaxException;
|
||||
use TYPO3\CMS\Core\Http\AjaxRequestHandler;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend ajax module page
|
||||
*/
|
||||
abstract class AbstractPageSeoController extends AbstractAjaxController implements PageSeoInterface
|
||||
{
|
||||
const LIST_TYPE = 'undefined';
|
||||
const AJAX_PREFIX = 'tx_metaseo_controller_ajax_pageseo_';
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* List of page uids which have templates
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $templatePidList;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldList;
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->templatePidList = array();
|
||||
$this->initFieldList();
|
||||
}
|
||||
|
||||
abstract protected function initFieldList();
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function indexAction($params = array(), AjaxRequestHandler &$ajaxObj = null)
|
||||
{
|
||||
try {
|
||||
$this->init();
|
||||
$ajaxObj->setContent($this->executeIndex());
|
||||
} catch (Exception $exception) {
|
||||
$this->ajaxExceptionHandler($exception, $ajaxObj);
|
||||
}
|
||||
|
||||
$ajaxObj->setContentFormat(self::CONTENT_FORMAT_JSON);
|
||||
$ajaxObj->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws AjaxException
|
||||
*/
|
||||
protected function executeIndex()
|
||||
{
|
||||
$pid = (int)$this->postVar['pid'];
|
||||
$depth = (int)$this->postVar['depth'];
|
||||
$sysLanguage = (int)$this->postVar['sysLanguage'];
|
||||
|
||||
// Store last selected language
|
||||
$this->getBackendUserAuthentication()
|
||||
->setAndSaveSessionData('MetaSEO.sysLanguage', $sysLanguage);
|
||||
|
||||
if (empty($pid)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.typo3_page_not_found',
|
||||
'[0x4FBF3C0C]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$page = $this->getPageSeoDao()->getPageById($pid);
|
||||
|
||||
$list = $this->getIndex($page, $depth, $sysLanguage);
|
||||
|
||||
return array(
|
||||
'results' => count($list),
|
||||
'rows' => array_values($list),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return default tree
|
||||
*
|
||||
* This function is made for list manipulation in subclasses (method template design pattern)
|
||||
*
|
||||
* @param array $page Root page
|
||||
* @param integer $depth Depth
|
||||
* @param integer $sysLanguage System language
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getIndex(array $page, $depth, $sysLanguage)
|
||||
{
|
||||
return $this->getPageSeoDao()->index($page, $depth, $sysLanguage, $this->fieldList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function updateAction($params = array(), AjaxRequestHandler &$ajaxObj = null)
|
||||
{
|
||||
try {
|
||||
$this->init();
|
||||
$ajaxObj->setContent($this->executeUpdate());
|
||||
} catch (Exception $exception) {
|
||||
$this->ajaxExceptionHandler($exception, $ajaxObj);
|
||||
}
|
||||
|
||||
$ajaxObj->setContentFormat(self::CONTENT_FORMAT_JSON);
|
||||
$ajaxObj->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws AjaxException
|
||||
*/
|
||||
protected function executeUpdate()
|
||||
{
|
||||
if (empty($this->postVar['pid']) || empty($this->postVar['field'])) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.warning.incomplete_data_received.message',
|
||||
'[0x4FBF3C02]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$pid = (int)$this->postVar['pid'];
|
||||
$fieldName = strtolower((string)$this->postVar['field']);
|
||||
$fieldValue = (string)$this->postVar['value'];
|
||||
$sysLanguage = (int)$this->postVar['sysLanguage'];
|
||||
|
||||
// validate field name: must match exactly to list of known field names
|
||||
if (!in_array($fieldName, array_merge($this->fieldList, array('title')))) {
|
||||
throw new AjaxException(
|
||||
'message.warning.incomplete_data_received.message',
|
||||
'[0x4FBF3C23]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($fieldName)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.warning.incomplete_data_received.message',
|
||||
'[0x4FBF3C03]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
// ############################
|
||||
// Security checks
|
||||
// ############################
|
||||
|
||||
|
||||
// check if user is able to modify pages
|
||||
if (!$this->getBackendUserAuthentication()->check('tables_modify', 'pages')) {
|
||||
// No access
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.access_denied',
|
||||
'[0x4FBF3BE2]',
|
||||
HttpUtility::HTTP_STATUS_UNAUTHORIZED
|
||||
);
|
||||
}
|
||||
|
||||
$page = $this->getPageSeoDao()->getPageById($pid);
|
||||
|
||||
// check if page exists and user can edit this specific record
|
||||
if (empty($page) || !$this->getBackendUserAuthentication()->doesUserHaveAccess($page, 2)) {
|
||||
// No access
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.access_denied',
|
||||
'[0x4FBF3BCF]',
|
||||
HttpUtility::HTTP_STATUS_UNAUTHORIZED
|
||||
);
|
||||
}
|
||||
|
||||
// check if user is able to modify the field of pages
|
||||
if (!$this->getBackendUserAuthentication()
|
||||
->check('non_exclude_fields', 'pages:' . $fieldName)
|
||||
) {
|
||||
// No access
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.access_denied',
|
||||
'[0x4FBF3BD9]',
|
||||
HttpUtility::HTTP_STATUS_UNAUTHORIZED
|
||||
);
|
||||
}
|
||||
|
||||
// also check for sys language
|
||||
if (!empty($sysLanguage)) {
|
||||
// check if user is able to modify pages
|
||||
if (!$this->getBackendUserAuthentication()
|
||||
->check('tables_modify', 'pages_language_overlay')
|
||||
) {
|
||||
// No access
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.access_denied',
|
||||
'[0x4FBF3BE2]',
|
||||
HttpUtility::HTTP_STATUS_UNAUTHORIZED
|
||||
);
|
||||
}
|
||||
|
||||
// check if user is able to modify the field of pages
|
||||
if (!$this->getBackendUserAuthentication()
|
||||
->check('non_exclude_fields', 'pages_language_overlay:' . $fieldName)
|
||||
) {
|
||||
// No access
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.access_denied',
|
||||
'[0x4FBF3BD9]',
|
||||
HttpUtility::HTTP_STATUS_UNAUTHORIZED
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ############################
|
||||
// Transformations
|
||||
// ############################
|
||||
|
||||
switch ($fieldName) {
|
||||
case 'lastupdated':
|
||||
// transform to unix timestamp
|
||||
$fieldValue = strtotime($fieldValue);
|
||||
break;
|
||||
}
|
||||
|
||||
// ############################
|
||||
// Update
|
||||
// ############################
|
||||
|
||||
return $this->getPageSeoDao()->updatePageTableField($pid, $sysLanguage, $fieldName, $fieldValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function updateRecursiveAction($params = array(), AjaxRequestHandler &$ajaxObj = null)
|
||||
{
|
||||
try {
|
||||
$this->init();
|
||||
$ajaxObj->setContent($this->executeUpdateRecursive());
|
||||
} catch (Exception $exception) {
|
||||
$this->ajaxExceptionHandler($exception, $ajaxObj);
|
||||
}
|
||||
|
||||
$ajaxObj->setContentFormat(self::CONTENT_FORMAT_JSON);
|
||||
$ajaxObj->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws AjaxException
|
||||
*/
|
||||
protected function executeUpdateRecursive()
|
||||
{
|
||||
if (empty($this->postVar['pid']) || empty($this->postVar['field'])) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.warning.incomplete_data_received.message',
|
||||
'[0x4FBF3C04]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$pid = $this->postVar['pid'];
|
||||
$sysLanguage = (int)$this->postVar['sysLanguage'];
|
||||
|
||||
$page = $this->getPageSeoDao()->getPageById($pid);
|
||||
|
||||
$list = $this->getPageSeoDao()->index($page, 999, $sysLanguage, array());
|
||||
|
||||
$count = 0;
|
||||
foreach ($list as $key => $page) {
|
||||
$this->postVar['pid'] = $key;
|
||||
$this->executeUpdate();
|
||||
$count++;
|
||||
}
|
||||
|
||||
return array(
|
||||
'updateCount' => $count, //not in use yet
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getAjaxPrefix()
|
||||
{
|
||||
return self::AJAX_PREFIX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Metaseo\Metaseo\Dao\PageSeoDao
|
||||
*/
|
||||
protected function getPageSeoDao()
|
||||
{
|
||||
return $this
|
||||
->objectManager
|
||||
->get('Metaseo\\Metaseo\\Dao\\PageSeoDao')
|
||||
->setPageTreeView($this->getPageTreeView())
|
||||
->setDataHandler($this->getDataHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\DataHandling\DataHandler
|
||||
*/
|
||||
protected function getDataHandler()
|
||||
{
|
||||
return $this->objectManager->get('TYPO3\\CMS\\Core\\DataHandling\\DataHandler');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Backend\Tree\View\PageTreeView
|
||||
*/
|
||||
protected function getPageTreeView()
|
||||
{
|
||||
return $this->objectManager->get('TYPO3\\CMS\\Backend\\Tree\\View\\PageTreeView');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Metaseo\Metaseo\DependencyInjection\Utility\FrontendUtility
|
||||
*/
|
||||
protected function getFrontendUtility()
|
||||
{
|
||||
return $this
|
||||
->objectManager
|
||||
->get('Metaseo\\Metaseo\\DependencyInjection\\Utility\\FrontendUtility')
|
||||
->setPageRepository($this->getPageRepository());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Frontend\Page\PageRepository
|
||||
*/
|
||||
protected function getPageRepository()
|
||||
{
|
||||
return $this->objectManager->get('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of classes which contain Ajax controllers with <ajaxPrefix> => <className)
|
||||
*
|
||||
* @todo replace class concatenation with e.g. 'UrlController::class' as of PHP 5.5 (renders $namespace obsolete)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getBackendAjaxClassNames()
|
||||
{
|
||||
$nameSpace = __NAMESPACE__ . '\\PageSeo';
|
||||
$ajaxPrefix = self::AJAX_PREFIX;
|
||||
|
||||
return array(
|
||||
//$ajaxPrefix . PageSeo\AdvancedController::LIST_TYPE
|
||||
// => $nameSpace . '\\' . 'AdvancedController',//unused
|
||||
$ajaxPrefix . PageSeo\GeoController::LIST_TYPE => $nameSpace . '\\' . 'GeoController',
|
||||
$ajaxPrefix . PageSeo\MetaDataController::LIST_TYPE => $nameSpace . '\\' . 'MetaDataController',
|
||||
$ajaxPrefix . PageSeo\PageTitleController::LIST_TYPE => $nameSpace . '\\' . 'PageTitleController',
|
||||
$ajaxPrefix . PageSeo\PageTitleSimController::LIST_TYPE => $nameSpace . '\\' . 'PageTitleSimController',
|
||||
$ajaxPrefix . PageSeo\SearchEnginesController::LIST_TYPE => $nameSpace . '\\' . 'SearchEnginesController',
|
||||
$ajaxPrefix . PageSeo\UrlController::LIST_TYPE => $nameSpace . '\\' . 'UrlController',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax;
|
||||
|
||||
use TYPO3\CMS\Core\Http\AjaxRequestHandler;
|
||||
|
||||
abstract class AbstractPageSeoSimController extends AbstractPageSeoController implements PageSeoSimulateInterface
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function simulateAction($params = array(), AjaxRequestHandler &$ajaxObj = null)
|
||||
{
|
||||
try {
|
||||
$this->init();
|
||||
$ajaxObj->setContent($this->executeSimulate());
|
||||
} catch (\Exception $exception) {
|
||||
$this->ajaxExceptionHandler($exception, $ajaxObj);
|
||||
}
|
||||
|
||||
$ajaxObj->setContentFormat(self::CONTENT_FORMAT_JSON);
|
||||
$ajaxObj->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*
|
||||
* @throws \Metaseo\Metaseo\Exception\Ajax\AjaxException
|
||||
*/
|
||||
abstract protected function executeSimulate();
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax\PageSeo;
|
||||
|
||||
use Metaseo\Metaseo\Controller\Ajax\AbstractPageSeoController;
|
||||
use Metaseo\Metaseo\DependencyInjection\Utility\HttpUtility;
|
||||
use Metaseo\Metaseo\Exception\Ajax\AjaxException;
|
||||
use Metaseo\Metaseo\Utility\DatabaseUtility;
|
||||
|
||||
class AdvancedController extends AbstractPageSeoController
|
||||
{
|
||||
const LIST_TYPE = 'advanced';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function initFieldList()
|
||||
{
|
||||
$this->fieldList = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function executeIndex()
|
||||
{
|
||||
if (empty($this->postVar['pid'])) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.typo3_page_not_found',
|
||||
'[0x4FBF3C0E]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$ret = array();
|
||||
|
||||
$pid = (int)$this->postVar['pid'];
|
||||
$sysLanguage = (int)$this->postVar['sysLanguage'];
|
||||
|
||||
|
||||
// check uid of pages language overlay
|
||||
$query = 'SELECT tag_name,
|
||||
tag_value
|
||||
FROM tx_metaseo_metatag
|
||||
WHERE pid = ' . (int)$pid . '
|
||||
AND sys_language_uid = ' . (int)$sysLanguage;
|
||||
$rowList = DatabaseUtility::getAll($query);
|
||||
foreach ($rowList as $row) {
|
||||
$ret[$row['tag_name']] = $row['tag_value'];
|
||||
}
|
||||
|
||||
return array(
|
||||
'results' => count($ret),
|
||||
'rows' => array_values($ret),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function executeUpdate()
|
||||
{
|
||||
if (empty($this->postVar['pid']) || empty($this->postVar['metaTags'])) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.typo3_page_not_found',
|
||||
'[0x4FBF3C0F]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$pid = (int)$this->postVar['pid'];
|
||||
$metaTagList = (array)$this->postVar['metaTags'];
|
||||
$sysLanguage = (int)$this->postVar['sysLanguage'];
|
||||
|
||||
|
||||
$this->clearMetaTags($pid, $sysLanguage);
|
||||
$metaTagGroup = 2;
|
||||
foreach ($metaTagList as $metaTagName => $metaTagValue) {
|
||||
if (is_scalar($metaTagValue)) {
|
||||
$metaTagValue = trim($metaTagValue);
|
||||
|
||||
if (strlen($metaTagValue) > 0) {
|
||||
$this->updateMetaTag($pid, $sysLanguage, $metaTagName, $metaTagValue);
|
||||
}
|
||||
} elseif (is_array($metaTagValue)) {
|
||||
foreach ($metaTagValue as $subTagName => $subTagValue) {
|
||||
$this->updateMetaTag(
|
||||
$pid,
|
||||
$sysLanguage,
|
||||
array($metaTagName, $subTagName),
|
||||
$subTagValue,
|
||||
$metaTagGroup++
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all meta tags for one page
|
||||
*
|
||||
* @param integer $pid PID
|
||||
* @param integer|null $sysLanguage system language id
|
||||
*/
|
||||
protected function clearMetaTags($pid, $sysLanguage)
|
||||
{
|
||||
$query = 'DELETE FROM tx_metaseo_metatag
|
||||
WHERE pid = ' . (int)$pid . '
|
||||
AND sys_language_uid = ' . (int)$sysLanguage;
|
||||
DatabaseUtility::exec($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $pid PID
|
||||
* @param integer|NULL $sysLanguage System language id
|
||||
* @param string|array $metaTag MetaTag name
|
||||
* @param string $value MetaTag value
|
||||
* @param integer $tagGroup MetaTag group
|
||||
*/
|
||||
protected function updateMetaTag($pid, $sysLanguage, $metaTag, $value, $tagGroup = null)
|
||||
{
|
||||
$tstamp = time();
|
||||
$crdate = time();
|
||||
$cruserId = $this->getBackendUserAuthentication()->user['uid'];
|
||||
|
||||
$subTagName = '';
|
||||
|
||||
if (is_array($metaTag)) {
|
||||
list($metaTag, $subTagName) = $metaTag;
|
||||
}
|
||||
|
||||
if ($tagGroup === null) {
|
||||
$tagGroup = 1;
|
||||
}
|
||||
|
||||
$query = 'INSERT INTO tx_metaseo_metatag
|
||||
(pid, tstamp, crdate, cruser_id, sys_language_uid,
|
||||
tag_name, tag_subname, tag_value, tag_group)
|
||||
VALUES (
|
||||
' . (int)$pid . ',
|
||||
' . (int)$tstamp . ',
|
||||
' . (int)$crdate . ',
|
||||
' . (int)$cruserId . ',
|
||||
' . (int)$sysLanguage . ',
|
||||
' . DatabaseUtility::quote($metaTag) . ',
|
||||
' . DatabaseUtility::quote($subTagName) . ',
|
||||
' . DatabaseUtility::quote($value) . ',
|
||||
' . (int)$tagGroup . '
|
||||
) ON DUPLICATE KEY UPDATE
|
||||
tstamp = VALUES(tstamp),
|
||||
tag_value = VALUES(tag_value)';
|
||||
DatabaseUtility::execInsert($query);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax\PageSeo;
|
||||
|
||||
use Metaseo\Metaseo\Controller\Ajax\AbstractPageSeoController;
|
||||
|
||||
class GeoController extends AbstractPageSeoController
|
||||
{
|
||||
const LIST_TYPE = 'geo';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function initFieldList()
|
||||
{
|
||||
$this->fieldList = array(
|
||||
'tx_metaseo_geo_lat',
|
||||
'tx_metaseo_geo_long',
|
||||
'tx_metaseo_geo_place',
|
||||
'tx_metaseo_geo_region'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax\PageSeo;
|
||||
|
||||
use Metaseo\Metaseo\Controller\Ajax\AbstractPageSeoController;
|
||||
|
||||
class MetaDataController extends AbstractPageSeoController
|
||||
{
|
||||
const LIST_TYPE = 'metadata';
|
||||
|
||||
protected function initFieldList()
|
||||
{
|
||||
$this->fieldList = array(
|
||||
'keywords',
|
||||
'description',
|
||||
'abstract',
|
||||
'author',
|
||||
'author_email',
|
||||
'lastupdated',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getIndex(array $page, $depth, $sysLanguage)
|
||||
{
|
||||
$list = $this->getPageSeoDao()->index($page, $depth, $sysLanguage, $this->fieldList);
|
||||
|
||||
unset($row);
|
||||
foreach ($list as &$row) {
|
||||
if (!empty($row['lastupdated'])) {
|
||||
$row['lastupdated'] = date('Y-m-d', $row['lastupdated']);
|
||||
} else {
|
||||
$row['lastupdated'] = '';
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax\PageSeo;
|
||||
|
||||
use Metaseo\Metaseo\Controller\Ajax\AbstractPageSeoSimController;
|
||||
use Metaseo\Metaseo\DependencyInjection\Utility\HttpUtility;
|
||||
use Metaseo\Metaseo\Exception\Ajax\AjaxException;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
|
||||
class PageTitleController extends AbstractPageSeoSimController
|
||||
{
|
||||
const LIST_TYPE = 'pagetitle';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function initFieldList()
|
||||
{
|
||||
$this->fieldList = array(
|
||||
'tx_metaseo_pagetitle',
|
||||
'tx_metaseo_pagetitle_rel',
|
||||
'tx_metaseo_pagetitle_prefix',
|
||||
'tx_metaseo_pagetitle_suffix',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function executeSimulate()
|
||||
{
|
||||
$pid = (int)$this->postVar['pid'];
|
||||
|
||||
if (empty($pid)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.typo3_page_not_found',
|
||||
'[0x4FBF3C08]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$page = $this->getPageSeoDao()->getPageById($pid);
|
||||
|
||||
if (empty($page)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.typo3_page_not_found',
|
||||
'[0x4FBF3C09]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
// Load TYPO3 classes
|
||||
$this->getFrontendUtility()->initTsfe($page, null, $page, null);
|
||||
|
||||
$pagetitle = Typo3GeneralUtility::makeInstance(
|
||||
'Metaseo\\Metaseo\\Page\\Part\\PagetitlePart'
|
||||
);
|
||||
|
||||
return array(
|
||||
'title' => $pagetitle->main($page['title']),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax\PageSeo;
|
||||
|
||||
use Metaseo\Metaseo\Controller\Ajax\AbstractPageSeoController;
|
||||
|
||||
class PageTitleSimController extends AbstractPageSeoController
|
||||
{
|
||||
const LIST_TYPE = 'pagetitlesim';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function initFieldList()
|
||||
{
|
||||
$this->fieldList = array(
|
||||
'title',
|
||||
'tx_metaseo_pagetitle',
|
||||
'tx_metaseo_pagetitle_rel',
|
||||
'tx_metaseo_pagetitle_prefix',
|
||||
'tx_metaseo_pagetitle_suffix',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getIndex(array $page, $depth, $sysLanguage)
|
||||
{
|
||||
$list = $this->getPageSeoDao()->index($page, $depth, $sysLanguage, $this->fieldList);
|
||||
|
||||
$uidList = array_keys($list);
|
||||
|
||||
if (!empty($uidList)) {
|
||||
// Check which pages have templates (for caching and faster building)
|
||||
$this->templatePidList = array();
|
||||
|
||||
$pidList = $this->getTemplateDao()->checkForTemplateByUidList($uidList);
|
||||
foreach ($pidList as $pid) {
|
||||
$this->templatePidList[$pid] = $pid;
|
||||
}
|
||||
|
||||
// Build simulated title
|
||||
foreach ($list as &$row) {
|
||||
$row['title_simulated'] = $this->simulateTitle($row, $sysLanguage);
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate simulated page title
|
||||
*
|
||||
* @param array $page Page
|
||||
* @param integer $sysLanguage System language
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function simulateTitle(array $page, $sysLanguage)
|
||||
{
|
||||
$this->getFrontendUtility()->initTsfe($page, null, $page, null, $sysLanguage);
|
||||
|
||||
$pagetitle = $this->objectManager->get('Metaseo\\Metaseo\\Page\\Part\\PagetitlePart');
|
||||
$ret = $pagetitle->main($page['title']);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Metaseo\Metaseo\Dao\TemplateDao
|
||||
*/
|
||||
protected function getTemplateDao()
|
||||
{
|
||||
return $this->objectManager->get('Metaseo\\Metaseo\\Dao\\TemplateDao');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax\PageSeo;
|
||||
|
||||
use Metaseo\Metaseo\Controller\Ajax\AbstractPageSeoController;
|
||||
|
||||
class SearchEnginesController extends AbstractPageSeoController
|
||||
{
|
||||
const LIST_TYPE = 'searchengines';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function initFieldList()
|
||||
{
|
||||
$this->fieldList = array(
|
||||
'tx_metaseo_canonicalurl',
|
||||
'tx_metaseo_is_exclude',
|
||||
'tx_metaseo_priority',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax\PageSeo;
|
||||
|
||||
use Metaseo\Metaseo\Controller\Ajax\AbstractPageSeoSimController;
|
||||
use Metaseo\Metaseo\DependencyInjection\Utility\HttpUtility;
|
||||
use Metaseo\Metaseo\Exception\Ajax\AjaxException;
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
|
||||
class UrlController extends AbstractPageSeoSimController
|
||||
{
|
||||
const LIST_TYPE = 'url';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function initFieldList()
|
||||
{
|
||||
$this->fieldList = array(
|
||||
'title',
|
||||
'url_scheme',
|
||||
'alias',
|
||||
'tx_realurl_pathsegment',
|
||||
'tx_realurl_pathoverride',
|
||||
'tx_realurl_exclude',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function executeSimulate()
|
||||
{
|
||||
$pid = (int)$this->postVar['pid'];
|
||||
|
||||
if (empty($pid)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.typo3_page_not_found',
|
||||
'[0x4FBF3C0A]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$page = $this->getPageSeoDao()->getPageById($pid);
|
||||
|
||||
if (empty($page)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.typo3_page_not_found',
|
||||
'[0x4FBF3C0B]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
if (ExtensionManagementUtility::isLoaded('realurl')) {
|
||||
// Disable caching for url
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['_DEFAULT']['enableUrlDecodeCache'] = 0;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['_DEFAULT']['enableUrlEncodeCache'] = 0;
|
||||
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']['_DEFAULT']['disablePathCache'] = 1;
|
||||
}
|
||||
|
||||
$this->getFrontendUtility()->initTsfe($page, null, $page, null);
|
||||
|
||||
$ret = $this->getFrontendUtility()->getTypoLinkUrl(array('parameter' => $page['uid']));
|
||||
|
||||
if (!empty($ret)) {
|
||||
$ret = GeneralUtility::fullUrl($ret);
|
||||
}
|
||||
|
||||
if (empty($ret)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.url_generation_failed',
|
||||
'[0x4FBF3C01]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'url' => $ret,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax;
|
||||
|
||||
use TYPO3\CMS\Core\Http\AjaxRequestHandler;
|
||||
|
||||
interface PageSeoInterface
|
||||
{
|
||||
/**
|
||||
* Executes an AJAX request which displays the data (usually as a list)
|
||||
*
|
||||
* @param array $params Array of parameters from the AJAX interface, currently unused (as of 6.2.14)
|
||||
* becomes available starting with 7.4.0 (c048cede,
|
||||
* https://forge.typo3.org/issues/68186)
|
||||
* @param AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function indexAction($params = array(), AjaxRequestHandler &$ajaxObj = null);
|
||||
|
||||
/**
|
||||
* Executes an AJAX request which updates the data in the database
|
||||
*
|
||||
* @param array $params Array of parameters from the AJAX interface, currently unused (as of 6.2.14)
|
||||
* becomes available starting with 7.4.0 (c048cede,
|
||||
* https://forge.typo3.org/issues/68186)
|
||||
* @param AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateAction($params = array(), AjaxRequestHandler &$ajaxObj = null);
|
||||
|
||||
|
||||
/**
|
||||
* Executes an AJAX request which updates the data in the database recursively
|
||||
*
|
||||
* @param array $params Array of parameters from the AJAX interface, currently unused (as of 6.2.14)
|
||||
* becomes available starting with 7.4.0 (c048cede,
|
||||
* https://forge.typo3.org/issues/68186)
|
||||
* @param AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateRecursiveAction($params = array(), AjaxRequestHandler &$ajaxObj = null);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax;
|
||||
|
||||
use TYPO3\CMS\Core\Http\AjaxRequestHandler;
|
||||
|
||||
interface PageSeoSimulateInterface extends PageSeoInterface
|
||||
{
|
||||
/**
|
||||
* Executes an AJAX request which simulates field values
|
||||
*
|
||||
* @param array $params Array of parameters from the AJAX interface, currently unused (as of 6.2.14)
|
||||
* becomes available starting with 7.4.0 (c048cede,
|
||||
* https://forge.typo3.org/issues/68186)
|
||||
* @param AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function simulateAction($params = array(), AjaxRequestHandler &$ajaxObj = null);
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax;
|
||||
|
||||
use Exception;
|
||||
use Metaseo\Metaseo\Controller\AbstractAjaxController;
|
||||
use Metaseo\Metaseo\DependencyInjection\Utility\HttpUtility;
|
||||
use Metaseo\Metaseo\Exception\Ajax\AjaxException;
|
||||
use Metaseo\Metaseo\Utility\DatabaseUtility;
|
||||
use Metaseo\Metaseo\Utility\SitemapUtility;
|
||||
use TYPO3\CMS\Core\Http\AjaxRequestHandler;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend ajax module sitemap
|
||||
*/
|
||||
class SitemapController extends AbstractAjaxController implements SitemapInterface
|
||||
{
|
||||
const AJAX_PREFIX = 'tx_metaseo_controller_ajax_sitemap';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function indexAction($params = array(), AjaxRequestHandler &$ajaxObj = null)
|
||||
{
|
||||
try {
|
||||
$this->init();
|
||||
$ajaxObj->setContent($this->executeIndex());
|
||||
} catch (Exception $exception) {
|
||||
$this->ajaxExceptionHandler($exception, $ajaxObj);
|
||||
}
|
||||
|
||||
$ajaxObj->setContentFormat(self::CONTENT_FORMAT_JSON);
|
||||
$ajaxObj->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return sitemap entry list for root tree
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function executeIndex()
|
||||
{
|
||||
// Init
|
||||
$rootPid = (int)$this->postVar['pid'];
|
||||
$offset = (int)$this->postVar['start'];
|
||||
$itemsPerPage = (int)$this->postVar['pagingSize'];
|
||||
|
||||
$searchFulltext = trim((string)$this->postVar['criteriaFulltext']);
|
||||
$searchPageUid = trim((int)$this->postVar['criteriaPageUid']);
|
||||
$searchPageLanguage = trim((string)$this->postVar['criteriaPageLanguage']);
|
||||
$searchPageDepth = trim((string)$this->postVar['criteriaPageDepth']);
|
||||
$searchIsBlacklisted = (bool)trim((string)$this->postVar['criteriaIsBlacklisted']);
|
||||
|
||||
// ############################
|
||||
// Criteria
|
||||
// ############################
|
||||
$where = array();
|
||||
|
||||
// Root pid limit
|
||||
$where[] = 's.page_rootpid = ' . (int)$rootPid;
|
||||
|
||||
// Fulltext
|
||||
if (!empty($searchFulltext)) {
|
||||
$where[] = 's.page_url LIKE ' . DatabaseUtility::quote('%' . $searchFulltext . '%', 'tx_metaseo_sitemap');
|
||||
}
|
||||
|
||||
// Page id
|
||||
if (!empty($searchPageUid)) {
|
||||
$where[] = 's.page_uid = ' . (int)$searchPageUid;
|
||||
}
|
||||
|
||||
// Language
|
||||
if ($searchPageLanguage != -1 && strlen($searchPageLanguage) >= 1) {
|
||||
$where[] = 's.page_language = ' . (int)$searchPageLanguage;
|
||||
}
|
||||
|
||||
// Depth
|
||||
if ($searchPageDepth != -1 && strlen($searchPageDepth) >= 1) {
|
||||
$where[] = 's.page_depth = ' . (int)$searchPageDepth;
|
||||
}
|
||||
|
||||
if ($searchIsBlacklisted) {
|
||||
$where[] = 's.is_blacklisted = 1';
|
||||
}
|
||||
|
||||
// Filter blacklisted page types
|
||||
$where[] = DatabaseUtility::conditionNotIn(
|
||||
'p.doktype',
|
||||
SitemapUtility::getDoktypeBlacklist()
|
||||
);
|
||||
|
||||
// Build where
|
||||
$where = DatabaseUtility::buildCondition($where);
|
||||
|
||||
// ############################
|
||||
// Pager
|
||||
// ############################
|
||||
|
||||
// Fetch total count of items with this filter settings
|
||||
$query = 'SELECT COUNT(*) AS count
|
||||
FROM tx_metaseo_sitemap s
|
||||
INNER JOIN pages p ON p.uid = s.page_uid
|
||||
WHERE ' . $where;
|
||||
$itemCount = DatabaseUtility::getOne($query);
|
||||
|
||||
// ############################
|
||||
// Sort
|
||||
// ############################
|
||||
// default sort
|
||||
$sort = 's.page_depth ASC, s.page_uid ASC';
|
||||
|
||||
if (!empty($this->sortField) && !empty($this->sortDir)) {
|
||||
// already filtered
|
||||
$sort = $this->sortField . ' ' . $this->sortDir;
|
||||
}
|
||||
|
||||
// ############################
|
||||
// Fetch sitemap
|
||||
// ############################
|
||||
$query = 'SELECT s.uid,
|
||||
s.page_rootpid,
|
||||
s.page_uid,
|
||||
s.page_language,
|
||||
s.page_url,
|
||||
s.page_depth,
|
||||
s.page_type,
|
||||
s.is_blacklisted,
|
||||
p.tx_metaseo_is_exclude,
|
||||
FROM_UNIXTIME(s.tstamp) as tstamp,
|
||||
FROM_UNIXTIME(s.crdate) as crdate
|
||||
FROM tx_metaseo_sitemap s
|
||||
INNER JOIN pages p ON p.uid = s.page_uid
|
||||
WHERE ' . $where . '
|
||||
ORDER BY ' . $sort . '
|
||||
LIMIT ' . (int)$offset . ', ' . (int)$itemsPerPage;
|
||||
$list = DatabaseUtility::getAll($query);
|
||||
|
||||
return array(
|
||||
'results' => $itemCount,
|
||||
'rows' => $list,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function blacklistAction($params = array(), AjaxRequestHandler &$ajaxObj = null)
|
||||
{
|
||||
try {
|
||||
$this->init();
|
||||
$ajaxObj->setContent($this->executeBlacklist());
|
||||
} catch (Exception $exception) {
|
||||
$this->ajaxExceptionHandler($exception, $ajaxObj);
|
||||
}
|
||||
|
||||
$ajaxObj->setContentFormat(self::CONTENT_FORMAT_JSON);
|
||||
$ajaxObj->render();
|
||||
}
|
||||
|
||||
/*
|
||||
* Blacklist sitemap entries
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws AjaxException
|
||||
*/
|
||||
protected function executeBlacklist()
|
||||
{
|
||||
$uidList = $this->postVar['uidList'];
|
||||
$rootPid = (int)$this->postVar['pid'];
|
||||
|
||||
$uidList = DatabaseUtility::connection()->cleanIntArray($uidList);
|
||||
|
||||
if (empty($uidList) || empty($rootPid)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.warning.incomplete_data_received.message',
|
||||
'[0x4FBF3C10]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$where = array();
|
||||
$where[] = 'page_rootpid = ' . (int)$rootPid;
|
||||
$where[] = DatabaseUtility::conditionIn('uid', $uidList);
|
||||
$where = DatabaseUtility::buildCondition($where);
|
||||
|
||||
$query = 'UPDATE tx_metaseo_sitemap
|
||||
SET is_blacklisted = 1
|
||||
WHERE ' . $where;
|
||||
DatabaseUtility::exec($query);
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function whitelistAction($params = array(), AjaxRequestHandler &$ajaxObj = null)
|
||||
{
|
||||
try {
|
||||
$this->init();
|
||||
$ajaxObj->setContent($this->executeWhitelist());
|
||||
} catch (Exception $exception) {
|
||||
$this->ajaxExceptionHandler($exception, $ajaxObj);
|
||||
}
|
||||
|
||||
$ajaxObj->setContentFormat(self::CONTENT_FORMAT_JSON);
|
||||
$ajaxObj->render();
|
||||
}
|
||||
|
||||
/*
|
||||
* Whitelist sitemap entries
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws AjaxException
|
||||
*/
|
||||
protected function executeWhitelist()
|
||||
{
|
||||
$uidList = $this->postVar['uidList'];
|
||||
$rootPid = (int)$this->postVar['pid'];
|
||||
|
||||
$uidList = DatabaseUtility::connection()->cleanIntArray($uidList);
|
||||
|
||||
if (empty($uidList) || empty($rootPid)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.warning.incomplete_data_received.message',
|
||||
'[0x4FBF3C12]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$where = array();
|
||||
$where[] = 'page_rootpid = ' . (int)$rootPid;
|
||||
$where[] = DatabaseUtility::conditionIn('uid', $uidList);
|
||||
$where = DatabaseUtility::buildCondition($where);
|
||||
|
||||
$query = 'UPDATE tx_metaseo_sitemap
|
||||
SET is_blacklisted = 0
|
||||
WHERE ' . $where;
|
||||
DatabaseUtility::exec($query);
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function deleteAction($params = array(), AjaxRequestHandler &$ajaxObj = null)
|
||||
{
|
||||
try {
|
||||
$this->init();
|
||||
$ajaxObj->setContent($this->executeDelete());
|
||||
} catch (Exception $exception) {
|
||||
$this->ajaxExceptionHandler($exception, $ajaxObj);
|
||||
}
|
||||
|
||||
$ajaxObj->setContentFormat(self::CONTENT_FORMAT_JSON);
|
||||
$ajaxObj->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete sitemap entries
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws AjaxException
|
||||
*/
|
||||
protected function executeDelete()
|
||||
{
|
||||
$uidList = $this->postVar['uidList'];
|
||||
$rootPid = (int)$this->postVar['pid'];
|
||||
|
||||
$uidList = DatabaseUtility::connection()->cleanIntArray($uidList);
|
||||
|
||||
if (empty($uidList) || empty($rootPid)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.warning.incomplete_data_received.message',
|
||||
'[0x4FBF3C11]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$where = array();
|
||||
$where[] = 'page_rootpid = ' . (int)$rootPid;
|
||||
$where[] = DatabaseUtility::conditionIn('uid', $uidList);
|
||||
$where = DatabaseUtility::buildCondition($where);
|
||||
|
||||
$query = 'DELETE FROM tx_metaseo_sitemap
|
||||
WHERE ' . $where;
|
||||
DatabaseUtility::exec($query);
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function deleteAllAction($params = array(), AjaxRequestHandler &$ajaxObj = null)
|
||||
{
|
||||
try {
|
||||
$this->init();
|
||||
$ajaxObj->setContent($this->executeDeleteAll());
|
||||
} catch (Exception $exception) {
|
||||
$this->ajaxExceptionHandler($exception, $ajaxObj);
|
||||
}
|
||||
|
||||
$ajaxObj->setContentFormat(self::CONTENT_FORMAT_JSON);
|
||||
$ajaxObj->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all sitemap entries
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws AjaxException
|
||||
*/
|
||||
protected function executeDeleteAll()
|
||||
{
|
||||
$rootPid = (int)$this->postVar['pid'];
|
||||
|
||||
if (empty($rootPid)) {
|
||||
|
||||
throw new AjaxException(
|
||||
'message.warning.incomplete_data_received.message',
|
||||
'[0x4FBF3C12]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
$where = array();
|
||||
$where[] = 'page_rootpid = ' . (int)$rootPid;
|
||||
$where = DatabaseUtility::buildCondition($where);
|
||||
|
||||
$query = 'DELETE FROM tx_metaseo_sitemap
|
||||
WHERE ' . $where;
|
||||
DatabaseUtility::exec($query);
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getAjaxPrefix()
|
||||
{
|
||||
return self::AJAX_PREFIX;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns array of classes which contain Ajax controllers with <ajaxPrefix> => <className)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getBackendAjaxClassNames()
|
||||
{
|
||||
return array(
|
||||
self::AJAX_PREFIX => __CLASS__,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller\Ajax;
|
||||
|
||||
use TYPO3\CMS\Core\Http\AjaxRequestHandler;
|
||||
|
||||
interface SitemapInterface
|
||||
{
|
||||
/**
|
||||
* Executes an AJAX request which displays the data (usually as a list)
|
||||
*
|
||||
* @param array $params Array of parameters from the AJAX interface, currently unused (as of 6.2.14)
|
||||
* becomes available starting with 7.4.0 (c048cede,
|
||||
* https://forge.typo3.org/issues/68186)
|
||||
* @param AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function indexAction($params = array(), AjaxRequestHandler &$ajaxObj = null);
|
||||
|
||||
/**
|
||||
* Blacklists a sitemap entry so that it does not appear in the sitemap presented to search engines
|
||||
*
|
||||
* @param array $params Array of parameters from the AJAX interface, currently unused (as of 6.2.14)
|
||||
* becomes available starting with 7.4.0 (c048cede,
|
||||
* https://forge.typo3.org/issues/68186)
|
||||
* @param AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function blacklistAction($params = array(), AjaxRequestHandler &$ajaxObj = null);
|
||||
|
||||
/**
|
||||
* Undoes the blacklist operation
|
||||
*
|
||||
* @param array $params Array of parameters from the AJAX interface, currently unused (as of 6.2.14)
|
||||
* becomes available starting with 7.4.0 (c048cede,
|
||||
* https://forge.typo3.org/issues/68186)
|
||||
* @param AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function whitelistAction($params = array(), AjaxRequestHandler &$ajaxObj = null);
|
||||
|
||||
/**
|
||||
* Deletes an entry from the sitemap. Entry will reappear as soon as it's indexed again
|
||||
*
|
||||
* @param array $params Array of parameters from the AJAX interface, currently unused (as of 6.2.14)
|
||||
* becomes available starting with 7.4.0 (c048cede,
|
||||
* https://forge.typo3.org/issues/68186)
|
||||
* @param AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteAction($params = array(), AjaxRequestHandler &$ajaxObj = null);
|
||||
|
||||
/**
|
||||
* Performs delete operation for all the entries in the sitemap
|
||||
*
|
||||
* @param array $params Array of parameters from the AJAX interface, currently unused (as of 6.2.14)
|
||||
* becomes available starting with 7.4.0 (c048cede,
|
||||
* https://forge.typo3.org/issues/68186)
|
||||
* @param AjaxRequestHandler $ajaxObj Object of type AjaxRequestHandler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deleteAllAction($params = array(), AjaxRequestHandler &$ajaxObj = null);
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller;
|
||||
|
||||
use Metaseo\Metaseo\Backend\Module\AbstractStandardModule;
|
||||
use Metaseo\Metaseo\Utility\BackendUtility;
|
||||
use Metaseo\Metaseo\Utility\DatabaseUtility;
|
||||
use Metaseo\Metaseo\Utility\RootPageUtility;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility as Typo3BackendUtility;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend module root settings
|
||||
*/
|
||||
class BackendControlCenterController extends AbstractStandardModule
|
||||
{
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Main action
|
||||
*/
|
||||
public function mainAction()
|
||||
{
|
||||
// #################
|
||||
// Root page list
|
||||
// #################
|
||||
|
||||
$rootPageList = BackendUtility::getRootPageList();
|
||||
$rootIdList = array_keys($rootPageList);
|
||||
|
||||
$rootPidCondition = null;
|
||||
if (!empty($rootIdList)) {
|
||||
$rootPidCondition = 'p.uid IN (' . implode(',', $rootIdList) . ')';
|
||||
} else {
|
||||
$rootPidCondition = '1=0';
|
||||
}
|
||||
|
||||
// #################
|
||||
// Root setting list (w/ automatic creation)
|
||||
// #################
|
||||
|
||||
// check which root pages have no root settings
|
||||
$query = 'SELECT p.uid
|
||||
FROM pages p
|
||||
LEFT JOIN tx_metaseo_setting_root seosr
|
||||
ON seosr.pid = p.uid
|
||||
AND seosr.deleted = 0
|
||||
WHERE ' . $rootPidCondition . '
|
||||
AND seosr.uid IS NULL';
|
||||
$rowList = DatabaseUtility::getAll($query);
|
||||
foreach ($rowList as $row) {
|
||||
$tmpUid = $row['uid'];
|
||||
$query = 'INSERT INTO tx_metaseo_setting_root (pid, tstamp, crdate, cruser_id)
|
||||
VALUES (' . (int)$tmpUid . ',
|
||||
' . (int)time() . ',
|
||||
' . (int)time() . ',
|
||||
' . (int)$GLOBALS['BE_USER']->user['uid'] . ')';
|
||||
DatabaseUtility::execInsert($query);
|
||||
}
|
||||
|
||||
$rootSettingList = BackendUtility::getRootPageSettingList();
|
||||
|
||||
// #################
|
||||
// Domain list
|
||||
// ##################
|
||||
|
||||
// Fetch domain name
|
||||
$query = 'SELECT uid,
|
||||
pid,
|
||||
domainName,
|
||||
forced
|
||||
FROM sys_domain
|
||||
WHERE hidden = 0
|
||||
ORDER BY forced DESC,
|
||||
sorting';
|
||||
$rowList = DatabaseUtility::getAll($query);
|
||||
|
||||
$domainList = array();
|
||||
foreach ($rowList as $row) {
|
||||
$domainList[$row['pid']][$row['uid']] = $row;
|
||||
}
|
||||
|
||||
// #################
|
||||
// Build root page list
|
||||
// #################
|
||||
|
||||
unset($page);
|
||||
foreach ($rootPageList as $pageId => &$page) {
|
||||
// Domain list
|
||||
$page['domainList'] = '';
|
||||
if (!empty($domainList[$pageId])) {
|
||||
$page['domainList'] = $domainList[$pageId];
|
||||
}
|
||||
|
||||
// Settings
|
||||
$page['rootSettings'] = array();
|
||||
if (!empty($rootSettingList[$pageId])) {
|
||||
$page['rootSettings'] = $rootSettingList[$pageId];
|
||||
}
|
||||
|
||||
// Settings available
|
||||
$page['settingsLink'] = Typo3BackendUtility::editOnClick(
|
||||
'&edit[tx_metaseo_setting_root][' . $rootSettingList[$pageId]['uid'] . ']=edit'
|
||||
);
|
||||
|
||||
$page['sitemapLink'] = RootPageUtility::getSitemapIndexUrl($pageId);
|
||||
$page['robotsTxtLink'] = RootPageUtility::getRobotsTxtUrl($pageId);
|
||||
}
|
||||
unset($page);
|
||||
|
||||
// check if there is any root page
|
||||
if (empty($rootPageList)) {
|
||||
$this->addFlashMessage(
|
||||
$this->translate('message.warning.noRootPage.message'),
|
||||
$this->translate('message.warning.noRootPage.title'),
|
||||
FlashMessage::WARNING
|
||||
);
|
||||
}
|
||||
|
||||
$this->view->assign('RootPageList', $rootPageList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller;
|
||||
|
||||
use Metaseo\Metaseo\Backend\Module\AbstractStandardModule;
|
||||
use Metaseo\Metaseo\Controller\Ajax\AbstractPageSeoController;
|
||||
use Metaseo\Metaseo\Controller\Ajax\PageSeo\GeoController;
|
||||
use Metaseo\Metaseo\Controller\Ajax\PageSeo\MetaDataController;
|
||||
use Metaseo\Metaseo\Controller\Ajax\PageSeo\PageTitleController;
|
||||
use Metaseo\Metaseo\Controller\Ajax\PageSeo\PageTitleSimController;
|
||||
use Metaseo\Metaseo\Controller\Ajax\PageSeo\SearchEnginesController;
|
||||
use Metaseo\Metaseo\Controller\Ajax\PageSeo\UrlController;
|
||||
use Metaseo\Metaseo\Utility\DatabaseUtility;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Backend\Utility\IconUtility;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend module page seo
|
||||
*/
|
||||
class BackendPageSeoController extends AbstractStandardModule
|
||||
{
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Main action
|
||||
*/
|
||||
public function mainAction()
|
||||
{
|
||||
$this->handleSubAction(MetaDataController::LIST_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Geo action
|
||||
*/
|
||||
public function geoAction()
|
||||
{
|
||||
$this->handleSubAction(GeoController::LIST_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* searchengines action
|
||||
*/
|
||||
public function searchenginesAction()
|
||||
{
|
||||
$this->handleSubAction(SearchEnginesController::LIST_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* url action
|
||||
*/
|
||||
public function urlAction()
|
||||
{
|
||||
$this->handleSubAction(UrlController::LIST_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* pagetitle action
|
||||
*/
|
||||
public function pagetitleAction()
|
||||
{
|
||||
$this->handleSubAction(PageTitleController::LIST_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* pagetitlesim action
|
||||
*/
|
||||
public function pagetitlesimAction()
|
||||
{
|
||||
$this->handleSubAction(PageTitleSimController::LIST_TYPE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $listType
|
||||
*/
|
||||
protected function handleSubAction($listType)
|
||||
{
|
||||
$pageId = (int) GeneralUtility::_GP('id');
|
||||
|
||||
if (empty($pageId)) {
|
||||
$this->addFlashMessage(
|
||||
$this->translate('message.warning.no_valid_page.message'),
|
||||
$this->translate('message.warning.no_valid_page.title'),
|
||||
FlashMessage::WARNING
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Load PageTS
|
||||
$pageTsConf = BackendUtility::getPagesTSconfig($pageId);
|
||||
|
||||
// Build language list
|
||||
$defaultLanguageText = $this->translate('default.language');
|
||||
|
||||
$languageFullList = array(
|
||||
0 => array(
|
||||
'label' => $this->translate('default.language'),
|
||||
'flag' => '',
|
||||
),
|
||||
);
|
||||
|
||||
if (!empty($pageTsConf['mod.']['SHARED.']['defaultLanguageFlag'])) {
|
||||
$languageFullList[0]['flag'] = $pageTsConf['mod.']['SHARED.']['defaultLanguageFlag'];
|
||||
}
|
||||
|
||||
if (!empty($pageTsConf['mod.']['SHARED.']['defaultLanguageLabel'])) {
|
||||
$label = $pageTsConf['mod.']['SHARED.']['defaultLanguageLabel'];
|
||||
|
||||
$languageFullList[0]['label'] = $this->translate('default.language.named', array($label));
|
||||
|
||||
$defaultLanguageText = $pageTsConf['mod.']['SHARED.']['defaultLanguageLabel'];
|
||||
}
|
||||
|
||||
// Fetch other flags
|
||||
$query = 'SELECT uid,
|
||||
title,
|
||||
flag
|
||||
FROM sys_language
|
||||
WHERE hidden = 0';
|
||||
$rowList = DatabaseUtility::getAll($query);
|
||||
foreach ($rowList as $row) {
|
||||
$languageFullList[$row['uid']] = array(
|
||||
'label' => htmlspecialchars($row['title']),
|
||||
'flag' => htmlspecialchars($row['flag']),
|
||||
);
|
||||
}
|
||||
|
||||
// Languages
|
||||
$languageList = array();
|
||||
|
||||
foreach ($languageFullList as $langId => $langRow) {
|
||||
$flag = '';
|
||||
|
||||
// Flag (if available)
|
||||
if (!empty($langRow['flag'])) {
|
||||
$flag .= '<span class="t3-icon t3-icon-flags t3-icon-flags-' . $langRow['flag']
|
||||
. ' t3-icon-' . $langRow['flag'] . '"></span>';
|
||||
$flag .= ' ';
|
||||
}
|
||||
|
||||
// label
|
||||
$label = $langRow['label'];
|
||||
|
||||
$languageList[] = array(
|
||||
$langId,
|
||||
$label,
|
||||
$flag
|
||||
);
|
||||
}
|
||||
|
||||
$sysLanguageDefault = (int)$GLOBALS['BE_USER']->getSessionData('MetaSEO.sysLanguage');
|
||||
|
||||
if (empty($sysLanguageDefault)) {
|
||||
$sysLanguageDefault = 0;
|
||||
}
|
||||
|
||||
// ############################
|
||||
// HTML
|
||||
// ############################
|
||||
|
||||
$realUrlAvailable = ExtensionManagementUtility::isLoaded('realurl');
|
||||
|
||||
$ajaxController = AbstractPageSeoController::AJAX_PREFIX . $listType;
|
||||
|
||||
if (!array_key_exists($ajaxController, AbstractPageSeoController::getBackendAjaxClassNames())) {
|
||||
throw new \RuntimeException('Ajax controller with this name was not registered by MetaSEO.');
|
||||
}
|
||||
|
||||
$metaSeoConf = array(
|
||||
'ajaxController' => $ajaxController,
|
||||
'pid' => (int)$pageId,
|
||||
'renderTo' => 'tx-metaseo-sitemap-grid',
|
||||
'pagingSize' => 50,
|
||||
'depth' => 2,
|
||||
'sortField' => 'crdate',
|
||||
'sortDir' => 'DESC',
|
||||
'filterIcon' => IconUtility::getSpriteIcon(
|
||||
'actions-system-tree-search-open'
|
||||
),
|
||||
'dataLanguage' => $languageList,
|
||||
'sysLanguage' => $sysLanguageDefault,
|
||||
'listType' => $listType,
|
||||
'criteriaFulltext' => '',
|
||||
'realurlAvailable' => $realUrlAvailable,
|
||||
'sprite' => array(
|
||||
'edit' => IconUtility::getSpriteIcon('actions-document-open'),
|
||||
'info' => IconUtility::getSpriteIcon('actions-document-info'),
|
||||
'editor' => IconUtility::getSpriteIcon('actions-system-options-view'),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
$metaSeoLang = array(
|
||||
'pagingMessage' => 'pager.results',
|
||||
'pagingEmpty' => 'pager.noresults',
|
||||
'boolean_yes' => 'boolean.yes',
|
||||
'boolean_no' => 'boolean.no',
|
||||
'button_save' => 'button.save',
|
||||
'button_saverecursively' => 'button.saverecursively',
|
||||
'button_saverecursively_tooltip' => 'button.saverecursively.tooltip',
|
||||
'button_cancel' => 'button.cancel',
|
||||
'labelDepth' => 'label.depth',
|
||||
'labelSearchFulltext' => 'label.search.fulltext',
|
||||
'emptySearchFulltext' => 'empty.search.fulltext',
|
||||
'labelSearchPageLanguage' => 'label.search.page_language',
|
||||
'emptySearchPageLanguage' => '',
|
||||
'page_uid' => 'header.sitemap.page_uid',
|
||||
'page_title' => 'header.sitemap.page_title',
|
||||
'page_keywords' => 'header.sitemap.page_keywords',
|
||||
'page_description' => 'header.sitemap.page_description',
|
||||
'page_abstract' => 'header.sitemap.page_abstract',
|
||||
'page_author' => 'header.sitemap.page_author',
|
||||
'page_author_email' => 'header.sitemap.page_author_email',
|
||||
'page_lastupdated' => 'header.sitemap.page_lastupdated',
|
||||
'page_geo_lat' => 'header.sitemap.page_geo_lat',
|
||||
'page_geo_long' => 'header.sitemap.page_geo_long',
|
||||
'page_geo_place' => 'header.sitemap.page_geo_place',
|
||||
'page_geo_region' => 'header.sitemap.page_geo_region',
|
||||
'page_tx_metaseo_pagetitle' => 'header.sitemap.page_tx_metaseo_pagetitle',
|
||||
'page_tx_metaseo_pagetitle_rel' => 'header.sitemap.page_tx_metaseo_pagetitle_rel',
|
||||
'page_tx_metaseo_pagetitle_prefix' => 'header.sitemap.page_tx_metaseo_pagetitle_prefix',
|
||||
'page_tx_metaseo_pagetitle_suffix' => 'header.sitemap.page_tx_metaseo_pagetitle_suffix',
|
||||
'page_title_simulated' => 'header.pagetitlesim.title_simulated',
|
||||
'page_searchengine_canonicalurl' => 'header.searchengine_canonicalurl',
|
||||
'page_searchengine_is_exclude' => 'header.searchengine_is_excluded',
|
||||
'searchengine_is_exclude_disabled' => 'searchengine.is_exclude_disabled',
|
||||
'searchengine_is_exclude_enabled' => 'searchengine.is_exclude_enabled',
|
||||
'page_sitemap_priority' => 'header.sitemap.priority',
|
||||
'page_url_scheme' => 'header.url_scheme',
|
||||
'page_url_scheme_default' => 'page.url_scheme_default',
|
||||
'page_url_scheme_http' => 'page.url_scheme_http',
|
||||
'page_url_scheme_https' => 'page.url_scheme_https',
|
||||
'page_url_alias' => 'header.url_alias',
|
||||
'page_url_realurl_pathsegment' => 'header.url_realurl_pathsegment',
|
||||
'page_url_realurl_pathoverride' => 'header.url_realurl_pathoverride',
|
||||
'page_url_realurl_exclude' => 'header.url_realurl_exclude',
|
||||
'qtip_pagetitle_simulate' => 'qtip.pagetitle_simulate',
|
||||
'qtip_url_simulate' => 'qtip.url_simulate',
|
||||
'metaeditor_title' => 'metaeditor.title',
|
||||
'metaeditor_tab_opengraph' => 'metaeditor.tab.opengraph',
|
||||
'metaeditor_button_hin' => 'metaeditor.button.hint',
|
||||
'value_from_base' => 'value.from_base',
|
||||
'value_from_overlay' => 'value.from_overlay',
|
||||
'value_only_base' => 'value.only_base',
|
||||
'value_default' => 'value_default',
|
||||
);
|
||||
|
||||
// translate list
|
||||
$metaSeoLang = $this->translateList($metaSeoLang);
|
||||
$metaSeoLang['emptySearchPageLanguage'] = $defaultLanguageText;
|
||||
|
||||
$this->view->assign(
|
||||
'JavaScript',
|
||||
'Ext.namespace("MetaSeo.overview");
|
||||
MetaSeo.overview.conf = ' . json_encode($metaSeoConf) . ';
|
||||
MetaSeo.overview.conf.lang = ' . json_encode($metaSeoLang) . ';
|
||||
'
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller;
|
||||
|
||||
use Metaseo\Metaseo\Backend\Module\AbstractStandardModule;
|
||||
use Metaseo\Metaseo\Utility\BackendUtility;
|
||||
use Metaseo\Metaseo\Utility\DatabaseUtility;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility as Typo3BackendUtility;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend module root settings
|
||||
*/
|
||||
class BackendRootSettingsController extends AbstractStandardModule
|
||||
{
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Main action
|
||||
*/
|
||||
public function mainAction()
|
||||
{
|
||||
// #################
|
||||
// Root page list
|
||||
// #################
|
||||
|
||||
$rootPageList = BackendUtility::getRootPageList();
|
||||
$rootIdList = array_keys($rootPageList);
|
||||
|
||||
$rootPidCondition = null;
|
||||
if (!empty($rootIdList)) {
|
||||
$rootPidCondition = 'p.uid IN (' . implode(',', $rootIdList) . ')';
|
||||
} else {
|
||||
$rootPidCondition = '1=0';
|
||||
}
|
||||
|
||||
// #################
|
||||
// Root setting list (w/ automatic creation)
|
||||
// #################
|
||||
|
||||
// check which root pages have no root settings
|
||||
$query = 'SELECT p.uid
|
||||
FROM pages p
|
||||
LEFT JOIN tx_metaseo_setting_root seosr
|
||||
ON seosr.pid = p.uid
|
||||
AND seosr.deleted = 0
|
||||
WHERE ' . $rootPidCondition . '
|
||||
AND seosr.uid IS NULL';
|
||||
$uidList = DatabaseUtility::getCol($query);
|
||||
foreach ($uidList as $tmpUid) {
|
||||
$query = 'INSERT INTO tx_metaseo_setting_root (pid, tstamp, crdate, cruser_id)
|
||||
VALUES (' . (int)$tmpUid . ',
|
||||
' . (int)time() . ',
|
||||
' . (int)time() . ',
|
||||
' . (int)$GLOBALS['BE_USER']->user['uid'] . ')';
|
||||
DatabaseUtility::execInsert($query);
|
||||
}
|
||||
|
||||
$rootSettingList = BackendUtility::getRootPageSettingList();
|
||||
|
||||
// #################
|
||||
// Domain list
|
||||
// ##################
|
||||
|
||||
// Fetch domain name
|
||||
$query = 'SELECT uid,
|
||||
pid,
|
||||
domainName,
|
||||
forced
|
||||
FROM sys_domain
|
||||
WHERE hidden = 0
|
||||
ORDER BY forced DESC,
|
||||
sorting';
|
||||
$rowList = DatabaseUtility::getAll($query);
|
||||
|
||||
$domainList = array();
|
||||
foreach ($rowList as $row) {
|
||||
$domainList[$row['pid']][$row['uid']] = $row;
|
||||
}
|
||||
|
||||
// #################
|
||||
// Build root page list
|
||||
// #################
|
||||
|
||||
unset($page);
|
||||
foreach ($rootPageList as $pageId => &$page) {
|
||||
// Domain list
|
||||
$page['domainList'] = '';
|
||||
if (!empty($domainList[$pageId])) {
|
||||
$page['domainList'] = $domainList[$pageId];
|
||||
}
|
||||
|
||||
// Settings
|
||||
$page['rootSettings'] = array();
|
||||
if (!empty($rootSettingList[$pageId])) {
|
||||
$page['rootSettings'] = $rootSettingList[$pageId];
|
||||
}
|
||||
|
||||
// Settings available
|
||||
$page['settingsLink'] = Typo3BackendUtility::editOnClick(
|
||||
'&edit[tx_metaseo_setting_root][' . $rootSettingList[$pageId]['uid'] . ']=edit'
|
||||
);
|
||||
}
|
||||
unset($page);
|
||||
|
||||
// check if there is any root page
|
||||
if (empty($rootPageList)) {
|
||||
$this->addFlashMessage(
|
||||
$this->translate('message.warning.noRootPage.message'),
|
||||
$this->translate('message.warning.noRootPage.title'),
|
||||
FlashMessage::WARNING
|
||||
);
|
||||
}
|
||||
|
||||
$this->view->assign('RootPageList', $rootPageList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Controller;
|
||||
|
||||
use Metaseo\Metaseo\Backend\Module\AbstractStandardModule;
|
||||
use Metaseo\Metaseo\Controller\Ajax\SitemapController;
|
||||
use Metaseo\Metaseo\Utility\BackendUtility;
|
||||
use Metaseo\Metaseo\Utility\DatabaseUtility;
|
||||
use Metaseo\Metaseo\Utility\SitemapUtility;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility as Typo3BackendUtility;
|
||||
use TYPO3\CMS\Backend\Utility\IconUtility;
|
||||
use TYPO3\CMS\Core\Messaging\FlashMessage;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* TYPO3 Backend module sitemap
|
||||
*/
|
||||
class BackendSitemapController extends AbstractStandardModule
|
||||
{
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Main action
|
||||
*/
|
||||
public function mainAction()
|
||||
{
|
||||
// Init
|
||||
$rootPageList = BackendUtility::getRootPageList();
|
||||
$rootSettingList = BackendUtility::getRootPageSettingList();
|
||||
|
||||
// ############################
|
||||
// Fetch
|
||||
// ############################
|
||||
|
||||
// Get statistics
|
||||
$query = 'SELECT s.page_rootpid,
|
||||
COUNT(*) AS sum_total,
|
||||
COUNT(s.page_uid) AS sum_pages
|
||||
FROM tx_metaseo_sitemap s
|
||||
INNER JOIN pages p
|
||||
ON p.uid = s.page_uid
|
||||
AND p.deleted = 0
|
||||
AND ' . DatabaseUtility::conditionNotIn(
|
||||
'p.doktype',
|
||||
SitemapUtility::getDoktypeBlacklist()
|
||||
) . '
|
||||
GROUP BY page_rootpid';
|
||||
$statsList = DatabaseUtility::getAllWithIndex($query, 'page_rootpid');
|
||||
|
||||
// Fetch domain name
|
||||
$query = 'SELECT uid,
|
||||
pid,
|
||||
domainName,
|
||||
forced
|
||||
FROM sys_domain
|
||||
WHERE hidden = 0
|
||||
ORDER BY forced DESC,
|
||||
sorting';
|
||||
$rowList = DatabaseUtility::getAll($query);
|
||||
|
||||
$domainList = array();
|
||||
foreach ($rowList as $row) {
|
||||
$pid = $row['pid'];
|
||||
|
||||
if (!empty($row['forced'])) {
|
||||
$domainList[$pid] = $row['domainName'];
|
||||
} elseif (empty($domainList[$pid])) {
|
||||
$domainList[$pid] = $row['domainName'];
|
||||
}
|
||||
}
|
||||
|
||||
// #################
|
||||
// Build root page list
|
||||
// #################
|
||||
|
||||
|
||||
unset($page);
|
||||
foreach ($rootPageList as $pageId => &$page) {
|
||||
$stats = array(
|
||||
'sum_pages' => 0,
|
||||
'sum_total' => 0,
|
||||
'sum_xml_pages' => 0,
|
||||
);
|
||||
|
||||
// Setting row
|
||||
$settingRow = array();
|
||||
if (!empty($rootSettingList[$pageId])) {
|
||||
$settingRow = $rootSettingList[$pageId];
|
||||
}
|
||||
|
||||
|
||||
// Calc stats
|
||||
if (!empty($statsList[$pageId])) {
|
||||
foreach ($statsList[$pageId] as $statsKey => $statsValue) {
|
||||
$stats[$statsKey] = $statsValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$joinWhere = DatabaseUtility::conditionNotIn(
|
||||
'p.doktype',
|
||||
SitemapUtility::getDoktypeBlacklist()
|
||||
);
|
||||
|
||||
// Root statistics
|
||||
$query = 'SELECT COUNT(s.page_uid)
|
||||
FROM tx_metaseo_sitemap s
|
||||
INNER JOIN pages p
|
||||
ON p.uid = s.page_uid
|
||||
AND ' . $joinWhere . '
|
||||
WHERE s.page_rootpid = ' . (int)$pageId;
|
||||
$stats['sum_pages'] = DatabaseUtility::getOne($query);
|
||||
|
||||
$pagesPerXmlSitemap = 1000;
|
||||
if (!empty($settingRow['sitemap_page_limit'])) {
|
||||
$pagesPerXmlSitemap = $settingRow['sitemap_page_limit'];
|
||||
}
|
||||
$sumXmlPages = ceil($stats['sum_total'] / $pagesPerXmlSitemap);
|
||||
$stats['sum_xml_pages'] = sprintf($this->translate('sitemap.xml.pages.total'), $sumXmlPages);
|
||||
|
||||
|
||||
$page['stats'] = $stats;
|
||||
}
|
||||
unset($page);
|
||||
|
||||
// check if there is any root page
|
||||
if (empty($rootPageList)) {
|
||||
$this->addFlashMessage(
|
||||
$this->translate('message.warning.noRootPage.message'),
|
||||
$this->translate('message.warning.noRootPage.title'),
|
||||
FlashMessage::WARNING
|
||||
);
|
||||
}
|
||||
|
||||
$this->view->assign('RootPageList', $rootPageList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sitemap action
|
||||
*/
|
||||
public function sitemapAction()
|
||||
{
|
||||
$params = GeneralUtility::_GP('tx_metaseo_metaseometaseo_metaseositemap');
|
||||
$rootPid = $params['pageId'];
|
||||
|
||||
if (empty($rootPid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rootPageList = BackendUtility::getRootPageList();
|
||||
$rootPage = $rootPageList[$rootPid];
|
||||
|
||||
// ###############################
|
||||
// Fetch
|
||||
// ###############################
|
||||
$pageTsConf = Typo3BackendUtility::getPagesTSconfig($rootPid);
|
||||
|
||||
$languageFullList = array(
|
||||
0 => array(
|
||||
'label' => $this->translate('default.language'),
|
||||
'flag' => '',
|
||||
),
|
||||
);
|
||||
|
||||
if (!empty($pageTsConf['mod.']['SHARED.']['defaultLanguageFlag'])) {
|
||||
$languageFullList[0]['flag'] = $pageTsConf['mod.']['SHARED.']['defaultLanguageFlag'];
|
||||
}
|
||||
|
||||
if (!empty($pageTsConf['mod.']['SHARED.']['defaultLanguageLabel'])) {
|
||||
$languageFullList[0]['label'] = $pageTsConf['mod.']['SHARED.']['defaultLanguageLabel'];
|
||||
}
|
||||
|
||||
// Fetch domain name
|
||||
$query = 'SELECT uid,
|
||||
title,
|
||||
flag
|
||||
FROM sys_language
|
||||
WHERE hidden = 0';
|
||||
$rowList = DatabaseUtility::getAll($query);
|
||||
|
||||
foreach ($rowList as $row) {
|
||||
$languageFullList[$row['uid']] = array(
|
||||
'label' => htmlspecialchars($row['title']),
|
||||
'flag' => htmlspecialchars($row['flag']),
|
||||
);
|
||||
}
|
||||
|
||||
// Languages
|
||||
$languageList = array();
|
||||
$languageList[] = array(
|
||||
-1,
|
||||
$this->translate('empty.search.page_language'),
|
||||
);
|
||||
|
||||
foreach ($languageFullList as $langId => $langRow) {
|
||||
$flag = '';
|
||||
|
||||
// Flag (if available)
|
||||
if (!empty($langRow['flag'])) {
|
||||
$flag .= '<span class="t3-icon t3-icon-flags t3-icon-flags-' . $langRow['flag']
|
||||
. ' t3-icon-' . $langRow['flag'] . '"></span>';
|
||||
$flag .= ' ';
|
||||
}
|
||||
|
||||
// label
|
||||
$label = $langRow['label'];
|
||||
|
||||
$languageList[] = array(
|
||||
$langId,
|
||||
$label,
|
||||
$flag
|
||||
);
|
||||
}
|
||||
|
||||
// Depth
|
||||
$depthList = array();
|
||||
$depthList[] = array(
|
||||
-1,
|
||||
$this->translate('empty.search.page_depth'),
|
||||
);
|
||||
|
||||
$query = 'SELECT DISTINCT page_depth
|
||||
FROM tx_metaseo_sitemap
|
||||
WHERE page_rootpid = ' . (int)$rootPid;
|
||||
foreach (DatabaseUtility::getCol($query) as $depth) {
|
||||
$depthList[] = array(
|
||||
$depth,
|
||||
$depth,
|
||||
);
|
||||
}
|
||||
|
||||
// ###############################
|
||||
// Page/JS
|
||||
// ###############################
|
||||
|
||||
$metaSeoConf = array(
|
||||
'ajaxController' => SitemapController::AJAX_PREFIX,
|
||||
'pid' => (int)$rootPid,
|
||||
'renderTo' => 'tx-metaseo-sitemap-grid',
|
||||
'pagingSize' => 50,
|
||||
'sortField' => 'crdate',
|
||||
'sortDir' => 'DESC',
|
||||
'filterIcon' => IconUtility::getSpriteIcon(
|
||||
'actions-system-tree-search-open'
|
||||
),
|
||||
'dataLanguage' => $languageList,
|
||||
'dataDepth' => $depthList,
|
||||
'criteriaFulltext' => '',
|
||||
'criteriaPageUid' => '',
|
||||
'criteriaPageLanguage' => '',
|
||||
'criteriaPageDepth' => '',
|
||||
'criteriaIsBlacklisted' => 0,
|
||||
'languageFullList' => $languageFullList,
|
||||
);
|
||||
|
||||
$metaSeoLang = array(
|
||||
'title' => 'title.sitemap.list',
|
||||
'pagingMessage' => 'pager.results',
|
||||
'pagingEmpty' => 'pager.noresults',
|
||||
'sitemap_page_uid' => 'header.sitemap.page_uid',
|
||||
'sitemap_page_url' => 'header.sitemap.page_url',
|
||||
'sitemap_page_type' => 'header.sitemap.page_type',
|
||||
'sitemap_page_depth' => 'header.sitemap.page_depth',
|
||||
'sitemap_page_language' => 'header.sitemap.page_language',
|
||||
'sitemap_page_is_blacklisted' => 'header.sitemap.page_is_blacklisted',
|
||||
'page_tx_metaseo_is_exclude' => 'header.sitemap.page_tx_metaseo_is_exclude',
|
||||
'sitemap_tstamp' => 'header.sitemap.tstamp',
|
||||
'sitemap_crdate' => 'header.sitemap.crdate',
|
||||
'labelSearchFulltext' => 'label.search.fulltext',
|
||||
'emptySearchFulltext' => 'empty.search.fulltext',
|
||||
'labelSearchPageUid' => 'label.search.page_uid',
|
||||
'emptySearchPageUid' => 'empty.search.page_uid',
|
||||
'labelSearchPageLanguage' => 'label.search.page_language',
|
||||
'emptySearchPageLanguage' => 'empty.search.page_language',
|
||||
'labelSearchPageDepth' => 'label.search.page_depth',
|
||||
'emptySearchPageDepth' => 'empty.search.page_depth',
|
||||
'labelSearchIsBlacklisted' => 'label.search.is_blacklisted',
|
||||
'labelYes' => 'label.yes',
|
||||
'labelNo' => 'label.no',
|
||||
'buttonYes' => 'button.yes',
|
||||
'buttonNo' => 'button.no',
|
||||
'buttonDelete' => 'button.delete',
|
||||
'buttonDeleteHint' => 'button.delete.hint',
|
||||
'buttonBlacklist' => 'button.blacklist',
|
||||
'buttonBlacklistHint' => 'button.blacklist.hint',
|
||||
'buttonWhitelist' => 'button.whitelist',
|
||||
'buttonWhitelistHint' => 'button.whitelist.hint',
|
||||
'buttonDeleteAll' => 'button.delete_all',
|
||||
'messageDeleteTitle' => 'message.delete.title',
|
||||
'messageDeleteQuestion' => 'message.delete.question',
|
||||
'messageDeleteAllTitle' => 'message.delete_all.title',
|
||||
'messageDeleteAllQuestion' => 'message.delete_all.question',
|
||||
'messageBlacklistTitle' => 'message.blacklist.title',
|
||||
'messageBlacklistQuestion' => 'message.blacklist.question',
|
||||
'messageWhitelistTitle' => 'message.whitelist.title',
|
||||
'messageWhitelistQuestion' => 'message.whitelist.question',
|
||||
'errorDeleteFailedMessage' => 'message.delete.failed_body',
|
||||
'errorNoSelectedItemsBody' => 'message.no_selected_items',
|
||||
'today' => 'today',
|
||||
'yesterday' => 'yesterday',
|
||||
'sitemapPageType' => array(
|
||||
0 => 'sitemap.pagetype.0',
|
||||
1 => 'sitemap.pagetype.1',
|
||||
),
|
||||
);
|
||||
|
||||
// translate list
|
||||
$metaSeoLang = $this->translateList($metaSeoLang);
|
||||
$metaSeoLang['title'] = sprintf($metaSeoLang['title'], $rootPage['title'], $rootPid);
|
||||
|
||||
$this->view->assign(
|
||||
'JavaScript',
|
||||
'Ext.namespace("MetaSeo.sitemap");
|
||||
MetaSeo.sitemap.conf = ' . json_encode($metaSeoConf) . ';
|
||||
MetaSeo.sitemap.conf.lang = ' . json_encode($metaSeoLang) . ';
|
||||
'
|
||||
);
|
||||
}
|
||||
}
|
||||
85
typo3conf/ext/metaseo/Classes/Dao/Dao.php
Normal file
85
typo3conf/ext/metaseo/Classes/Dao/Dao.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Dao;
|
||||
|
||||
use TYPO3\CMS\Core\DataHandling\DataHandler;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
|
||||
class Dao implements SingletonInterface
|
||||
{
|
||||
/**
|
||||
* DataHandler (TCE)
|
||||
*
|
||||
* @var \TYPO3\CMS\Core\DataHandling\DataHandler
|
||||
*/
|
||||
protected $dataHandler;
|
||||
|
||||
/**
|
||||
* Check if field is in table (TCA)
|
||||
*
|
||||
* @param string $table Table
|
||||
* @param string $field Field
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function isFieldInTcaTable($table, $field)
|
||||
{
|
||||
return isset($GLOBALS['TCA'][$table]['columns'][$field]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return (cached) instance of t3lib_TCEmain
|
||||
*
|
||||
* @return \TYPO3\CMS\Core\DataHandling\DataHandler
|
||||
*/
|
||||
protected function getDataHandler()
|
||||
{
|
||||
$this->dataHandler->start(null, null);
|
||||
|
||||
return $this->dataHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
|
||||
*/
|
||||
protected function getBackendUserAuthentication()
|
||||
{
|
||||
return $GLOBALS['BE_USER'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DataHandler $dataHandler
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDataHandler(DataHandler $dataHandler)
|
||||
{
|
||||
$this->dataHandler = $dataHandler;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
327
typo3conf/ext/metaseo/Classes/Dao/PageSeoDao.php
Normal file
327
typo3conf/ext/metaseo/Classes/Dao/PageSeoDao.php
Normal file
@@ -0,0 +1,327 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Dao;
|
||||
|
||||
use Metaseo\Metaseo\DependencyInjection\Utility\HttpUtility;
|
||||
use Metaseo\Metaseo\Exception\Ajax\AjaxException;
|
||||
use Metaseo\Metaseo\Utility\DatabaseUtility;
|
||||
use TYPO3\CMS\Backend\Tree\View\PageTreeView;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
|
||||
class PageSeoDao extends Dao
|
||||
{
|
||||
/**
|
||||
* @var PageTreeView
|
||||
*/
|
||||
protected $pageTreeView;
|
||||
|
||||
/**
|
||||
* Return default tree
|
||||
*
|
||||
* @param array $page Root page
|
||||
* @param integer $depth Depth
|
||||
* @param integer $sysLanguage System language
|
||||
* @param array $fieldList Field list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function index(array $page, $depth, $sysLanguage, $fieldList = array())
|
||||
{
|
||||
$rootPid = $page['uid'];
|
||||
|
||||
$list = array();
|
||||
|
||||
$fieldList[] = 'pid';
|
||||
$pageIdList = array();
|
||||
|
||||
// ###########################
|
||||
// Build tree
|
||||
// ############################
|
||||
|
||||
// Init tree
|
||||
/** @var \TYPO3\CMS\Backend\Tree\View\PageTreeView $tree */
|
||||
$tree = $this->pageTreeView;
|
||||
foreach ($fieldList as $field) {
|
||||
$tree->addField($field, true);
|
||||
}
|
||||
$tree->init(
|
||||
'AND doktype IN (1,4) AND ' . $this->getBackendUserAuthentication()->getPagePermsClause(1)
|
||||
);
|
||||
|
||||
$tree->tree[] = array(
|
||||
'row' => $page,
|
||||
'invertedDepth' => 0,
|
||||
);
|
||||
|
||||
$tree->getTree($rootPid, $depth, '');
|
||||
|
||||
// Build tree list
|
||||
foreach ($tree->tree as $row) {
|
||||
$tmp = $row['row'];
|
||||
$list[$tmp['uid']] = $tmp;
|
||||
|
||||
$pageIdList[$tmp['uid']] = $tmp['uid'];
|
||||
}
|
||||
|
||||
// Calc depth
|
||||
$rootLineRaw = array();
|
||||
foreach ($list as $row) {
|
||||
$rootLineRaw[$row['uid']] = $row['pid'];
|
||||
}
|
||||
|
||||
$rootLineRaw[$rootPid] = null;
|
||||
|
||||
// overlay status "current"
|
||||
$defaultOverlayStatus = 0;
|
||||
if (!empty($sysLanguage)) {
|
||||
// overlay status "only available from base"
|
||||
$defaultOverlayStatus = 2;
|
||||
}
|
||||
|
||||
unset($row);
|
||||
foreach ($list as &$row) {
|
||||
// Set field as main fields
|
||||
foreach ($fieldList as $fieldName) {
|
||||
$row['_overlay'][$fieldName] = $defaultOverlayStatus;
|
||||
$row['_base'][$fieldName] = $row[$fieldName];
|
||||
}
|
||||
|
||||
$row['_depth'] = $this->listCalcDepth($row['uid'], $rootLineRaw);
|
||||
}
|
||||
unset($row);
|
||||
|
||||
// ############################
|
||||
// Language overlay
|
||||
// ############################
|
||||
|
||||
if (!empty($sysLanguage) && !empty($pageIdList)) {
|
||||
// Fetch all overlay rows for current page list
|
||||
$overlayFieldList = array();
|
||||
foreach ($fieldList as $fieldName) {
|
||||
if ($this->isFieldInTcaTable('pages_language_overlay', $fieldName)) {
|
||||
$overlayFieldList[$fieldName] = $fieldName;
|
||||
}
|
||||
}
|
||||
|
||||
// Build list of fields which we need to query
|
||||
$queryFieldList = array(
|
||||
'uid',
|
||||
'pid',
|
||||
'title',
|
||||
);
|
||||
$queryFieldList = array_merge($queryFieldList, $overlayFieldList);
|
||||
|
||||
$res = DatabaseUtility::connection()->exec_SELECTquery(
|
||||
implode(',', $queryFieldList),
|
||||
'pages_language_overlay',
|
||||
'pid IN(' . implode(',', $pageIdList) . ') AND sys_language_uid = ' . (int)$sysLanguage
|
||||
);
|
||||
|
||||
// update all overlay status field to "from base"
|
||||
unset($row);
|
||||
foreach ($list as &$row) {
|
||||
foreach ($overlayFieldList as $fieldName) {
|
||||
$row['_overlay'][$fieldName] = 0;
|
||||
}
|
||||
}
|
||||
unset($row);
|
||||
|
||||
while ($overlayRow = DatabaseUtility::connection()->sql_fetch_assoc($res)) {
|
||||
$pageOriginalId = $overlayRow['pid'];
|
||||
|
||||
// Don't use uid and pid
|
||||
unset($overlayRow['uid'], $overlayRow['pid']);
|
||||
|
||||
// inject title
|
||||
$fieldName = 'title';
|
||||
if (!empty($overlayRow[$fieldName])) {
|
||||
$list[$pageOriginalId][$fieldName] = $overlayRow[$fieldName];
|
||||
}
|
||||
|
||||
// inject all other fields
|
||||
foreach ($fieldList as $fieldName) {
|
||||
if (!empty($overlayRow[$fieldName])) {
|
||||
$list[$pageOriginalId][$fieldName] = $overlayRow[$fieldName];
|
||||
|
||||
// update overlay status field to "from overlay"
|
||||
$list[$pageOriginalId]['_overlay'][$fieldName] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the depth of a page
|
||||
*
|
||||
* @param integer $pageUid Page UID
|
||||
* @param array $rootLineRaw Root line (raw list)
|
||||
* @param integer $depth Current depth
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
protected function listCalcDepth($pageUid, array $rootLineRaw, $depth = null)
|
||||
{
|
||||
if ($depth === null) {
|
||||
$depth = 1;
|
||||
}
|
||||
|
||||
if (empty($rootLineRaw[$pageUid])) {
|
||||
// found root page
|
||||
return $depth;
|
||||
}
|
||||
|
||||
// we must be at least in the first depth
|
||||
++$depth;
|
||||
|
||||
$pagePid = $rootLineRaw[$pageUid];
|
||||
|
||||
if (!empty($pagePid)) {
|
||||
// recursive
|
||||
$depth = $this->listCalcDepth($pagePid, $rootLineRaw, $depth);
|
||||
}
|
||||
|
||||
return $depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update field in page table
|
||||
*
|
||||
* @param integer $pid PID
|
||||
* @param integer|NULL $sysLanguage System language id
|
||||
* @param string $fieldName Field name
|
||||
* @param string $fieldValue Field value
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws AjaxException
|
||||
*/
|
||||
public function updatePageTableField($pid, $sysLanguage, $fieldName, $fieldValue)
|
||||
{
|
||||
$tableName = 'pages';
|
||||
|
||||
if (!empty($sysLanguage)) {
|
||||
// check if field is in overlay
|
||||
if ($this->isFieldInTcaTable('pages_language_overlay', $fieldName)) {
|
||||
// Field is in pages language overlay
|
||||
$tableName = 'pages_language_overlay';
|
||||
}
|
||||
}
|
||||
|
||||
switch ($tableName) {
|
||||
case 'pages_language_overlay':
|
||||
// Update field in pages overlay (also logs update event and clear cache for this page)
|
||||
|
||||
// check uid of pages language overlay
|
||||
$query = 'SELECT uid
|
||||
FROM pages_language_overlay
|
||||
WHERE pid = ' . (int)$pid . '
|
||||
AND sys_language_uid = ' . (int)$sysLanguage;
|
||||
$overlayId = DatabaseUtility::getOne($query);
|
||||
|
||||
if (empty($overlayId)) {
|
||||
// No access
|
||||
|
||||
throw new AjaxException(
|
||||
'message.error.no_language_overlay_found',
|
||||
'[0x4FBF3C05]',
|
||||
HttpUtility::HTTP_STATUS_BAD_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
// ################
|
||||
// UPDATE
|
||||
// ################
|
||||
|
||||
$this->getDataHandler()->updateDB(
|
||||
'pages_language_overlay',
|
||||
(int)$overlayId,
|
||||
array(
|
||||
$fieldName => $fieldValue
|
||||
)
|
||||
);
|
||||
break;
|
||||
case 'pages':
|
||||
// Update field in page (also logs update event and clear cache for this page)
|
||||
$this->getDataHandler()->updateDB(
|
||||
'pages',
|
||||
(int)$pid,
|
||||
array(
|
||||
$fieldName => $fieldValue
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $pid
|
||||
*
|
||||
* @return array|NULL
|
||||
*/
|
||||
public function getPageById($pid)
|
||||
{
|
||||
return $this->getRecord('pages', $pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets record with uid = $uid from $table
|
||||
* You can set $field to a list of fields (default is '*')
|
||||
* Additional WHERE clauses can be added by $where (fx. ' AND blabla = 1')
|
||||
* Will automatically check if records has been deleted and if so, not return anything.
|
||||
* $table must be found in $GLOBALS['TCA']
|
||||
*
|
||||
* @param string $table Table name present in $GLOBALS['TCA']
|
||||
* @param int $uid UID of record
|
||||
* @param string $fields List of fields to select
|
||||
* @param string $where Additional WHERE clause, eg. " AND blablabla = 0
|
||||
* @param bool $useDeleteClause Use the deleteClause to check if a record is deleted (default TRUE)
|
||||
*
|
||||
* @return array|NULL Returns the row if found, otherwise NULL
|
||||
*/
|
||||
protected function getRecord($table, $uid, $fields = '*', $where = '', $useDeleteClause = true)
|
||||
{
|
||||
return BackendUtility::getRecord($table, $uid, $fields, $where, $useDeleteClause);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $pageTreeView
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPageTreeView($pageTreeView)
|
||||
{
|
||||
$this->pageTreeView = $pageTreeView;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
48
typo3conf/ext/metaseo/Classes/Dao/TemplateDao.php
Normal file
48
typo3conf/ext/metaseo/Classes/Dao/TemplateDao.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Dao;
|
||||
|
||||
use Metaseo\Metaseo\Utility\DatabaseUtility;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
|
||||
class TemplateDao implements SingletonInterface
|
||||
{
|
||||
/**
|
||||
* @param integer[] array of page IDs to be checked for templates
|
||||
*
|
||||
* @return array of PIDs which have a template which is not deleted or hidden.
|
||||
*/
|
||||
public function checkForTemplateByUidList($uidList)
|
||||
{
|
||||
$query = 'SELECT pid
|
||||
FROM sys_template
|
||||
WHERE pid IN (' . implode(',', $uidList) . ')
|
||||
AND deleted = 0
|
||||
AND hidden = 0';
|
||||
return DatabaseUtility::getCol($query);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\DependencyInjection\Utility;
|
||||
|
||||
use Metaseo\Metaseo\Utility\FrontendUtility as MetaseoFrontendUtility;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
use TYPO3\CMS\Frontend\Page\PageRepository;
|
||||
|
||||
class FrontendUtility implements SingletonInterface
|
||||
{
|
||||
/**
|
||||
* @var PageRepository
|
||||
*/
|
||||
protected $pageRepository;
|
||||
|
||||
/**
|
||||
* Init TSFE (for simulated pagetitle)
|
||||
*
|
||||
* @param array $page Page
|
||||
* @param null|array $rootLine Rootline
|
||||
* @param null|array $pageData Page data (recursive generated)
|
||||
* @param null|array $rootlineFull Rootline full
|
||||
* @param null|integer $sysLanguage System language
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initTsfe(
|
||||
array $page,
|
||||
array $rootLine = null,
|
||||
array $pageData = null,
|
||||
array $rootlineFull = null,
|
||||
$sysLanguage = null
|
||||
) {
|
||||
$pageUid = (int)$page['uid'];
|
||||
|
||||
if ($rootLine === null) {
|
||||
$rootLine = $this->pageRepository->getRootLine($pageUid);
|
||||
|
||||
// save full rootline, we need it in TSFE
|
||||
$rootlineFull = $rootLine;
|
||||
}
|
||||
|
||||
// check if current page has a ts-setup-template
|
||||
// if not, we go down the tree to the parent page
|
||||
if (count($rootLine) >= 2 && !empty($this->templatePidList) && empty($this->templatePidList[$pageUid])) {
|
||||
// go to parent page in rootline
|
||||
reset($rootLine);
|
||||
next($rootLine);
|
||||
$prevPage = current($rootLine);
|
||||
|
||||
// strip current page from rootline
|
||||
reset($rootLine);
|
||||
$currPageIndex = key($rootLine);
|
||||
unset($rootLine[$currPageIndex]);
|
||||
|
||||
MetaseoFrontendUtility::init(
|
||||
$prevPage['uid'],
|
||||
$rootLine,
|
||||
$pageData,
|
||||
$rootlineFull,
|
||||
$sysLanguage
|
||||
);
|
||||
}
|
||||
|
||||
MetaseoFrontendUtility::init($page['uid'], $rootLine, $pageData, $rootlineFull, $sysLanguage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $conf
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTypoLinkUrl(array $conf)
|
||||
{
|
||||
return $this->getTSFE()->cObj->typolink_URL($conf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
|
||||
*/
|
||||
protected function getTSFE()
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param PageRepository $pageRepository
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPageRepository(PageRepository $pageRepository)
|
||||
{
|
||||
$this->pageRepository = $pageRepository;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\DependencyInjection\Utility;
|
||||
|
||||
use Exception;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
|
||||
class HttpUtility implements SingletonInterface
|
||||
{
|
||||
/**
|
||||
* Http Status Codes for Ajax
|
||||
*
|
||||
* @link https://dev.twitter.com/overview/api/response-codes
|
||||
*/
|
||||
const HTTP_STATUS_OK = 200;
|
||||
const HTTP_STATUS_BAD_REQUEST = 400;
|
||||
const HTTP_STATUS_UNAUTHORIZED = 401;
|
||||
const HTTP_STATUS_FORBIDDEN = 403;
|
||||
const HTTP_STATUS_NOT_FOUND = 404;
|
||||
const HTTP_STATUS_NOT_ACCEPTABLE = 406;
|
||||
const HTTP_STATUS_INTERNAL_SERVER_ERROR = 500;
|
||||
const HTTP_STATUS_SERVICE_UNAVAILABLE = 503;
|
||||
|
||||
/**
|
||||
* @param $httpStatusCode
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getHttpStatusMessage($httpStatusCode)
|
||||
{
|
||||
switch ($httpStatusCode) {
|
||||
case self::HTTP_STATUS_OK:
|
||||
return 'OK';
|
||||
case self::HTTP_STATUS_BAD_REQUEST:
|
||||
return 'Bad Request';
|
||||
case self::HTTP_STATUS_UNAUTHORIZED:
|
||||
return 'Unauthorized';
|
||||
case self::HTTP_STATUS_FORBIDDEN:
|
||||
return 'Forbidden';
|
||||
case self::HTTP_STATUS_NOT_FOUND:
|
||||
return 'Not Found';
|
||||
case self::HTTP_STATUS_NOT_ACCEPTABLE:
|
||||
return 'Not Acceptable';
|
||||
case self::HTTP_STATUS_INTERNAL_SERVER_ERROR:
|
||||
return 'Internal Server Error';
|
||||
case self::HTTP_STATUS_SERVICE_UNAVAILABLE:
|
||||
return 'Service Unavailable';
|
||||
default:
|
||||
throw new Exception('Http status message is not available.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $httpStatusCode
|
||||
*/
|
||||
public function sendHttpHeader($httpStatusCode)
|
||||
{
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.0 ' . $httpStatusCode . ' ' . $this->getHttpStatusMessage($httpStatusCode));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Exception\Ajax;
|
||||
|
||||
use Exception;
|
||||
|
||||
class AjaxException extends Exception
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $message;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $code;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $httpStatus;
|
||||
|
||||
/**
|
||||
* @param string $messageTranslationKey The error message translation KEY
|
||||
* @param string $code Custom alphanumeric error code
|
||||
* @param int $httpStatus http status code, e.g. 500 for internal server error.
|
||||
*/
|
||||
public function __construct($messageTranslationKey = '', $code = '', $httpStatus = 500)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->message = (string) $messageTranslationKey;
|
||||
$this->code = (string) $code;
|
||||
$this->httpStatus = (int) $httpStatus;
|
||||
}
|
||||
|
||||
public function getHttpStatus()
|
||||
{
|
||||
return $this->httpStatus;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Hook\Extension;
|
||||
|
||||
/**
|
||||
* EXT:news hook for metatags
|
||||
*/
|
||||
class NewsExtension
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Hook\Extension;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\Plugin\AbstractPlugin;
|
||||
|
||||
/**
|
||||
* EXT:tt_news hook for metatags
|
||||
*/
|
||||
class TtnewsExtension
|
||||
{
|
||||
|
||||
/**
|
||||
* Extra item marker hook for metatag fetching
|
||||
*
|
||||
* @param array $markerArray Marker array
|
||||
* @param array $row Current tt_news row
|
||||
* @param array $lConf Local configuration
|
||||
* @param AbstractPlugin $ttnewsObj Pi-object from tt_news
|
||||
*
|
||||
* @return array Marker array (not changed)
|
||||
*/
|
||||
public function extraItemMarkerProcessor(array $markerArray, array $row, array $lConf, AbstractPlugin $ttnewsObj)
|
||||
{
|
||||
$theCode = (string)strtoupper(trim($ttnewsObj->theCode));
|
||||
|
||||
$connector = GeneralUtility::makeInstance('Metaseo\\Metaseo\\Connector');
|
||||
|
||||
switch ($theCode) {
|
||||
case 'SINGLE':
|
||||
case 'SINGLE2':
|
||||
// Title
|
||||
if (!empty($row['title'])) {
|
||||
$connector->setMetaTag('title', $row['title']);
|
||||
}
|
||||
|
||||
// Description
|
||||
if (!empty($row['short'])) {
|
||||
$connector->setMetaTag('description', $row['short']);
|
||||
}
|
||||
|
||||
// Keywords
|
||||
if (!empty($row['keywords'])) {
|
||||
$connector->setMetaTag('keywords', $row['keywords']);
|
||||
}
|
||||
|
||||
// Short/Description
|
||||
if (!empty($row['short'])) {
|
||||
$connector->setMetaTag('description', $row['short']);
|
||||
}
|
||||
|
||||
// Author
|
||||
if (!empty($row['author'])) {
|
||||
$connector->setMetaTag('author', $row['author']);
|
||||
}
|
||||
|
||||
// E-Mail
|
||||
if (!empty($row['author_email'])) {
|
||||
$connector->setMetaTag('email', $row['author_email']);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $markerArray;
|
||||
}
|
||||
}
|
||||
128
typo3conf/ext/metaseo/Classes/Hook/HttpHook.php
Normal file
128
typo3conf/ext/metaseo/Classes/Hook/HttpHook.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Hook;
|
||||
|
||||
use Metaseo\Metaseo\Utility\FrontendUtility;
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Http Header generator
|
||||
*/
|
||||
class HttpHook
|
||||
{
|
||||
|
||||
/**
|
||||
* Add HTTP Headers
|
||||
*/
|
||||
public function main()
|
||||
{
|
||||
// INIT
|
||||
$tsSetup = $GLOBALS['TSFE']->tmpl->setup;
|
||||
$headers = array();
|
||||
|
||||
// don't send any headers if headers are already sent
|
||||
if (headers_sent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Init caches
|
||||
$cacheIdentification = sprintf(
|
||||
'%s_%s_http',
|
||||
$GLOBALS['TSFE']->id,
|
||||
substr(sha1(FrontendUtility::getCurrentUrl()), 10, 30)
|
||||
);
|
||||
|
||||
/** @var \TYPO3\CMS\Core\Cache\CacheManager $cacheManager */
|
||||
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Extbase\\Object\\ObjectManager'
|
||||
);
|
||||
$cacheManager = $objectManager->get('TYPO3\\CMS\\Core\\Cache\\CacheManager');
|
||||
$cache = $cacheManager->getCache('cache_pagesection');
|
||||
|
||||
if (!empty($GLOBALS['TSFE']->tmpl->loaded)) {
|
||||
// ##################################
|
||||
// Non-Cached page
|
||||
// ##################################
|
||||
|
||||
if (!empty($tsSetup['plugin.']['metaseo.']['metaTags.'])) {
|
||||
$tsSetupSeo = $tsSetup['plugin.']['metaseo.']['metaTags.'];
|
||||
|
||||
// ##################################
|
||||
// W3C P3P Tags
|
||||
// ##################################
|
||||
$p3pCP = null;
|
||||
$p3pPolicyUrl = null;
|
||||
|
||||
if (!empty($tsSetupSeo['p3pCP'])) {
|
||||
$p3pCP = $tsSetupSeo['p3pCP'];
|
||||
}
|
||||
|
||||
if (!empty($tsSetupSeo['p3pPolicyUrl'])) {
|
||||
$p3pPolicyUrl = $tsSetupSeo['p3pPolicyUrl'];
|
||||
}
|
||||
|
||||
if (!empty($p3pCP) || !empty($p3pPolicyUrl)) {
|
||||
$p3pHeader = array();
|
||||
|
||||
if (!empty($p3pCP)) {
|
||||
$p3pHeader[] = 'CP="' . $p3pCP . '"';
|
||||
}
|
||||
|
||||
if (!empty($p3pPolicyUrl)) {
|
||||
$p3pHeader[] = 'policyref="' . $p3pPolicyUrl . '"';
|
||||
}
|
||||
|
||||
$headers['P3P'] = implode(' ', $p3pHeader);
|
||||
}
|
||||
}
|
||||
|
||||
// Store headers into cache
|
||||
$cache->set($cacheIdentification, $headers, array('pageId_' . $GLOBALS['TSFE']->id));
|
||||
} else {
|
||||
// #####################################
|
||||
// Cached page
|
||||
// #####################################
|
||||
|
||||
// Fetched cached headers
|
||||
$cachedHeaders = $cache->get($cacheIdentification);
|
||||
|
||||
if (!empty($cachedHeaders)) {
|
||||
$headers = $cachedHeaders;
|
||||
}
|
||||
}
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'httpHeaderOutput', $this, $headers);
|
||||
|
||||
// #####################################
|
||||
// Sender headers
|
||||
// #####################################
|
||||
if (!empty($headers['P3P'])) {
|
||||
header('P3P: ' . $headers['P3P']);
|
||||
}
|
||||
}
|
||||
}
|
||||
290
typo3conf/ext/metaseo/Classes/Hook/SitemapIndexHook.php
Normal file
290
typo3conf/ext/metaseo/Classes/Hook/SitemapIndexHook.php
Normal file
@@ -0,0 +1,290 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Hook;
|
||||
|
||||
use Metaseo\Metaseo\Utility\FrontendUtility;
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
use Metaseo\Metaseo\Utility\SitemapUtility;
|
||||
use TYPO3\CMS\Core\SingletonInterface;
|
||||
|
||||
/**
|
||||
* Sitemap Indexer
|
||||
*/
|
||||
abstract class SitemapIndexHook implements SingletonInterface
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* List of blacklisted page doktypes
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $doktypeBlacklist = array();
|
||||
|
||||
/**
|
||||
* List of blacklisted page types (Setup PAGE object typeNum)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $pageTypeBlacklist = array();
|
||||
|
||||
/**
|
||||
* Page index status
|
||||
*
|
||||
* @var null|boolean
|
||||
*/
|
||||
protected $pageIndexFlag;
|
||||
|
||||
/**
|
||||
* MetaSEO configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $conf = array();
|
||||
|
||||
/**
|
||||
* Blacklist configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $blacklistConf = array();
|
||||
|
||||
/**
|
||||
* File extension list
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fileExtList = array();
|
||||
|
||||
/**
|
||||
* Sitemap entry expiration
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $indexExpiration;
|
||||
|
||||
|
||||
/**
|
||||
* Object manager
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManager
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
/** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */
|
||||
$this->objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Extbase\\Object\\ObjectManager'
|
||||
);
|
||||
|
||||
$this->initConfiguration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init configuration
|
||||
*/
|
||||
protected function initConfiguration()
|
||||
{
|
||||
// Get configuration
|
||||
if (!empty($GLOBALS['TSFE']->tmpl->setup['plugin.']['metaseo.'])) {
|
||||
$this->conf = $GLOBALS['TSFE']->tmpl->setup['plugin.']['metaseo.'];
|
||||
}
|
||||
|
||||
// Store blacklist configuration
|
||||
if (!empty($this->conf['sitemap.']['index.']['blacklist.'])) {
|
||||
$this->blacklistConf = $this->conf['sitemap.']['index.']['blacklist.'];
|
||||
}
|
||||
|
||||
// Store blacklist configuration
|
||||
if (!empty($this->conf['sitemap.']['index.']['fileExtension.'])) {
|
||||
# File extensions can be a comma separated list
|
||||
foreach ($this->conf['sitemap.']['index.']['fileExtension.'] as $fileExtListRaw) {
|
||||
$fileExtList = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $fileExtListRaw);
|
||||
$this->fileExtList = array_merge($this->fileExtList, $fileExtList);
|
||||
};
|
||||
}
|
||||
|
||||
// Get expiration
|
||||
$expirationInDays = 60;
|
||||
if (!empty($this->conf['sitemap.']['expiration'])) {
|
||||
$expirationInDays = abs($this->conf['sitemap.']['expiration']);
|
||||
}
|
||||
|
||||
$this->indexExpiration = $_SERVER['REQUEST_TIME'] + ($expirationInDays * 24 * 60 * 60);
|
||||
|
||||
// Init blacklist for doktype (from table pages)
|
||||
$this->doktypeBlacklist = SitemapUtility::getDoktypeBlacklist();
|
||||
|
||||
// Init blacklist for PAGE typenum
|
||||
$this->pageTypeBlacklist = SitemapUtility::getPageTypeBlacklist();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process/Clear link url
|
||||
*
|
||||
* @param string $linkUrl Link url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function processLinkUrl($linkUrl)
|
||||
{
|
||||
static $absRefPrefix = null;
|
||||
static $absRefPrefixLength = 0;
|
||||
$ret = $linkUrl;
|
||||
|
||||
// Fetch abs ref prefix if available/set
|
||||
if ($absRefPrefix === null) {
|
||||
if (!empty($GLOBALS['TSFE']->tmpl->setup['config.']['absRefPrefix'])) {
|
||||
$absRefPrefix = $GLOBALS['TSFE']->tmpl->setup['config.']['absRefPrefix'];
|
||||
$absRefPrefixLength = strlen($absRefPrefix);
|
||||
} else {
|
||||
$absRefPrefix = false;
|
||||
}
|
||||
}
|
||||
|
||||
// remove abs ref prefix
|
||||
if ($absRefPrefix !== false && strpos($ret, $absRefPrefix) === 0) {
|
||||
$ret = substr($ret, $absRefPrefixLength);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return page change frequency
|
||||
*
|
||||
* @param array $page Page data
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
protected function getPageChangeFrequency(array $page)
|
||||
{
|
||||
$ret = 0;
|
||||
|
||||
if (!empty($page['tx_metaseo_change_frequency'])) {
|
||||
$ret = (int)$page['tx_metaseo_change_frequency'];
|
||||
} elseif (!empty($this->conf['sitemap.']['changeFrequency'])) {
|
||||
$ret = (int)$this->conf['sitemap.']['changeFrequency'];
|
||||
}
|
||||
|
||||
if (empty($pageChangeFrequency)) {
|
||||
$ret = 0;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if sitemap indexing is enabled
|
||||
*
|
||||
* @param string $indexingType Indexing type (page or typolink)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkIfSitemapIndexingIsEnabled($indexingType)
|
||||
{
|
||||
// check if sitemap is enabled in root
|
||||
if (!GeneralUtility::getRootSettingValue('is_sitemap', true)
|
||||
|| !GeneralUtility::getRootSettingValue('is_sitemap_' . $indexingType . '_indexer', true)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check current page
|
||||
if (!$this->checkIfCurrentPageIsIndexable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current page is indexable
|
||||
*
|
||||
* Will do following checks:
|
||||
* - REQUEST_METHOD (must be GET)
|
||||
* - If there is a feuser session
|
||||
* - Page type blacklisting
|
||||
* - If page is static cacheable
|
||||
* - If no_cache is not set
|
||||
*
|
||||
* (checks will be cached)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkIfCurrentPageIsIndexable()
|
||||
{
|
||||
// check caching status
|
||||
if ($this->pageIndexFlag !== null) {
|
||||
return $this->pageIndexFlag;
|
||||
}
|
||||
|
||||
// by default page is not cacheable
|
||||
$this->pageIndexFlag = false;
|
||||
|
||||
// ############################
|
||||
// Basic checks
|
||||
// ############################
|
||||
|
||||
$cacheConf = array(
|
||||
'allowNoStaticCachable' => (bool)$this->conf['sitemap.']['index.']['allowNoStaticCachable'],
|
||||
'allowNoCache' => (bool)$this->conf['sitemap.']['index.']['allowNoCache']
|
||||
);
|
||||
|
||||
|
||||
if (!FrontendUtility::isCacheable($cacheConf)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for type blacklisting (from typoscript PAGE object)
|
||||
if (in_array($GLOBALS['TSFE']->type, $this->pageTypeBlacklist)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for doktype blacklisting (from current page record)
|
||||
if (in_array((int)$GLOBALS['TSFE']->page['doktype'], $this->doktypeBlacklist)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// all checks successful, page is cacheable
|
||||
$this->pageIndexFlag = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
294
typo3conf/ext/metaseo/Classes/Hook/SitemapIndexLinkHook.php
Normal file
294
typo3conf/ext/metaseo/Classes/Hook/SitemapIndexLinkHook.php
Normal file
@@ -0,0 +1,294 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Hook;
|
||||
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
use Metaseo\Metaseo\Utility\SitemapUtility;
|
||||
|
||||
/**
|
||||
* Sitemap Indexer
|
||||
*/
|
||||
class SitemapIndexLinkHook extends SitemapIndexHook
|
||||
{
|
||||
|
||||
|
||||
// ########################################################################
|
||||
// HOOKS
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Hook: Link Parser
|
||||
*
|
||||
* @param array $pObj Object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function hook_linkParse(array &$pObj)
|
||||
{
|
||||
if (!$this->checkIfSitemapIndexingIsEnabled('typolink')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check
|
||||
if (empty($pObj['finalTagParts']) || empty($pObj['conf']) || empty($pObj['finalTagParts']['url'])) {
|
||||
// no valid link
|
||||
return;
|
||||
}
|
||||
|
||||
// Init link information
|
||||
$linkConf = $pObj['conf'];
|
||||
$linkUrl = $pObj['finalTagParts']['url'];
|
||||
list($linkPageUid, $linkType) = $this->parseLinkConf($pObj);
|
||||
$linkUrl = $this->processLinkUrl($linkUrl);
|
||||
|
||||
if ($linkType === null || empty($linkPageUid)) {
|
||||
// no valid link
|
||||
return;
|
||||
}
|
||||
|
||||
// check blacklisting
|
||||
if (GeneralUtility::checkUrlForBlacklisting($linkUrl, $this->blacklistConf)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ####################################
|
||||
// Init
|
||||
// ####################################
|
||||
|
||||
$addParameters = array();
|
||||
if (!empty($linkConf['additionalParams'])) {
|
||||
parse_str($linkConf['additionalParams'], $addParameters);
|
||||
}
|
||||
|
||||
// #####################################
|
||||
// Check if link is cacheable
|
||||
// #####################################
|
||||
$isValid = false;
|
||||
|
||||
// check if conf is valid
|
||||
if (!empty($linkConf['useCacheHash'])) {
|
||||
$isValid = true;
|
||||
}
|
||||
|
||||
// check for typical typo3 params
|
||||
$addParamsCache = $addParameters;
|
||||
unset($addParamsCache['L']);
|
||||
unset($addParamsCache['type']);
|
||||
|
||||
if (empty($addParamsCache)) {
|
||||
$isValid = true;
|
||||
}
|
||||
|
||||
if (!$isValid) {
|
||||
// page is not cacheable, skip it
|
||||
return;
|
||||
}
|
||||
|
||||
// #####################################
|
||||
// Rootline
|
||||
// #####################################
|
||||
$rootline = GeneralUtility::getRootLine($linkPageUid);
|
||||
|
||||
if (empty($rootline)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// #####################################
|
||||
// Page settings
|
||||
// #####################################
|
||||
|
||||
// Fetch sysLanguage
|
||||
if (isset($addParameters['L'])) {
|
||||
$pageLanguage = (int)$addParameters['L'];
|
||||
} else {
|
||||
$pageLanguage = (int)GeneralUtility::getLanguageId();
|
||||
}
|
||||
|
||||
// Index link
|
||||
$pageData = $this->generateSitemapPageData($linkUrl, $linkPageUid, $rootline, $pageLanguage, $linkType);
|
||||
if (!empty($pageData)) {
|
||||
SitemapUtility::index($pageData);
|
||||
}
|
||||
}
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Generate sitemap page data
|
||||
*
|
||||
* @param string $linkUrl Link of current url
|
||||
* @param integer $linkPageUid Link target page id
|
||||
* @param array $rootline Rootline of link
|
||||
* @param integer $pageLanguage Language id
|
||||
* @param integer $linkType Link type
|
||||
*
|
||||
* @return array
|
||||
* @internal param string $pageUrl Page url
|
||||
*
|
||||
*/
|
||||
protected function generateSitemapPageData($linkUrl, $linkPageUid, array $rootline, $pageLanguage, $linkType)
|
||||
{
|
||||
$tstamp = $_SERVER['REQUEST_TIME'];
|
||||
|
||||
$rootPid = $rootline[0]['uid'];
|
||||
|
||||
// Get page data from rootline
|
||||
$page = reset($rootline);
|
||||
|
||||
$ret = array(
|
||||
'tstamp' => $tstamp,
|
||||
'crdate' => $tstamp,
|
||||
'page_rootpid' => $rootPid,
|
||||
'page_uid' => $linkPageUid,
|
||||
'page_language' => $pageLanguage,
|
||||
'page_url' => $this->getPageUrl($linkUrl),
|
||||
'page_depth' => count($rootline),
|
||||
'page_change_frequency' => $this->getPageChangeFrequency($page),
|
||||
'page_type' => $linkType,
|
||||
'expire' => $this->indexExpiration,
|
||||
);
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'sitemapIndexLink', $this, $ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse uid and type from generated link (from config array)
|
||||
*
|
||||
* @param array $conf Generated Link config array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parseLinkConf(array $conf)
|
||||
{
|
||||
$uid = null;
|
||||
$type = null;
|
||||
|
||||
// Check link type
|
||||
switch ($conf['finalTagParts']['TYPE']) {
|
||||
// ##############
|
||||
// Page URL
|
||||
// ##############
|
||||
case 'page':
|
||||
// TODO: Add support for more parameter checks
|
||||
if (is_numeric($conf['conf']['parameter'])) {
|
||||
$uid = $conf['conf']['parameter'];
|
||||
}
|
||||
|
||||
$type = SitemapUtility::SITEMAP_TYPE_PAGE;
|
||||
break;
|
||||
|
||||
// ##############
|
||||
// File URL
|
||||
// ##############
|
||||
case 'file':
|
||||
$fileUrl = $conf['finalTagParts']['url'];
|
||||
|
||||
if ($this->checkIfFileIsWhitelisted($fileUrl)) {
|
||||
// File will be registered from the root page
|
||||
// to prevent duplicate urls
|
||||
$uid = GeneralUtility::getRootPid();
|
||||
$type = SitemapUtility::SITEMAP_TYPE_FILE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return array($uid, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if file is whitelisted
|
||||
*
|
||||
* Configuration specified in
|
||||
* plugin.metaseo.sitemap.index.fileExtension
|
||||
*
|
||||
* @param string $url Url to file
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function checkIfFileIsWhitelisted($url)
|
||||
{
|
||||
$ret = false;
|
||||
|
||||
// check for valid url
|
||||
if (empty($url)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// parse url to extract only path
|
||||
$urlParts = parse_url($url);
|
||||
$filePath = $urlParts['path'];
|
||||
|
||||
// Extract last file extension
|
||||
if (preg_match('/\.([^\.]+)$/', $filePath, $matches)) {
|
||||
$fileExt = trim(strtolower($matches[1]));
|
||||
|
||||
// Check if file extension is whitelisted
|
||||
foreach ($this->fileExtList as $allowedFileExt) {
|
||||
if ($allowedFileExt === $fileExt) {
|
||||
// File is whitelisted, not blacklisted
|
||||
$ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current page url
|
||||
*
|
||||
* @param string $linkUrl Link url
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected function getPageUrl($linkUrl)
|
||||
{
|
||||
$linkParts = parse_url($linkUrl);
|
||||
|
||||
// Remove left / (but only if not root page)
|
||||
if ($linkParts['path'] === '/') {
|
||||
// Link points to root page
|
||||
$ret = '/';
|
||||
} else {
|
||||
// Link points to another page, strip left /
|
||||
$ret = ltrim($linkParts['path'], '/');
|
||||
}
|
||||
|
||||
// Add query
|
||||
if (!empty($linkParts['query'])) {
|
||||
$ret .= '?' . $linkParts['query'];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
168
typo3conf/ext/metaseo/Classes/Hook/SitemapIndexPageHook.php
Normal file
168
typo3conf/ext/metaseo/Classes/Hook/SitemapIndexPageHook.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Hook;
|
||||
|
||||
use Metaseo\Metaseo\Utility\FrontendUtility;
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
use Metaseo\Metaseo\Utility\SitemapUtility;
|
||||
|
||||
/**
|
||||
* Sitemap Indexer
|
||||
*/
|
||||
class SitemapIndexPageHook extends SitemapIndexHook
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Init configuration
|
||||
*/
|
||||
protected function initConfiguration()
|
||||
{
|
||||
parent::initConfiguration();
|
||||
|
||||
// Check custom index expiration (from connector)
|
||||
/** @var \Metaseo\Metaseo\Connector $connector */
|
||||
$connector = $this->objectManager->get('Metaseo\\Metaseo\\Connector');
|
||||
$sitemapStore = $connector->getStore('sitemap');
|
||||
|
||||
// Set new expiration date
|
||||
if (!empty($sitemapStore['expiration'])) {
|
||||
$this->indexExpiration = $_SERVER['REQUEST_TIME'] + ($sitemapStore['expiration'] * 24 * 60 * 60);
|
||||
}
|
||||
}
|
||||
|
||||
// ########################################################################
|
||||
// HOOKS
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Hook: Index Page Content
|
||||
*/
|
||||
public function hook_indexContent()
|
||||
{
|
||||
$this->addPageToSitemapIndex();
|
||||
|
||||
$possibility = (int)GeneralUtility::getExtConf('sitemap_clearCachePossibility', 0);
|
||||
|
||||
if ($possibility > 0) {
|
||||
$clearCacheChance = ceil(mt_rand(0, $possibility));
|
||||
if ($clearCacheChance == 1) {
|
||||
SitemapUtility::expire();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Add Page to sitemap table
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPageToSitemapIndex()
|
||||
{
|
||||
if (!$this->checkIfSitemapIndexingIsEnabled('page')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pageUrl = $this->getPageUrl();
|
||||
|
||||
// check blacklisting
|
||||
if (GeneralUtility::checkUrlForBlacklisting($pageUrl, $this->blacklistConf)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Index page
|
||||
$pageData = $this->generateSitemapPageData($pageUrl);
|
||||
if (!empty($pageData)) {
|
||||
SitemapUtility::index($pageData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate sitemap page data
|
||||
*
|
||||
* @param string $pageUrl Page url
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function generateSitemapPageData($pageUrl)
|
||||
{
|
||||
$page = $GLOBALS['TSFE']->page;
|
||||
|
||||
$tstamp = $_SERVER['REQUEST_TIME'];
|
||||
|
||||
$ret = array(
|
||||
'tstamp' => $tstamp,
|
||||
'crdate' => $tstamp,
|
||||
'page_rootpid' => GeneralUtility::getRootPid(),
|
||||
'page_uid' => $GLOBALS['TSFE']->id,
|
||||
'page_language' => GeneralUtility::getLanguageId(),
|
||||
'page_url' => $pageUrl,
|
||||
'page_depth' => count($GLOBALS['TSFE']->rootLine),
|
||||
'page_change_frequency' => $this->getPageChangeFrequency($page),
|
||||
'page_type' => SitemapUtility::SITEMAP_TYPE_PAGE,
|
||||
'expire' => $this->indexExpiration,
|
||||
);
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'sitemapIndexPage', $this, $ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current page url
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
protected function getPageUrl()
|
||||
{
|
||||
// Fetch chash
|
||||
$pageHash = null;
|
||||
if (!empty($GLOBALS['TSFE']->cHash)) {
|
||||
$pageHash = $GLOBALS['TSFE']->cHash;
|
||||
}
|
||||
|
||||
|
||||
// Fetch pageUrl
|
||||
if ($pageHash !== null) {
|
||||
$ret = FrontendUtility::getCurrentUrl();
|
||||
} else {
|
||||
$linkConf = array(
|
||||
'parameter' => $GLOBALS['TSFE']->id,
|
||||
);
|
||||
|
||||
$ret = $GLOBALS['TSFE']->cObj->typoLink_URL($linkConf);
|
||||
$ret = $this->processLinkUrl($ret);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
154
typo3conf/ext/metaseo/Classes/Hook/TCA/RobotsTxtDefault.php
Normal file
154
typo3conf/ext/metaseo/Classes/Hook/TCA/RobotsTxtDefault.php
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Hook\TCA;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
|
||||
|
||||
/**
|
||||
* TCA Hook: Robots.txt default content
|
||||
*/
|
||||
class RobotsTxtDefault
|
||||
{
|
||||
|
||||
/**
|
||||
* TYPO3 Object manager
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManager
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* TYPO3 configuration manager
|
||||
*
|
||||
* @var ConfigurationManager
|
||||
*/
|
||||
protected $configurationManager;
|
||||
|
||||
/**
|
||||
* TYPO3 Content object renderer
|
||||
*
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
protected $cObj;
|
||||
|
||||
/**
|
||||
* Render default Robots.txt from TypoScript Setup
|
||||
*
|
||||
* @param array $data TCE Information array
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function main(array $data)
|
||||
{
|
||||
// ############################
|
||||
// Init
|
||||
// ############################
|
||||
|
||||
/** @var \TYPO3\CMS\Extbase\Object\ObjectManager objectManager */
|
||||
$this->objectManager = GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Extbase\\Object\\ObjectManager'
|
||||
);
|
||||
|
||||
/** @var ConfigurationManager configurationManager */
|
||||
$this->configurationManager = $this->objectManager->get(
|
||||
'TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager'
|
||||
);
|
||||
|
||||
/** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer cObj */
|
||||
$this->cObj = $this->objectManager->get('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
|
||||
|
||||
// ############################
|
||||
// Init TSFE
|
||||
// ############################
|
||||
$rootPageId = $data['row']['pid'];
|
||||
|
||||
/** @var \TYPO3\CMS\Core\TimeTracker\NullTimeTracker $timeTracker */
|
||||
$timeTracker = $this->objectManager->get('TYPO3\\CMS\\Core\\TimeTracker\\NullTimeTracker');
|
||||
|
||||
$GLOBALS['TT'] = $timeTracker;
|
||||
$GLOBALS['TT']->start();
|
||||
|
||||
/** @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $tsfeController */
|
||||
$tsfeController = $this->objectManager->get(
|
||||
'TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController',
|
||||
$GLOBALS['TYPO3_CONF_VARS'],
|
||||
$rootPageId,
|
||||
0
|
||||
);
|
||||
|
||||
$GLOBALS['TSFE'] = $tsfeController;
|
||||
|
||||
// ############################
|
||||
// Render default robots.txt content
|
||||
// ############################
|
||||
|
||||
// Fetch TypoScript setup
|
||||
$tsSetup = $this->configurationManager->getConfiguration(
|
||||
ConfigurationManager::CONFIGURATION_TYPE_FULL_TYPOSCRIPT,
|
||||
'metaseo',
|
||||
'plugin'
|
||||
);
|
||||
|
||||
$content = '';
|
||||
if (!empty($tsSetup['plugin.']['metaseo.']['robotsTxt.'])) {
|
||||
$content = $this->cObj->cObjGetSingle(
|
||||
$tsSetup['plugin.']['metaseo.']['robotsTxt.']['default'],
|
||||
$tsSetup['plugin.']['metaseo.']['robotsTxt.']['default.']
|
||||
);
|
||||
}
|
||||
|
||||
$content = htmlspecialchars($content);
|
||||
$content = nl2br($content);
|
||||
|
||||
/**
|
||||
* instanciation of TypoScriptFrontendController instanciates PageRenderer which
|
||||
* sets backPath to TYPO3_mainDir which is very bad in the Backend. Therefore,
|
||||
* we must set it back to null to not get frontend-prefixed asset URLs. See #150.
|
||||
*/
|
||||
$this->cleanUpPageRendererBackPath();
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets backPath of PageRenderer back to null (for Backend)
|
||||
*/
|
||||
protected function cleanUpPageRendererBackPath()
|
||||
{
|
||||
$pageRenderer = $this->getPageRenderer();
|
||||
$pageRenderer->setBackPath(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \TYPO3\CMS\Core\Page\PageRenderer
|
||||
*/
|
||||
protected function getPageRenderer()
|
||||
{
|
||||
return GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Page\\PageRenderer');
|
||||
}
|
||||
}
|
||||
90
typo3conf/ext/metaseo/Classes/Page/AbstractPage.php
Normal file
90
typo3conf/ext/metaseo/Classes/Page/AbstractPage.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Page;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Abstract page
|
||||
*/
|
||||
abstract class AbstractPage
|
||||
{
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManager
|
||||
* @inject
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* TypoScript Setup
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tsSetup = array();
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Init object manager
|
||||
$this->objectManager = GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Extbase\\Object\\ObjectManager'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function main();
|
||||
|
||||
/**
|
||||
* Show error
|
||||
*
|
||||
* @param string $msg Message
|
||||
*/
|
||||
protected function showError($msg = null)
|
||||
{
|
||||
if ($msg === null) {
|
||||
$msg = 'Sitemap is not available, please check your configuration';
|
||||
}
|
||||
|
||||
header('HTTP/1.0 503 Service Unavailable');
|
||||
$GLOBALS['TSFE']->pageErrorHandler(true, null, $msg);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
59
typo3conf/ext/metaseo/Classes/Page/Part/AbstractPart.php
Normal file
59
typo3conf/ext/metaseo/Classes/Page/Part/AbstractPart.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Page\Part;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Abstract part
|
||||
*/
|
||||
abstract class AbstractPart
|
||||
{
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManager
|
||||
* @inject
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Init object manager
|
||||
$this->objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
|
||||
}
|
||||
}
|
||||
235
typo3conf/ext/metaseo/Classes/Page/Part/FooterPart.php
Normal file
235
typo3conf/ext/metaseo/Classes/Page/Part/FooterPart.php
Normal file
@@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Page\Part;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Page Footer
|
||||
*/
|
||||
class FooterPart extends AbstractPart
|
||||
{
|
||||
/**
|
||||
* Content object renderer
|
||||
*
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
public $cObj;
|
||||
|
||||
/**
|
||||
* Add Page Footer
|
||||
*
|
||||
* @param string $title Default page title (rendered by TYPO3)
|
||||
*
|
||||
* @return string Modified page title
|
||||
*/
|
||||
public function main($title)
|
||||
{
|
||||
// INIT
|
||||
$ret = array();
|
||||
$tsSetup = $GLOBALS['TSFE']->tmpl->setup;
|
||||
$tsServices = array();
|
||||
|
||||
$beLoggedIn = isset($GLOBALS['BE_USER']->user['username']);
|
||||
|
||||
$disabledHeaderCode = false;
|
||||
if (!empty($tsSetup['config.']['disableAllHeaderCode'])) {
|
||||
$disabledHeaderCode = true;
|
||||
}
|
||||
|
||||
if (!empty($tsSetup['plugin.']['metaseo.']['services.'])) {
|
||||
$tsServices = $tsSetup['plugin.']['metaseo.']['services.'];
|
||||
}
|
||||
|
||||
// Call hook
|
||||
\Metaseo\Metaseo\Utility\GeneralUtility::callHookAndSignal(__CLASS__, 'pageFooterSetup', $this, $tsServices);
|
||||
|
||||
// #########################################
|
||||
// GOOGLE ANALYTICS
|
||||
// #########################################
|
||||
|
||||
if (!empty($tsServices['googleAnalytics'])) {
|
||||
$gaConf = $tsServices['googleAnalytics.'];
|
||||
|
||||
$gaEnabled = true;
|
||||
|
||||
if ($disabledHeaderCode && empty($gaConf['enableIfHeaderIsDisabled'])) {
|
||||
$gaEnabled = false;
|
||||
}
|
||||
|
||||
if ($gaEnabled && !(empty($gaConf['showIfBeLogin']) && $beLoggedIn)) {
|
||||
// Build Google Analytics service
|
||||
$ret['ga'] = $this->buildGoogleAnalyticsCode($tsServices, $gaConf);
|
||||
|
||||
if (!empty($gaConf['trackDownloads']) && !empty($gaConf['trackDownloadsScript'])) {
|
||||
$ret['ga.trackdownload'] = $this->serviceGoogleAnalyticsTrackDownloads($tsServices, $gaConf);
|
||||
}
|
||||
} elseif ($gaEnabled && $beLoggedIn) {
|
||||
// Disable caching
|
||||
$GLOBALS['TSFE']->set_no_cache('MetaSEO: Google Analytics code disabled, backend login detected');
|
||||
|
||||
// Backend login detected, disable cache because this page is viewed by BE-users
|
||||
$ret['ga.disabled'] = '<!-- Google Analytics disabled, '
|
||||
. 'Page cache disabled - Backend-Login detected -->';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #########################################
|
||||
// PIWIK
|
||||
// #########################################
|
||||
if (!empty($tsServices['piwik.'])
|
||||
&& !empty($tsServices['piwik.']['url'])
|
||||
&& !empty($tsServices['piwik.']['id'])
|
||||
) {
|
||||
$piwikConf = $tsServices['piwik.'];
|
||||
|
||||
$piwikEnabled = true;
|
||||
|
||||
if ($disabledHeaderCode && empty($piwikConf['enableIfHeaderIsDisabled'])) {
|
||||
$piwikEnabled = false;
|
||||
}
|
||||
|
||||
if ($piwikEnabled && !(empty($piwikConf['showIfBeLogin']) && $beLoggedIn)) {
|
||||
// Build Piwik service
|
||||
$ret['piwik'] = $this->buildPiwikCode($tsServices, $piwikConf);
|
||||
} elseif ($piwikEnabled && $beLoggedIn) {
|
||||
// Disable caching
|
||||
$GLOBALS['TSFE']->set_no_cache('MetaSEO: Piwik code disabled, backend login detected');
|
||||
|
||||
// Backend login detected, disable cache because this page is viewed by BE-users
|
||||
$ret['piwik.disabled'] = '<!-- Piwik disabled, Page cache disabled - Backend-Login detected -->';
|
||||
}
|
||||
}
|
||||
|
||||
// Call hook
|
||||
\Metaseo\Metaseo\Utility\GeneralUtility::callHookAndSignal(__CLASS__, 'pageFooterOutput', $this, $ret);
|
||||
|
||||
return implode("\n", $ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Google analytics
|
||||
*
|
||||
* @param array $tsServices SetupTS of services
|
||||
* @param array $gaConf Google Analytics configuration
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function buildGoogleAnalyticsCode(array $tsServices, array $gaConf)
|
||||
{
|
||||
$ret = array();
|
||||
$gaCodeList = GeneralUtility::trimExplode(',', $tsServices['googleAnalytics']);
|
||||
|
||||
foreach ($gaCodeList as $gaCode) {
|
||||
$customCode = '';
|
||||
if (!empty($gaConf['customizationCode'])) {
|
||||
$customCode .= "\n" . $this->cObj->cObjGetSingle(
|
||||
$gaConf['customizationCode'],
|
||||
$gaConf['customizationCode.']
|
||||
);
|
||||
}
|
||||
|
||||
$this->cObj->data['gaCode'] = $gaCode;
|
||||
$this->cObj->data['gaIsAnonymize'] = (int)!empty($gaConf['anonymizeIp']);
|
||||
$this->cObj->data['gaDomainName'] = $gaConf['domainName'];
|
||||
$this->cObj->data['gaCustomizationCode'] = $customCode;
|
||||
$this->cObj->data['gaUseUniversalAnalytics'] = (int)!empty($gaConf['universalAnalytics']);
|
||||
|
||||
// Build code
|
||||
$ret[] = $this->cObj->cObjGetSingle($gaConf['template'], $gaConf['template.']);
|
||||
}
|
||||
|
||||
// Build all GA codes
|
||||
$ret = implode("\n", $ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Google analytics
|
||||
*
|
||||
* @param array $tsServices SetupTS of services
|
||||
* @param array $gaConf Google Analytics configuration
|
||||
*
|
||||
* @return string
|
||||
* @todo $tsServices is never used
|
||||
*/
|
||||
public function serviceGoogleAnalyticsTrackDownloads(array $tsServices, array $gaConf)
|
||||
{
|
||||
$jsFile = Typo3GeneralUtility::getFileAbsFileName($gaConf['trackDownloadsScript']);
|
||||
$jsfile = preg_replace('/^' . preg_quote(PATH_site, '/') . '/i', '', $jsFile);
|
||||
|
||||
$ret = '<script type="text/javascript" src="' . htmlspecialchars($jsfile) . '"></script>';
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Piwik
|
||||
*
|
||||
* @param array $tsServices SetupTS of services
|
||||
* @param array $piwikConf Piwik configuration
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function buildPiwikCode(array $tsServices, array $piwikConf)
|
||||
{
|
||||
$ret = array();
|
||||
$piwikCodeList = GeneralUtility::trimExplode(',', $piwikConf['id']);
|
||||
|
||||
foreach ($piwikCodeList as $piwikCode) {
|
||||
$customCode = '';
|
||||
if (!empty($piwikConf['customizationCode'])) {
|
||||
$customCode .= "\n";
|
||||
$customCode .= $this->cObj->cObjGetSingle(
|
||||
$piwikConf['customizationCode'],
|
||||
$piwikConf['customizationCode.']
|
||||
);
|
||||
}
|
||||
|
||||
// remove last slash
|
||||
$piwikConf['url'] = rtrim($piwikConf['url'], '/');
|
||||
|
||||
$this->cObj->data['piwikUrl'] = $piwikConf['url'];
|
||||
$this->cObj->data['piwikId'] = $piwikCode;
|
||||
$this->cObj->data['piwikDomainName'] = $piwikConf['domainName'];
|
||||
$this->cObj->data['piwikCookieDomainName'] = $piwikConf['cookieDomainName'];
|
||||
$this->cObj->data['piwikDoNotTrack'] = $piwikConf['doNotTrack'];
|
||||
$this->cObj->data['piwikCustomizationCode'] = $customCode;
|
||||
|
||||
// Build code
|
||||
$ret[] = $this->cObj->cObjGetSingle($piwikConf['template'], $piwikConf['template.']);
|
||||
}
|
||||
|
||||
// Build all piwik codes
|
||||
$ret = implode("\n", $ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
1353
typo3conf/ext/metaseo/Classes/Page/Part/MetatagPart.php
Normal file
1353
typo3conf/ext/metaseo/Classes/Page/Part/MetatagPart.php
Normal file
File diff suppressed because it is too large
Load Diff
417
typo3conf/ext/metaseo/Classes/Page/Part/PagetitlePart.php
Normal file
417
typo3conf/ext/metaseo/Classes/Page/Part/PagetitlePart.php
Normal file
@@ -0,0 +1,417 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Page\Part;
|
||||
|
||||
use Metaseo\Metaseo\Utility\FrontendUtility;
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
|
||||
/**
|
||||
* Page Title Changer
|
||||
*/
|
||||
class PagetitlePart extends AbstractPart
|
||||
{
|
||||
|
||||
/**
|
||||
* List of stdWrap manipulations
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $stdWrapList = array();
|
||||
|
||||
/**
|
||||
* Content object renderer
|
||||
*
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
public $cObj;
|
||||
|
||||
/**
|
||||
* TypoScript Setup
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tsSetup = array();
|
||||
|
||||
/**
|
||||
* TypoScript Setup (subtree of plugin.metaseo)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tsSetupSeo = array();
|
||||
|
||||
/**
|
||||
* Page rootline
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $rootLine = array();
|
||||
|
||||
/**
|
||||
* Add SEO-Page Title
|
||||
*
|
||||
* @param string $title Default page title (rendered by TYPO3)
|
||||
*
|
||||
* @return string Modified page title
|
||||
*/
|
||||
public function main($title)
|
||||
{
|
||||
$ret = null;
|
||||
|
||||
// ############################
|
||||
// Fetch from cache
|
||||
// ############################
|
||||
|
||||
$pageTitleCachingEnabled = $this->checkIfPageTitleCachingEnabled();
|
||||
if ($pageTitleCachingEnabled === true) {
|
||||
$cacheIdentification = sprintf(
|
||||
'%s_%s_title',
|
||||
$GLOBALS['TSFE']->id,
|
||||
substr(sha1(FrontendUtility::getCurrentUrl()), 10, 30)
|
||||
);
|
||||
|
||||
/** @var \TYPO3\CMS\Core\Cache\CacheManager $cacheManager */
|
||||
$objectManager = Typo3GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Extbase\\Object\\ObjectManager'
|
||||
);
|
||||
$cacheManager = $objectManager->get('TYPO3\\CMS\\Core\\Cache\\CacheManager');
|
||||
$cache = $cacheManager->getCache('cache_pagesection');
|
||||
|
||||
$cacheTitle = $cache->get($cacheIdentification);
|
||||
if (!empty($cacheTitle)) {
|
||||
$ret = $cacheTitle;
|
||||
}
|
||||
}
|
||||
|
||||
// ############################
|
||||
// Generate page title
|
||||
// ############################
|
||||
|
||||
// Generate page title if not set
|
||||
// also fallback
|
||||
if (empty($ret)) {
|
||||
$this->initialize();
|
||||
$ret = $this->generatePageTitle($title);
|
||||
|
||||
// Cache page title (if page is not cacheable)
|
||||
if ($pageTitleCachingEnabled === true && isset($cache) && isset($cacheIdentification)) {
|
||||
$cache->set($cacheIdentification, $ret, array('pageId_' . $GLOBALS['TSFE']->id));
|
||||
}
|
||||
}
|
||||
|
||||
// ############################
|
||||
// Output
|
||||
// ############################
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'pageTitleOutput', $this, $ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
$this->cObj = $GLOBALS['TSFE']->cObj;
|
||||
$this->tsSetup = $GLOBALS['TSFE']->tmpl->setup;
|
||||
$this->rootLine = GeneralUtility::getRootLine();
|
||||
|
||||
if (!empty($this->tsSetup['plugin.']['metaseo.'])) {
|
||||
$this->tsSetupSeo = $this->tsSetup['plugin.']['metaseo.'];
|
||||
|
||||
// get stdwrap list
|
||||
if (!empty($this->tsSetupSeo['stdWrap.'])) {
|
||||
$this->stdWrapList = $this->tsSetupSeo['pageTitle.']['stdWrap.'];
|
||||
}
|
||||
} else {
|
||||
$this->tsSetupSeo = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if page title caching is enabled
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function checkIfPageTitleCachingEnabled()
|
||||
{
|
||||
$cachingEnabled = !empty($GLOBALS['TSFE']->tmpl->setup['plugin.']['metaseo.']['pageTitle.']['caching']);
|
||||
|
||||
// Enable caching only if caching is enabled in SetupTS
|
||||
// And if there is any USER_INT on the current page
|
||||
//
|
||||
// -> USER_INT will break Connector pagetitle setting
|
||||
// because the plugin output is cached but not the whole
|
||||
// page. so the Connector will not be called again
|
||||
// and the default page title will be shown
|
||||
// which is wrong
|
||||
// -> if the page is fully cacheable we don't have anything
|
||||
// to do
|
||||
return $cachingEnabled && !FrontendUtility::isCacheable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add SEO-Page Title
|
||||
*
|
||||
* @param string $title Default page title (rendered by TYPO3)
|
||||
*
|
||||
* @return string Modified page title
|
||||
* @todo: split up function (too long)
|
||||
*/
|
||||
public function generatePageTitle($title)
|
||||
{
|
||||
// INIT
|
||||
$ret = $title;
|
||||
$rawTitle = !empty($GLOBALS['TSFE']->altPageTitle) ?
|
||||
$GLOBALS['TSFE']->altPageTitle : $GLOBALS['TSFE']->page['title'];
|
||||
$currentPid = $GLOBALS['TSFE']->id;
|
||||
$skipPrefixSuffix = false;
|
||||
$applySitetitle = true;
|
||||
|
||||
$pageTitlePrefix = false;
|
||||
$pageTitleSuffix = false;
|
||||
|
||||
$this->stdWrapList = array();
|
||||
|
||||
$sitetitle = $this->tsSetup['sitetitle'];
|
||||
|
||||
// Use browsertitle if available
|
||||
if (!empty($GLOBALS['TSFE']->page['tx_metaseo_pagetitle_rel'])) {
|
||||
$rawTitle = $GLOBALS['TSFE']->page['tx_metaseo_pagetitle_rel'];
|
||||
}
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(
|
||||
__CLASS__,
|
||||
'pageTitleSetup',
|
||||
$this,
|
||||
$this->tsSetupSeo
|
||||
);
|
||||
|
||||
// get stdwrap list
|
||||
if (!empty($this->tsSetupSeo['pageTitle.']['stdWrap.'])) {
|
||||
$this->stdWrapList = $this->tsSetupSeo['pageTitle.']['stdWrap.'];
|
||||
}
|
||||
|
||||
// Apply stdWrap before
|
||||
if (!empty($this->stdWrapList['before.'])) {
|
||||
$rawTitle = $this->cObj->stdWrap($rawTitle, $this->stdWrapList['before.']);
|
||||
}
|
||||
|
||||
// #######################################################################
|
||||
// RAW PAGE TITLE
|
||||
// #######################################################################
|
||||
if (!empty($GLOBALS['TSFE']->page['tx_metaseo_pagetitle'])) {
|
||||
$ret = $GLOBALS['TSFE']->page['tx_metaseo_pagetitle'];
|
||||
|
||||
// Add template prefix/suffix
|
||||
if (empty($this->tsSetupSeo['pageTitle.']['applySitetitleToPagetitle'])) {
|
||||
$applySitetitle = false;
|
||||
}
|
||||
|
||||
$skipPrefixSuffix = true;
|
||||
}
|
||||
|
||||
|
||||
// #######################################################################
|
||||
// PAGE TITLE PREFIX/SUFFIX
|
||||
// #######################################################################
|
||||
if (!$skipPrefixSuffix) {
|
||||
foreach ($this->rootLine as $page) {
|
||||
switch ((int)$page['tx_metaseo_inheritance']) {
|
||||
case 0:
|
||||
// ###################################
|
||||
// Normal
|
||||
// ###################################
|
||||
if (!empty($page['tx_metaseo_pagetitle_prefix'])) {
|
||||
$pageTitlePrefix = $page['tx_metaseo_pagetitle_prefix'];
|
||||
}
|
||||
|
||||
if (!empty($page['tx_metaseo_pagetitle_suffix'])) {
|
||||
$pageTitleSuffix = $page['tx_metaseo_pagetitle_suffix'];
|
||||
}
|
||||
|
||||
if ($pageTitlePrefix !== false || $pageTitleSuffix !== false) {
|
||||
// pagetitle found - break foreach
|
||||
break 2;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
// ###################################
|
||||
// Skip
|
||||
// (don't inherit from this page)
|
||||
// ###################################
|
||||
if ((int)$page['uid'] != $currentPid) {
|
||||
continue 2;
|
||||
}
|
||||
|
||||
if (!empty($page['tx_metaseo_pagetitle_prefix'])) {
|
||||
$pageTitlePrefix = $page['tx_metaseo_pagetitle_prefix'];
|
||||
}
|
||||
|
||||
if (!empty($page['tx_metaseo_pagetitle_suffix'])) {
|
||||
$pageTitleSuffix = $page['tx_metaseo_pagetitle_suffix'];
|
||||
}
|
||||
|
||||
break 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// #################
|
||||
// Process settings from access point
|
||||
// #################
|
||||
$connector = $this->objectManager->get('Metaseo\\Metaseo\\Connector');
|
||||
$store = $connector->getStore('pagetitle');
|
||||
|
||||
if (!empty($store)) {
|
||||
if (isset($store['pagetitle.title'])) {
|
||||
$rawTitle = $store['pagetitle.title'];
|
||||
}
|
||||
|
||||
if (isset($store['pagetitle.prefix'])) {
|
||||
$pageTitlePrefix = $store['pagetitle.prefix'];
|
||||
}
|
||||
|
||||
if (isset($store['pagetitle.suffix'])) {
|
||||
$pageTitleSuffix = $store['pagetitle.suffix'];
|
||||
}
|
||||
|
||||
if (isset($store['pagetitle.absolute'])) {
|
||||
$ret = $store['pagetitle.absolute'];
|
||||
$rawTitle = $store['pagetitle.absolute'];
|
||||
|
||||
$pageTitlePrefix = false;
|
||||
$pageTitleSuffix = false;
|
||||
|
||||
if (empty($this->tsSetupSeo['pageTitle.']['applySitetitleToPagetitle'])) {
|
||||
$applySitetitle = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($store['pagetitle.sitetitle'])) {
|
||||
$sitetitle = $store['pagetitle.sitetitle'];
|
||||
}
|
||||
}
|
||||
|
||||
// Apply prefix and suffix
|
||||
if ($pageTitlePrefix !== false || $pageTitleSuffix !== false) {
|
||||
$ret = $rawTitle;
|
||||
|
||||
if ($pageTitlePrefix !== false) {
|
||||
$ret = $pageTitlePrefix . ' ' . $ret;
|
||||
}
|
||||
|
||||
if ($pageTitleSuffix !== false) {
|
||||
$ret .= ' ' . $pageTitleSuffix;
|
||||
}
|
||||
|
||||
if (!empty($this->tsSetupSeo['pageTitle.']['applySitetitleToPrefixSuffix'])) {
|
||||
$applySitetitle = true;
|
||||
}
|
||||
} else {
|
||||
$ret = $rawTitle;
|
||||
}
|
||||
}
|
||||
|
||||
// #######################################################################
|
||||
// APPLY SITETITLE (from setup)
|
||||
// #######################################################################
|
||||
if ($applySitetitle) {
|
||||
$ret = $this->applySitetitleToPagetitle($sitetitle, $ret);
|
||||
}
|
||||
|
||||
// Apply stdWrap after
|
||||
if (!empty($this->stdWrapList['after.'])) {
|
||||
$ret = $this->cObj->stdWrap($ret, $this->stdWrapList['after.']);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply sitetitle (from sys_template) to pagetitle
|
||||
*
|
||||
* @param string $sitetitle Sitetitle
|
||||
* @param string $title Page title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function applySitetitleToPagetitle($sitetitle, $title)
|
||||
{
|
||||
$pageTitleGlue = ':';
|
||||
$glueSpacerBefore = '';
|
||||
$glueSpacerAfter = '';
|
||||
|
||||
$ret = $title;
|
||||
|
||||
// Overwrite sitetitle with the one from ts-setup (if available)
|
||||
if (!empty($this->tsSetupSeo['pageTitle.']['sitetitle'])) {
|
||||
$sitetitle = $this->tsSetupSeo['pageTitle.']['sitetitle'];
|
||||
}
|
||||
|
||||
// Apply stdWrap after
|
||||
if (!empty($this->stdWrapList['sitetitle.'])) {
|
||||
$sitetitle = $this->cObj->stdWrap($sitetitle, $this->stdWrapList['sitetitle.']);
|
||||
}
|
||||
|
||||
|
||||
if (isset($this->tsSetupSeo['pageTitle.']['sitetitleGlue'])) {
|
||||
$pageTitleGlue = $this->tsSetupSeo['pageTitle.']['sitetitleGlue'];
|
||||
}
|
||||
|
||||
if (!empty($this->tsSetupSeo['pageTitle.']['sitetitleGlueSpaceBefore'])) {
|
||||
$glueSpacerBefore = ' ';
|
||||
}
|
||||
|
||||
if (!empty($this->tsSetupSeo['pageTitle.']['sitetitleGlueSpaceAfter'])) {
|
||||
$glueSpacerAfter = ' ';
|
||||
}
|
||||
|
||||
$sitetitlePosition = 0;
|
||||
if (isset($this->tsSetupSeo['pageTitle.']['sitetitlePosition'])) {
|
||||
$sitetitlePosition = (int)$this->tsSetupSeo['pageTitle.']['sitetitlePosition'];
|
||||
} elseif (isset($this->tsSetup['config.']['pageTitleFirst'])) {
|
||||
$sitetitlePosition = (int)$this->tsSetup['config.']['pageTitleFirst'];
|
||||
}
|
||||
|
||||
// add overall pagetitle from template/ts-setup
|
||||
if ($sitetitlePosition) {
|
||||
// suffix
|
||||
$ret .= $glueSpacerBefore . $pageTitleGlue . $glueSpacerAfter . $sitetitle;
|
||||
|
||||
return $ret;
|
||||
} else {
|
||||
// prefix (default)
|
||||
$ret = $sitetitle . $glueSpacerBefore . $pageTitleGlue . $glueSpacerAfter . $ret;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
225
typo3conf/ext/metaseo/Classes/Page/RobotsTxtPage.php
Normal file
225
typo3conf/ext/metaseo/Classes/Page/RobotsTxtPage.php
Normal file
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Page;
|
||||
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Robots txt Page
|
||||
*/
|
||||
class RobotsTxtPage extends AbstractPage
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Content object renderer
|
||||
*
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
public $cObj;
|
||||
|
||||
/**
|
||||
* TypoScript Setup Seo
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tsSetupSeo = array();
|
||||
|
||||
/**
|
||||
* Root page id
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $rootPid;
|
||||
|
||||
/**
|
||||
* Language id
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $languageId;
|
||||
|
||||
/**
|
||||
* Link to static sitemap
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $linkToStaticSitemap;
|
||||
|
||||
/**
|
||||
* Sitemap language lock
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $sitemapLanguageLock;
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Fetch and build robots.txt
|
||||
*/
|
||||
public function main()
|
||||
{
|
||||
$ret = '';
|
||||
|
||||
$settings = GeneralUtility::getRootSetting();
|
||||
|
||||
// INIT
|
||||
$this->tsSetup = $GLOBALS['TSFE']->tmpl->setup;
|
||||
$this->cObj = $GLOBALS['TSFE']->cObj;
|
||||
$this->rootPid = GeneralUtility::getRootPid();
|
||||
|
||||
$this->tsSetupSeo = null;
|
||||
if (!empty($this->tsSetup['plugin.']['metaseo.']['robotsTxt.'])) {
|
||||
$this->tsSetupSeo = $this->tsSetup['plugin.']['metaseo.']['robotsTxt.'];
|
||||
}
|
||||
|
||||
// check if sitemap is enabled in root
|
||||
if (!GeneralUtility::getRootSettingValue('is_robotstxt', true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->linkToStaticSitemap = GeneralUtility::getRootSettingValue('is_robotstxt_sitemap_static', false);
|
||||
|
||||
// Language lock
|
||||
$this->sitemapLanguageLock = GeneralUtility::getRootSettingValue('is_sitemap_language_lock', false);
|
||||
$this->languageId = GeneralUtility::getLanguageId();
|
||||
|
||||
// ###############################
|
||||
// Fetch robots.txt content
|
||||
// ###############################
|
||||
$settings['robotstxt'] = trim($settings['robotstxt']);
|
||||
|
||||
if (!empty($settings['robotstxt'])) {
|
||||
// Custom Robots.txt
|
||||
$ret .= $settings['robotstxt'];
|
||||
} elseif ($this->tsSetupSeo) {
|
||||
// Default robots.txt
|
||||
$ret .= $this->cObj->cObjGetSingle($this->tsSetupSeo['default'], $this->tsSetupSeo['default.']);
|
||||
}
|
||||
|
||||
// ###############################
|
||||
// Fetch extra robots.txt content
|
||||
// ###############################
|
||||
// User additional
|
||||
if (!empty($settings['robotstxt_additional'])) {
|
||||
$ret .= "\n\n" . $settings['robotstxt_additional'];
|
||||
}
|
||||
|
||||
// Setup additional
|
||||
if ($this->tsSetupSeo) {
|
||||
// Default robots.txt
|
||||
$tmp = $this->cObj->cObjGetSingle($this->tsSetupSeo['extra'], $this->tsSetupSeo['extra.']);
|
||||
|
||||
if (!empty($tmp)) {
|
||||
$ret .= "\n\n" . $tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// ###############################
|
||||
// Marker
|
||||
// ###############################
|
||||
if (!empty($this->tsSetupSeo['marker.'])) {
|
||||
$ret = $this->applyMarker($ret);
|
||||
}
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'robotsTxtOutput', $this, $ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply marker to robots.txt
|
||||
*
|
||||
* @param string $robotsTxt Content of robots.txt
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function applyMarker($robotsTxt)
|
||||
{
|
||||
$ret = $robotsTxt;
|
||||
|
||||
$markerList = array();
|
||||
$markerConfList = array();
|
||||
|
||||
foreach ($this->tsSetupSeo['marker.'] as $name => $data) {
|
||||
if (strpos($name, '.') === false) {
|
||||
$markerConfList[$name] = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->linkToStaticSitemap) {
|
||||
// remove sitemap-marker because we link to static url
|
||||
unset($markerConfList['sitemap']);
|
||||
}
|
||||
|
||||
// Fetch marker content
|
||||
foreach ($markerConfList as $name => $conf) {
|
||||
$markerList['%' . $name . '%'] = $this->cObj->cObjGetSingle(
|
||||
$this->tsSetupSeo['marker.'][$name],
|
||||
$this->tsSetupSeo['marker.'][$name . '.']
|
||||
);
|
||||
}
|
||||
|
||||
// generate sitemap-static marker
|
||||
if ($this->linkToStaticSitemap) {
|
||||
if ($this->sitemapLanguageLock) {
|
||||
$path = 'uploads/tx_metaseo/sitemap_xml/index-r' . (int)$this->rootPid . '-l'
|
||||
. (int)$this->languageId . '.xml.gz';
|
||||
} else {
|
||||
$path = 'uploads/tx_metaseo/sitemap_xml/index-r' . (int)$this->rootPid . '.xml.gz';
|
||||
}
|
||||
|
||||
$conf = array(
|
||||
'parameter' => $path
|
||||
);
|
||||
|
||||
$markerList['%sitemap%'] = $this->cObj->typolink_URL($conf);
|
||||
}
|
||||
|
||||
// Fix sitemap-marker url (add prefix if needed)
|
||||
$markerList['%sitemap%'] = GeneralUtility::fullUrl($markerList['%sitemap%']);
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'robotsTxtMarker', $this, $markerList);
|
||||
|
||||
// Apply marker list
|
||||
if (!empty($markerList)) {
|
||||
$ret = strtr($ret, $markerList);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
80
typo3conf/ext/metaseo/Classes/Page/SitemapTxtPage.php
Normal file
80
typo3conf/ext/metaseo/Classes/Page/SitemapTxtPage.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Page;
|
||||
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Sitemap txt page
|
||||
*/
|
||||
class SitemapTxtPage extends AbstractPage
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Build sitemap xml
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function main()
|
||||
{
|
||||
// INIT
|
||||
$this->tsSetup = $GLOBALS['TSFE']->tmpl->setup['plugin.']['metaseo.']['sitemap.'];
|
||||
|
||||
// check if sitemap is enabled in root
|
||||
if (!GeneralUtility::getRootSettingValue('is_sitemap', true)) {
|
||||
$this->showError('Sitemap is not available, please check your configuration [control-center]');
|
||||
}
|
||||
|
||||
$ret = $this->build();
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build sitemap index or specific page
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function build()
|
||||
{
|
||||
/** @var \Metaseo\Metaseo\Sitemap\Generator\TxtGenerator $generator */
|
||||
$generator = $this->objectManager->get('Metaseo\\Metaseo\\Sitemap\\Generator\\TxtGenerator');
|
||||
|
||||
$ret = $generator->sitemap();
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
87
typo3conf/ext/metaseo/Classes/Page/SitemapXmlPage.php
Normal file
87
typo3conf/ext/metaseo/Classes/Page/SitemapXmlPage.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Page;
|
||||
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
|
||||
/**
|
||||
* Sitemap xml page
|
||||
*/
|
||||
class SitemapXmlPage extends AbstractPage
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Build sitemap xml
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function main()
|
||||
{
|
||||
// INIT
|
||||
$this->tsSetup = $GLOBALS['TSFE']->tmpl->setup['plugin.']['metaseo.']['sitemap.'];
|
||||
|
||||
// check if sitemap is enabled in root
|
||||
if (!GeneralUtility::getRootSettingValue('is_sitemap', true)) {
|
||||
$this->showError('Sitemap is not available, please check your configuration [control-center]');
|
||||
}
|
||||
|
||||
$ret = $this->build();
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build sitemap index or specific page
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function build()
|
||||
{
|
||||
$page = Typo3GeneralUtility::_GP('page');
|
||||
|
||||
/** @var \Metaseo\Metaseo\Sitemap\Generator\XmlGenerator $generator */
|
||||
$generator = $this->objectManager->get('Metaseo\\Metaseo\\Sitemap\\Generator\\XmlGenerator');
|
||||
|
||||
if (empty($page) || $page === 'index') {
|
||||
$ret = $generator->sitemapIndex();
|
||||
} else {
|
||||
$ret = $generator->sitemap($page);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Scheduler\Task;
|
||||
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
|
||||
/**
|
||||
* Scheduler Task Sitemap Base
|
||||
*/
|
||||
abstract class AbstractSitemapTask extends AbstractTask
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Sitemap base directory
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sitemapDir;
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Execute task
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
// Build sitemap
|
||||
|
||||
$this->initialize();
|
||||
$rootPageList = $this->getRootPages();
|
||||
$this->cleanupDirectory();
|
||||
$this->initLanguages();
|
||||
|
||||
foreach ($rootPageList as $uid => $page) {
|
||||
$this->initRootPage($uid);
|
||||
|
||||
if (GeneralUtility::getRootSettingValue('is_sitemap_language_lock', false, $uid)) {
|
||||
foreach ($this->languageIdList as $languageId) {
|
||||
$this->setRootPageLanguage($languageId);
|
||||
$this->buildSitemap($uid, $languageId);
|
||||
}
|
||||
} else {
|
||||
$this->buildSitemap($uid, null);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup sitemap directory
|
||||
*/
|
||||
protected function cleanupDirectory()
|
||||
{
|
||||
if (empty($this->sitemapDir)) {
|
||||
throw new \Exception('Basedir not set');
|
||||
}
|
||||
|
||||
$fullPath = PATH_site . '/' . $this->sitemapDir;
|
||||
|
||||
if (!is_dir($fullPath)) {
|
||||
Typo3GeneralUtility::mkdir($fullPath);
|
||||
}
|
||||
|
||||
foreach (new \DirectoryIterator($fullPath) as $file) {
|
||||
if ($file->isFile() && !$file->isDot()) {
|
||||
$fileName = $file->getFilename();
|
||||
unlink($fullPath . '/' . $fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build sitemap
|
||||
*
|
||||
* @param integer $rootPageId Root page id
|
||||
* @param integer $languageId Language id
|
||||
*/
|
||||
abstract protected function buildSitemap($rootPageId, $languageId);
|
||||
|
||||
|
||||
// ########################################################################
|
||||
// Abstract Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Generate sitemap link template
|
||||
*
|
||||
* @param string $template File link template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function generateSitemapLinkTemplate($template)
|
||||
{
|
||||
$ret = null;
|
||||
|
||||
// Set link template for index file
|
||||
$linkConf = array(
|
||||
'parameter' => $this->sitemapDir . '/' . $template,
|
||||
);
|
||||
|
||||
if (strlen($GLOBALS['TSFE']->baseUrl) > 1) {
|
||||
$ret = $GLOBALS['TSFE']->baseUrlWrap($GLOBALS['TSFE']->cObj->typoLink_URL($linkConf));
|
||||
} elseif (strlen($GLOBALS['TSFE']->absRefPrefix) > 1) {
|
||||
$ret = $GLOBALS['TSFE']->absRefPrefix . $GLOBALS['TSFE']->cObj->typoLink_URL($linkConf);
|
||||
} else {
|
||||
$ret = $GLOBALS['TSFE']->cObj->typoLink_URL($linkConf);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
154
typo3conf/ext/metaseo/Classes/Scheduler/Task/AbstractTask.php
Normal file
154
typo3conf/ext/metaseo/Classes/Scheduler/Task/AbstractTask.php
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Scheduler\Task;
|
||||
|
||||
use Metaseo\Metaseo\Utility\DatabaseUtility;
|
||||
use Metaseo\Metaseo\Utility\FrontendUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Scheduler Task Sitemap Base
|
||||
*/
|
||||
abstract class AbstractTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Backend Form Protection object
|
||||
*
|
||||
* @var \TYPO3\CMS\Extbase\Object\ObjectManager
|
||||
* @inject
|
||||
*/
|
||||
protected $objectManager;
|
||||
|
||||
/**
|
||||
* Language lock
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $languageLock;
|
||||
|
||||
/**
|
||||
* Language list
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $languageIdList;
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Initialize task
|
||||
*/
|
||||
protected function initialize()
|
||||
{
|
||||
$this->objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of root pages in current typo3
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getRootPages()
|
||||
{
|
||||
$query = 'SELECT uid
|
||||
FROM pages
|
||||
WHERE is_siteroot = 1
|
||||
AND deleted = 0';
|
||||
|
||||
return DatabaseUtility::getColWithIndex($query);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get list of root pages in current typo3
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function initLanguages()
|
||||
{
|
||||
$this->languageIdList[0] = 0;
|
||||
|
||||
$query = 'SELECT uid
|
||||
FROM sys_language
|
||||
WHERE hidden = 0';
|
||||
$langIdList = DatabaseUtility::getColWithIndex($query);
|
||||
|
||||
$this->languageIdList = $langIdList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set root page language
|
||||
*
|
||||
* @param integer $languageId
|
||||
*/
|
||||
protected function setRootPageLanguage($languageId)
|
||||
{
|
||||
$GLOBALS['TSFE']->tmpl->setup['config.']['sys_language_uid'] = $languageId;
|
||||
$this->languageLock = $languageId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize root page (TSFE and stuff)
|
||||
*
|
||||
* @param integer $rootPageId $rootPageId
|
||||
*/
|
||||
protected function initRootPage($rootPageId)
|
||||
{
|
||||
FrontendUtility::init($rootPageId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write content to file
|
||||
*
|
||||
* @param string $file Filename/path
|
||||
* @param string $content Content
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function writeToFile($file, $content)
|
||||
{
|
||||
if (!function_exists('gzopen')) {
|
||||
throw new \Exception('metaseo needs zlib support');
|
||||
}
|
||||
|
||||
$fp = gzopen($file, 'w');
|
||||
|
||||
if ($fp) {
|
||||
gzwrite($fp, $content);
|
||||
gzclose($fp);
|
||||
} else {
|
||||
throw new \Exception('Could not open ' . $file . ' for writing');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Scheduler\Task;
|
||||
|
||||
use Metaseo\Metaseo\Utility\SitemapUtility;
|
||||
use TYPO3\CMS\Scheduler\Task\AbstractTask as Typo3AbstractTask;
|
||||
|
||||
/**
|
||||
* Scheduler Task Garbage Collection
|
||||
*/
|
||||
class GarbageCollectionTask extends Typo3AbstractTask
|
||||
{
|
||||
|
||||
/**
|
||||
* Execute task
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
// Expire sitemap entries
|
||||
SitemapUtility::expire();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Scheduler\Task;
|
||||
|
||||
/**
|
||||
* Scheduler Task Sitemap TXT
|
||||
*/
|
||||
class SitemapTxtTask extends AbstractSitemapTask
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Sitemap base directory
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sitemapDir = 'uploads/tx_metaseo/sitemap_txt';
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Build sitemap
|
||||
*
|
||||
* @param integer $rootPageId Root page id
|
||||
* @param integer $languageId Language id
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function buildSitemap($rootPageId, $languageId)
|
||||
{
|
||||
|
||||
if ($languageId !== null) {
|
||||
// Language lock enabled
|
||||
$sitemapFileName = 'sitemap-r%s-l%s.txt.gz';
|
||||
} else {
|
||||
$sitemapFileName = 'sitemap-r%s.txt.gz';
|
||||
}
|
||||
|
||||
$generator = $this->objectManager->get('Metaseo\\Metaseo\\Sitemap\\Generator\\TxtGenerator');
|
||||
$content = $generator->sitemap();
|
||||
|
||||
$fileName = sprintf($sitemapFileName, $rootPageId, $languageId);
|
||||
$this->writeToFile(PATH_site . '/' . $this->sitemapDir . '/' . $fileName, $content);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Scheduler\Task;
|
||||
|
||||
/**
|
||||
* Scheduler Task Sitemap XML
|
||||
*/
|
||||
class SitemapXmlTask extends AbstractSitemapTask
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Sitemap base directory
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sitemapDir = 'uploads/tx_metaseo/sitemap_xml';
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Build sitemap
|
||||
*
|
||||
* @param integer $rootPageId Root page id
|
||||
* @param integer $languageId Language id
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
protected function buildSitemap($rootPageId, $languageId)
|
||||
{
|
||||
if ($languageId !== null) {
|
||||
// Language lock enabled
|
||||
$rootPageLinkTemplate = 'sitemap-r%s-l%s-p###PAGE###.xml.gz';
|
||||
$sitemapIndexFileName = 'index-r%s-l%s.xml.gz';
|
||||
$sitemapPageFileName = 'sitemap-r%s-l%s-p%s.xml.gz';
|
||||
} else {
|
||||
$rootPageLinkTemplate = 'sitemap-r%s-p###PAGE###.xml.gz';
|
||||
$sitemapIndexFileName = 'index-r%s.xml.gz';
|
||||
$sitemapPageFileName = 'sitemap-r%s-p%3$s.xml.gz';
|
||||
}
|
||||
|
||||
// Init builder
|
||||
$generator = $this->objectManager->get('Metaseo\\Metaseo\\Sitemap\\Generator\\XmlGenerator');
|
||||
$fileName = sprintf($rootPageLinkTemplate, $rootPageId, $languageId);
|
||||
|
||||
$generator->indexPathTemplate = $this->generateSitemapLinkTemplate($fileName);
|
||||
|
||||
// Get list of pages
|
||||
$pageCount = $generator->pageCount();
|
||||
|
||||
// Index
|
||||
$content = $generator->sitemapIndex();
|
||||
$fileName = sprintf($sitemapIndexFileName, $rootPageId, $languageId);
|
||||
$this->writeToFile(PATH_site . '/' . $this->sitemapDir . '/' . $fileName, $content);
|
||||
|
||||
// Page
|
||||
for ($i = 0; $i < $pageCount; $i++) {
|
||||
$content = $generator->sitemap($i);
|
||||
$fileName = sprintf($sitemapPageFileName, $rootPageId, $languageId, $i);
|
||||
$this->writeToFile(PATH_site . '/' . $this->sitemapDir . '/' . $fileName, $content);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Sitemap\Generator;
|
||||
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
use Metaseo\Metaseo\Utility\SitemapUtility;
|
||||
|
||||
/**
|
||||
* Sitemap abstract generator
|
||||
*/
|
||||
abstract class AbstractGenerator
|
||||
{
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Current root pid
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
public $rootPid;
|
||||
|
||||
/**
|
||||
* Sitemap pages
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $sitemapPages = array();
|
||||
|
||||
/**
|
||||
* Page lookups
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $pages = array();
|
||||
/**
|
||||
* Extension setup configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $tsSetup = array();
|
||||
/**
|
||||
* Page change frequency definition list
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $pageChangeFrequency = array(
|
||||
1 => 'always',
|
||||
2 => 'hourly',
|
||||
3 => 'daily',
|
||||
4 => 'weekly',
|
||||
5 => 'monthly',
|
||||
6 => 'yearly',
|
||||
7 => 'never',
|
||||
);
|
||||
/**
|
||||
* Link template for sitemap index
|
||||
*
|
||||
* Replacement marker ###PAGE### for page-uid
|
||||
*
|
||||
* @var string|boolean
|
||||
*/
|
||||
public $indexPathTemplate = false;
|
||||
/**
|
||||
* Extension configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extConf = array();
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Fetch sitemap information and generate sitemap
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// INIT
|
||||
$this->rootPid = GeneralUtility::getRootPid();
|
||||
$sysLanguageId = null;
|
||||
|
||||
$this->tsSetup = $GLOBALS['TSFE']->tmpl->setup['plugin.']['metaseo.']['sitemap.'];
|
||||
|
||||
// Language limit via setupTS
|
||||
if (GeneralUtility::getRootSettingValue('is_sitemap_language_lock', false)) {
|
||||
$sysLanguageId = GeneralUtility::getLanguageId();
|
||||
}
|
||||
|
||||
// Fetch sitemap list/pages
|
||||
$list = SitemapUtility::getList($this->rootPid, $sysLanguageId);
|
||||
|
||||
$this->sitemapPages = $list['tx_metaseo_sitemap'];
|
||||
$this->pages = $list['pages'];
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'sitemapSetup', $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return page count
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function pageCount()
|
||||
{
|
||||
$pageLimit = GeneralUtility::getRootSettingValue('sitemap_page_limit', null);
|
||||
|
||||
if (empty($pageLimit)) {
|
||||
$pageLimit = 1000;
|
||||
}
|
||||
|
||||
$pageItems = count($this->sitemapPages);
|
||||
$pageCount = ceil($pageItems / $pageLimit);
|
||||
|
||||
return $pageCount;
|
||||
}
|
||||
|
||||
// ########################################################################
|
||||
// Abstract methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Create sitemap index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function sitemapIndex();
|
||||
|
||||
/**
|
||||
* Create sitemap (for page)
|
||||
*
|
||||
* @param integer $page Page
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function sitemap($page = null);
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Sitemap\Generator;
|
||||
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Sitemap TXT generator
|
||||
*/
|
||||
class TxtGenerator extends AbstractGenerator
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Create sitemap index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sitemapIndex()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create sitemap (for page)
|
||||
*
|
||||
* @param integer $page Page
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sitemap($page = null)
|
||||
{
|
||||
$ret = array();
|
||||
|
||||
foreach ($this->sitemapPages as $sitemapPage) {
|
||||
if (empty($this->pages[$sitemapPage['page_uid']])) {
|
||||
// invalid page
|
||||
continue;
|
||||
}
|
||||
|
||||
$ret[] = GeneralUtility::fullUrl($sitemapPage['page_url']);
|
||||
}
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'sitemapTextOutput', $this, $ret);
|
||||
|
||||
return implode("\n", $ret);
|
||||
}
|
||||
}
|
||||
259
typo3conf/ext/metaseo/Classes/Sitemap/Generator/XmlGenerator.php
Normal file
259
typo3conf/ext/metaseo/Classes/Sitemap/Generator/XmlGenerator.php
Normal file
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Sitemap\Generator;
|
||||
|
||||
use Metaseo\Metaseo\Utility\GeneralUtility;
|
||||
|
||||
/**
|
||||
* Sitemap XML generator
|
||||
*/
|
||||
class XmlGenerator extends AbstractGenerator
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Create sitemap index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sitemapIndex()
|
||||
{
|
||||
$pageLimit = 10000;
|
||||
|
||||
if (isset($this->tsSetup['pageLimit']) && $this->tsSetup['pageLimit'] != '') {
|
||||
$pageLimit = (int)$this->tsSetup['pageLimit'];
|
||||
}
|
||||
|
||||
$sitemaps = array();
|
||||
$pageItems = count($this->sitemapPages);
|
||||
$pageCount = ceil($pageItems / $pageLimit);
|
||||
|
||||
$linkConf = array(
|
||||
'parameter' => GeneralUtility::getCurrentPid() . ',' . $GLOBALS['TSFE']->type,
|
||||
'additionalParams' => '',
|
||||
'useCacheHash' => 1,
|
||||
);
|
||||
|
||||
for ($i = 0; $i < $pageCount; $i++) {
|
||||
if ($this->indexPathTemplate) {
|
||||
$link = GeneralUtility::fullUrl(str_replace('###PAGE###', $i, $this->indexPathTemplate));
|
||||
|
||||
$sitemaps[] = $link;
|
||||
} else {
|
||||
$linkConf['additionalParams'] = '&page=' . ($i + 1);
|
||||
|
||||
$sitemaps[] = GeneralUtility::fullUrl($GLOBALS['TSFE']->cObj->typoLink_URL($linkConf));
|
||||
}
|
||||
}
|
||||
|
||||
$ret = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$ret .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" '
|
||||
. 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
|
||||
$ret .= ' xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 '
|
||||
. 'http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">';
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'sitemapXmlIndexSitemapList', $this, $sitemaps);
|
||||
|
||||
foreach ($sitemaps as $sitemapPage) {
|
||||
$ret .= '<sitemap><loc>' . htmlspecialchars($sitemapPage) . '</loc></sitemap>';
|
||||
}
|
||||
|
||||
$ret .= '</sitemapindex>';
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'sitemapXmlIndexOutput', $this, $ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create sitemap (for page)
|
||||
*
|
||||
* @param integer $page Page
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function sitemap($page = null)
|
||||
{
|
||||
$ret = '';
|
||||
|
||||
$pageLimit = 10000;
|
||||
|
||||
if (isset($this->tsSetup['pageLimit']) && $this->tsSetup['pageLimit'] != '') {
|
||||
$pageLimit = (int)$this->tsSetup['pageLimit'];
|
||||
}
|
||||
|
||||
$pageItems = count($this->sitemapPages);
|
||||
$pageItemBegin = $pageLimit * ($page - 1);
|
||||
|
||||
if ($pageItemBegin <= $pageItems) {
|
||||
$this->sitemapPages = array_slice($this->sitemapPages, $pageItemBegin, $pageLimit);
|
||||
|
||||
$ret = $this->createSitemapPage();
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Sitemap Page
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function createSitemapPage()
|
||||
{
|
||||
$ret = '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
$ret .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"';
|
||||
$ret .= ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
|
||||
$ret .= ' xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9';
|
||||
$ret .= ' http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">';
|
||||
|
||||
$pagePriorityDefaultValue = (float)GeneralUtility::getRootSettingValue('sitemap_priorty', 0);
|
||||
$pagePriorityDepthMultiplier = (float)GeneralUtility::getRootSettingValue(
|
||||
'sitemap_priorty_depth_multiplier',
|
||||
0
|
||||
);
|
||||
$pagePriorityDepthModificator = (float)GeneralUtility::getRootSettingValue(
|
||||
'sitemap_priorty_depth_modificator',
|
||||
0
|
||||
);
|
||||
|
||||
if ($pagePriorityDefaultValue == 0) {
|
||||
$pagePriorityDefaultValue = 1;
|
||||
}
|
||||
|
||||
if ($pagePriorityDepthMultiplier == 0) {
|
||||
$pagePriorityDepthMultiplier = 1;
|
||||
}
|
||||
|
||||
if ($pagePriorityDepthModificator == 0) {
|
||||
$pagePriorityDepthModificator = 1;
|
||||
}
|
||||
|
||||
|
||||
// #####################
|
||||
// SetupTS conf
|
||||
// #####################
|
||||
|
||||
foreach ($this->sitemapPages as $sitemapPage) {
|
||||
if (empty($this->pages[$sitemapPage['page_uid']])) {
|
||||
// invalid page
|
||||
continue;
|
||||
}
|
||||
|
||||
$page = $this->pages[$sitemapPage['page_uid']];
|
||||
|
||||
// #####################################
|
||||
// Page priority
|
||||
// #####################################
|
||||
$pageDepth = $sitemapPage['page_depth'];
|
||||
$pageDepthBase = 1;
|
||||
|
||||
if (!empty($sitemapPage['page_hash'])) {
|
||||
// page has module-content - trade as subpage
|
||||
++$pageDepth;
|
||||
}
|
||||
|
||||
$pageDepth -= $pagePriorityDepthModificator;
|
||||
|
||||
|
||||
if ($pageDepth > 0.1) {
|
||||
$pageDepthBase = 1 / $pageDepth;
|
||||
}
|
||||
|
||||
$pagePriority = $pagePriorityDefaultValue * ($pageDepthBase * $pagePriorityDepthMultiplier);
|
||||
if (!empty($page['tx_metaseo_priority'])) {
|
||||
$pagePriority = $page['tx_metaseo_priority'] / 100;
|
||||
}
|
||||
|
||||
$pagePriority = number_format($pagePriority, 2);
|
||||
|
||||
if ($pagePriority > 1) {
|
||||
$pagePriority = '1.00';
|
||||
} elseif ($pagePriority <= 0) {
|
||||
$pagePriority = '0.00';
|
||||
}
|
||||
|
||||
// #####################################
|
||||
// Page information
|
||||
// #####################################
|
||||
|
||||
// page Url
|
||||
$pageUrl = GeneralUtility::fullUrl($sitemapPage['page_url']);
|
||||
|
||||
// Page modification date
|
||||
$pageModificationDate = date('c', $sitemapPage['tstamp']);
|
||||
|
||||
// Page change frequency
|
||||
$pageChangeFrequency = null;
|
||||
if (!empty($page['tx_metaseo_change_frequency'])) {
|
||||
// from page
|
||||
$pageChangeFrequency = (int)$page['tx_metaseo_change_frequency'];
|
||||
} elseif (!empty($sitemapPage['page_change_frequency'])) {
|
||||
// from sitemap settings
|
||||
$pageChangeFrequency = (int)$sitemapPage['page_change_frequency'];
|
||||
} elseif (!empty($this->tsSetup['changeFrequency'])) {
|
||||
// default from SetupTS
|
||||
$pageChangeFrequency = (int)$this->tsSetup['changeFrequency'];
|
||||
}
|
||||
|
||||
// translate change frequency
|
||||
if (!empty($pageChangeFrequency) && !empty($this->pageChangeFrequency[$pageChangeFrequency])) {
|
||||
$pageChangeFrequency = $this->pageChangeFrequency[$pageChangeFrequency];
|
||||
} else {
|
||||
$pageChangeFrequency = null;
|
||||
}
|
||||
|
||||
// #####################################
|
||||
// Sitemal page output
|
||||
// #####################################
|
||||
$ret .= '<url>';
|
||||
$ret .= '<loc>' . htmlspecialchars($pageUrl) . '</loc>';
|
||||
$ret .= '<lastmod>' . $pageModificationDate . '</lastmod>';
|
||||
|
||||
if (!empty($pageChangeFrequency)) {
|
||||
$ret .= '<changefreq>' . htmlspecialchars($pageChangeFrequency) . '</changefreq>';
|
||||
}
|
||||
|
||||
$ret .= '<priority>' . $pagePriority . '</priority>';
|
||||
|
||||
$ret .= '</url>';
|
||||
}
|
||||
|
||||
|
||||
$ret .= '</urlset>';
|
||||
|
||||
// Call hook
|
||||
GeneralUtility::callHookAndSignal(__CLASS__, 'sitemapXmlPageOutput', $this, $ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
79
typo3conf/ext/metaseo/Classes/Utility/BackendUtility.php
Normal file
79
typo3conf/ext/metaseo/Classes/Utility/BackendUtility.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Utility;
|
||||
|
||||
/**
|
||||
* Backend utility
|
||||
*/
|
||||
class BackendUtility
|
||||
{
|
||||
|
||||
/**
|
||||
* Fetch list of root pages (is_siteroot) in TYPO3 (cached)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getRootPageList()
|
||||
{
|
||||
static $cache = null;
|
||||
|
||||
if ($cache === null) {
|
||||
$query = 'SELECT uid,
|
||||
pid,
|
||||
title
|
||||
FROM pages
|
||||
WHERE is_siteroot = 1
|
||||
AND deleted = 0';
|
||||
$cache = DatabaseUtility::getAllWithIndex($query, 'uid');
|
||||
}
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch list of setting entries
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getRootPageSettingList()
|
||||
{
|
||||
static $cache = null;
|
||||
|
||||
if ($cache === null) {
|
||||
$query = 'SELECT seosr.*
|
||||
FROM tx_metaseo_setting_root seosr
|
||||
INNER JOIN pages p
|
||||
ON p.uid = seosr.pid
|
||||
AND p.is_siteroot = 1
|
||||
AND p.deleted = 0
|
||||
WHERE seosr.deleted = 0';
|
||||
$cache = DatabaseUtility::getAllWithIndex($query, 'pid');
|
||||
}
|
||||
|
||||
return $cache;
|
||||
}
|
||||
}
|
||||
122
typo3conf/ext/metaseo/Classes/Utility/ConsoleUtility.php
Normal file
122
typo3conf/ext/metaseo/Classes/Utility/ConsoleUtility.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Utility;
|
||||
|
||||
/**
|
||||
* Console utility
|
||||
*/
|
||||
class ConsoleUtility
|
||||
{
|
||||
|
||||
/**
|
||||
* Write output (without forcing newline)
|
||||
*
|
||||
* @param string $message Message text
|
||||
* @param integer $padding Pad message
|
||||
*/
|
||||
public static function write($message = null, $padding = null)
|
||||
{
|
||||
if ($padding > 0) {
|
||||
$message = str_pad($message, $padding, ' ');
|
||||
}
|
||||
|
||||
self::stdOut($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send output to STD_OUT
|
||||
*
|
||||
* @param string $message Message text
|
||||
*/
|
||||
public static function stdOut($message = null)
|
||||
{
|
||||
if (defined('TYPO3_cliMode')) {
|
||||
file_put_contents('php://stdout', $message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write output (forcing newline)
|
||||
*
|
||||
* @param string $message Message text
|
||||
*/
|
||||
public static function writeLine($message = null)
|
||||
{
|
||||
self::stdOut($message . "\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Write error (without forcing newline)
|
||||
*
|
||||
* @param string $message Message text
|
||||
* @param integer $padding Pad message
|
||||
*/
|
||||
public static function writeError($message = null, $padding = null)
|
||||
{
|
||||
if ($padding > 0) {
|
||||
$message = str_pad($message, $padding, ' ');
|
||||
}
|
||||
|
||||
self::stdError($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send output to STD_ERR
|
||||
*
|
||||
* @param string $message Message text
|
||||
*/
|
||||
public static function stdError($message = null)
|
||||
{
|
||||
if (defined('TYPO3_cliMode')) {
|
||||
file_put_contents('php://stderr', $message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write error (forcing newline)
|
||||
*
|
||||
* @param string $message Message
|
||||
*/
|
||||
public static function writeErrorLine($message = null)
|
||||
{
|
||||
$message .= "\n";
|
||||
|
||||
self::stdError($message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit cli script with return code
|
||||
*
|
||||
* @param integer $exitCode Exit code (0 = success)
|
||||
*/
|
||||
public static function terminate($exitCode)
|
||||
{
|
||||
if (defined('TYPO3_cliMode')) {
|
||||
exit($exitCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
456
typo3conf/ext/metaseo/Classes/Utility/DatabaseUtility.php
Normal file
456
typo3conf/ext/metaseo/Classes/Utility/DatabaseUtility.php
Normal file
@@ -0,0 +1,456 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Utility;
|
||||
|
||||
/**
|
||||
* Database utility
|
||||
*/
|
||||
class DatabaseUtility
|
||||
{
|
||||
|
||||
/**
|
||||
* relation we know of that it exists and which we can use for database vendor determination
|
||||
*/
|
||||
const TYPO3_DEFAULT_TABLE = 'pages';
|
||||
|
||||
###########################################################################
|
||||
# Query functions
|
||||
###########################################################################
|
||||
|
||||
/**
|
||||
* Get row
|
||||
*
|
||||
* @param string $query SQL query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getRow($query)
|
||||
{
|
||||
$ret = null;
|
||||
|
||||
$res = self::query($query);
|
||||
if ($res) {
|
||||
if ($row = self::connection()->sql_fetch_assoc($res)) {
|
||||
$ret = $row;
|
||||
}
|
||||
self::free($res);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute sql query
|
||||
*
|
||||
* @param string $query SQL query
|
||||
*
|
||||
* @return \mysqli_result
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function query($query)
|
||||
{
|
||||
$res = self::connection()->sql_query($query);
|
||||
|
||||
if (!$res || self::connection()->sql_errno()) {
|
||||
// SQL statement failed
|
||||
$errorMsg = sprintf(
|
||||
'SQL Error: %s [errno: %s]',
|
||||
self::connection()->sql_error(),
|
||||
self::connection()->sql_errno()
|
||||
);
|
||||
|
||||
if (defined('TYPO3_cliMode')) {
|
||||
throw new \Exception($errorMsg);
|
||||
} else {
|
||||
debug('SQL-QUERY: ' . $query, $errorMsg, __LINE__, __FILE__);
|
||||
}
|
||||
|
||||
$res = null;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current database connection
|
||||
*
|
||||
* @return \TYPO3\CMS\Core\Database\DatabaseConnection
|
||||
*/
|
||||
public static function connection()
|
||||
{
|
||||
return $GLOBALS['TYPO3_DB'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Free sql result
|
||||
*
|
||||
* @param boolean|\mysqli_result|object $res SQL result
|
||||
*/
|
||||
public static function free($res)
|
||||
{
|
||||
if ($res && $res !== true) {
|
||||
self::connection()->sql_free_result($res);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get All
|
||||
*
|
||||
* @param string $query SQL query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getAll($query)
|
||||
{
|
||||
$ret = array();
|
||||
|
||||
$res = self::query($query);
|
||||
if ($res) {
|
||||
while ($row = self::connection()->sql_fetch_assoc($res)) {
|
||||
$ret[] = $row;
|
||||
}
|
||||
self::free($res);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get All with index (first value)
|
||||
*
|
||||
* @param string $query SQL query
|
||||
* @param string $indexCol Index column name
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getAllWithIndex($query, $indexCol = null)
|
||||
{
|
||||
$ret = array();
|
||||
|
||||
$res = self::query($query);
|
||||
if ($res) {
|
||||
while ($row = self::connection()->sql_fetch_assoc($res)) {
|
||||
if ($indexCol === null) {
|
||||
// use first key as index
|
||||
$index = reset($row);
|
||||
} else {
|
||||
$index = $row[$indexCol];
|
||||
}
|
||||
|
||||
$ret[$index] = $row;
|
||||
}
|
||||
self::free($res);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get List
|
||||
*
|
||||
* @param string $query SQL query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getList($query)
|
||||
{
|
||||
$ret = array();
|
||||
|
||||
$res = self::query($query);
|
||||
if ($res) {
|
||||
while ($row = self::connection()->sql_fetch_row($res)) {
|
||||
$ret[$row[0]] = $row[1];
|
||||
}
|
||||
self::free($res);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column
|
||||
*
|
||||
* @param string $query SQL query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getCol($query)
|
||||
{
|
||||
$ret = array();
|
||||
|
||||
$res = self::query($query);
|
||||
if ($res) {
|
||||
while ($row = self::connection()->sql_fetch_row($res)) {
|
||||
$ret[] = $row[0];
|
||||
}
|
||||
self::free($res);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column
|
||||
*
|
||||
* @param string $query SQL query
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getColWithIndex($query)
|
||||
{
|
||||
$ret = array();
|
||||
|
||||
$res = self::query($query);
|
||||
if ($res) {
|
||||
while ($row = self::connection()->sql_fetch_row($res)) {
|
||||
$ret[$row[0]] = $row[0];
|
||||
}
|
||||
self::free($res);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get count (from query)
|
||||
*
|
||||
* @param string $query SQL query
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public static function getCount($query)
|
||||
{
|
||||
$query = 'SELECT COUNT(*) FROM (' . $query . ') tmp';
|
||||
|
||||
return self::getOne($query);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Quote functions
|
||||
###########################################################################
|
||||
|
||||
/**
|
||||
* Get one
|
||||
*
|
||||
* @param string $query SQL query
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getOne($query)
|
||||
{
|
||||
$ret = null;
|
||||
|
||||
$res = self::query($query);
|
||||
if ($res) {
|
||||
if ($row = self::connection()->sql_fetch_assoc($res)) {
|
||||
$ret = reset($row);
|
||||
}
|
||||
self::free($res);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exec query (INSERT)
|
||||
*
|
||||
* @param string $query SQL query
|
||||
*
|
||||
* @return integer Last insert id
|
||||
*/
|
||||
public static function execInsert($query)
|
||||
{
|
||||
$ret = false;
|
||||
|
||||
$res = self::query($query);
|
||||
|
||||
if ($res) {
|
||||
$ret = self::connection()->sql_insert_id();
|
||||
self::free($res);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exec query (DELETE, UPDATE etc)
|
||||
*
|
||||
* @param string $query SQL query
|
||||
*
|
||||
* @return integer Affected rows
|
||||
*/
|
||||
public static function exec($query)
|
||||
{
|
||||
$ret = false;
|
||||
|
||||
$res = self::query($query);
|
||||
|
||||
if ($res) {
|
||||
$ret = self::connection()->sql_affected_rows();
|
||||
self::free($res);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Helper functions
|
||||
###########################################################################
|
||||
|
||||
/**
|
||||
* Add condition to query
|
||||
*
|
||||
* @param array|string $condition Condition
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function addCondition($condition)
|
||||
{
|
||||
$ret = ' ';
|
||||
|
||||
if (!empty($condition)) {
|
||||
if (is_array($condition)) {
|
||||
$ret .= ' AND (( ' . implode(" )\nAND (", $condition) . ' ))';
|
||||
} else {
|
||||
$ret .= ' AND ( ' . $condition . ' )';
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create condition 'field IN (1,2,3,4)'
|
||||
*
|
||||
* @param string $field SQL field
|
||||
* @param array $values Values
|
||||
* @param boolean $required Required
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function conditionIn($field, array $values, $required = true)
|
||||
{
|
||||
return self::buildConditionIn($field, $values, $required, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create condition 'field NOT IN (1,2,3,4)'
|
||||
*
|
||||
* @param string $field SQL field
|
||||
* @param array $values Values
|
||||
* @param boolean $required Required
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function conditionNotIn($field, array $values, $required = true)
|
||||
{
|
||||
return self::buildConditionIn($field, $values, $required, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create condition 'field [NOT] IN (1,2,3,4)'
|
||||
*
|
||||
* @param string $field SQL field
|
||||
* @param array $values Values
|
||||
* @param boolean $required Required
|
||||
* @param boolean $negate use true for a NOT IN clause, use false for an IN clause (default)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function buildConditionIn($field, array $values, $required = true, $negate = false)
|
||||
{
|
||||
if (empty($values)) {
|
||||
return $required ? '1=0' : '1=1';
|
||||
}
|
||||
|
||||
$not = $negate ? ' NOT' : '';
|
||||
$quotedValues = self::quoteArray($values);
|
||||
|
||||
return $field . $not . ' IN (' . implode(',', $quotedValues) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Quote array with values
|
||||
*
|
||||
* @param array $valueList Values
|
||||
* @param string $table Table
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function quoteArray(array $valueList, $table = null)
|
||||
{
|
||||
$ret = array();
|
||||
foreach ($valueList as $k => $v) {
|
||||
$ret[$k] = self::quote($v, $table);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# SQL wrapper functions
|
||||
###########################################################################
|
||||
|
||||
/**
|
||||
* Quote value
|
||||
*
|
||||
* @param string $value Value
|
||||
* @param string $table Table
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function quote($value, $table = null)
|
||||
{
|
||||
if ($table === null) {
|
||||
$table = self::TYPO3_DEFAULT_TABLE;
|
||||
}
|
||||
|
||||
if ($value === null) {
|
||||
return 'NULL';
|
||||
}
|
||||
|
||||
return self::connection()->fullQuoteStr($value, $table);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build condition
|
||||
*
|
||||
* @param array $where Where condition
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function buildCondition(array $where)
|
||||
{
|
||||
$ret = ' ';
|
||||
|
||||
if (!empty($where)) {
|
||||
$ret = ' ( ' . implode(' ) AND ( ', $where) . ' ) ';
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Utility;
|
||||
|
||||
use ReflectionMethod;
|
||||
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility as Typo3ExtensionManagementUtility;
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
|
||||
class ExtensionManagementUtility
|
||||
{
|
||||
const AJAX_METHOD_NAME_SUFFIX = 'Action';
|
||||
const AJAX_METHOD_DELIMITER = '::';
|
||||
|
||||
/**
|
||||
* Registers all public methods of a specified class with method name suffix 'Action' as ajax actions
|
||||
* The ajax method names have the form <ajaxPrefix>::<ajaxMethod> (with 'Action' removed from the method)
|
||||
* or <ajaxMethod> for empty/unspecified <ajaxPrefix>
|
||||
*
|
||||
* @param string $qualifiedClassName
|
||||
* @param string $ajaxPrefix
|
||||
*/
|
||||
public static function registerAjaxClass($qualifiedClassName, $ajaxPrefix = '')
|
||||
{
|
||||
if (!empty($ajaxPrefix)) {
|
||||
$ajaxPrefix = $ajaxPrefix . self::AJAX_METHOD_DELIMITER;
|
||||
}
|
||||
self::removeBeginningBackslash($qualifiedClassName);
|
||||
$reflectionClass = self::getReflectionClass($qualifiedClassName);
|
||||
$methods = $reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC);
|
||||
foreach ($methods as $method) {
|
||||
$methodName = $method->getName();
|
||||
if (self::isAjaxMethod($methodName)) {
|
||||
$ajaxMethodName = self::extractAjaxMethod($methodName);
|
||||
Typo3ExtensionManagementUtility::registerAjaxHandler(
|
||||
$ajaxPrefix . $ajaxMethodName,
|
||||
$qualifiedClassName . '->' . $methodName
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $qualifiedClassNames
|
||||
*/
|
||||
public static function registerAjaxClasses(array $qualifiedClassNames)
|
||||
{
|
||||
foreach ($qualifiedClassNames as $ajaxPrefix => $qualifiedClassName) {
|
||||
self::registerAjaxClass($qualifiedClassName, $ajaxPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $methodName
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function isAjaxMethod($methodName)
|
||||
{
|
||||
$suffixLength = strlen(self::AJAX_METHOD_NAME_SUFFIX);
|
||||
|
||||
return strlen($methodName) > $suffixLength
|
||||
&& self::AJAX_METHOD_NAME_SUFFIX === substr($methodName, -1 * $suffixLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $methodName
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function extractAjaxMethod($methodName)
|
||||
{
|
||||
$suffixLength = strlen(self::AJAX_METHOD_NAME_SUFFIX);
|
||||
|
||||
return substr(
|
||||
$methodName,
|
||||
0,
|
||||
strlen($methodName) - $suffixLength
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $qualifiedClassName
|
||||
*/
|
||||
protected static function removeBeginningBackslash(&$qualifiedClassName)
|
||||
{
|
||||
if ($qualifiedClassName[0] === '\\') {
|
||||
$qualifiedClassName = substr($qualifiedClassName, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $qualifiedClassName
|
||||
*
|
||||
* @return \ReflectionClass
|
||||
*/
|
||||
protected static function getReflectionClass($qualifiedClassName)
|
||||
{
|
||||
return Typo3GeneralUtility::makeInstance('ReflectionClass', $qualifiedClassName);
|
||||
}
|
||||
}
|
||||
212
typo3conf/ext/metaseo/Classes/Utility/FrontendUtility.php
Normal file
212
typo3conf/ext/metaseo/Classes/Utility/FrontendUtility.php
Normal file
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
|
||||
/**
|
||||
* General utility
|
||||
*/
|
||||
class FrontendUtility
|
||||
{
|
||||
|
||||
/**
|
||||
* Init TSFE with all needed classes eg. for backend usage ($GLOBALS['TSFE'])
|
||||
*
|
||||
* @param integer $pageUid PageUID
|
||||
* @param null|array $rootLine Rootline
|
||||
* @param null|array $pageData Page data array
|
||||
* @param null|array $rootlineFull Full rootline
|
||||
* @param null|integer $sysLanguage Sys language uid
|
||||
*/
|
||||
public static function init(
|
||||
$pageUid,
|
||||
$rootLine = null,
|
||||
$pageData = null,
|
||||
$rootlineFull = null,
|
||||
$sysLanguage = null
|
||||
) {
|
||||
static $cacheTSFE = array();
|
||||
static $lastTsSetupPid = null;
|
||||
|
||||
/** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */
|
||||
$objectManager = Typo3GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Extbase\\Object\\ObjectManager'
|
||||
);
|
||||
|
||||
// Fetch page if needed
|
||||
if ($pageData === null) {
|
||||
/** @var \TYPO3\CMS\Frontend\Page\PageRepository $sysPageObj */
|
||||
$sysPageObj = $objectManager->get('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
|
||||
$sysPageObj->sys_language_uid = $sysLanguage;
|
||||
|
||||
$pageData = $sysPageObj->getPage_noCheck($pageUid);
|
||||
}
|
||||
|
||||
// create time tracker if needed
|
||||
if (empty($GLOBALS['TT'])) {
|
||||
/** @var \TYPO3\CMS\Core\TimeTracker\NullTimeTracker $timeTracker */
|
||||
$timeTracker = $objectManager->get('TYPO3\\CMS\\Core\\TimeTracker\\NullTimeTracker');
|
||||
|
||||
$GLOBALS['TT'] = $timeTracker;
|
||||
$GLOBALS['TT']->start();
|
||||
}
|
||||
|
||||
if ($rootLine === null) {
|
||||
/** @var \TYPO3\CMS\Frontend\Page\PageRepository $sysPageObj */
|
||||
$sysPageObj = $objectManager->get('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
|
||||
$sysPageObj->sys_language_uid = $sysLanguage;
|
||||
$rootLine = $sysPageObj->getRootLine($pageUid);
|
||||
|
||||
// save full rootline, we need it in TSFE
|
||||
$rootlineFull = $rootLine;
|
||||
}
|
||||
|
||||
// Only setup tsfe if current instance must be changed
|
||||
if ($lastTsSetupPid !== $pageUid) {
|
||||
// Cache TSFE if possible to prevent reinit (is still slow but we need the TSFE)
|
||||
if (empty($cacheTSFE[$pageUid])) {
|
||||
/** @var \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController $tsfeController */
|
||||
$tsfeController = $objectManager->get(
|
||||
'TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController',
|
||||
$GLOBALS['TYPO3_CONF_VARS'],
|
||||
$pageUid,
|
||||
0
|
||||
);
|
||||
$tsfeController->sys_language_uid = $sysLanguage;
|
||||
|
||||
/** @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObjRenderer */
|
||||
$cObjRenderer = $objectManager->get('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
|
||||
|
||||
/** @var \TYPO3\CMS\Core\TypoScript\ExtendedTemplateService $TSObj */
|
||||
$TSObj = $objectManager->get('TYPO3\\CMS\\Core\\TypoScript\\ExtendedTemplateService');
|
||||
|
||||
$TSObj->tt_track = 0;
|
||||
$TSObj->init();
|
||||
$TSObj->runThroughTemplates($rootLine);
|
||||
$TSObj->generateConfig();
|
||||
|
||||
$_GET['id'] = $pageUid;
|
||||
|
||||
// Init TSFE
|
||||
$GLOBALS['TSFE'] = $tsfeController;
|
||||
$GLOBALS['TSFE']->cObj = $cObjRenderer;
|
||||
$GLOBALS['TSFE']->initFEuser();
|
||||
$GLOBALS['TSFE']->determineId();
|
||||
|
||||
if (empty($GLOBALS['TSFE']->tmpl)) {
|
||||
$GLOBALS['TSFE']->tmpl = new \stdClass();
|
||||
}
|
||||
|
||||
$GLOBALS['TSFE']->tmpl->setup = $TSObj->setup;
|
||||
$GLOBALS['TSFE']->initTemplate();
|
||||
$GLOBALS['TSFE']->getConfigArray();
|
||||
|
||||
$GLOBALS['TSFE']->baseUrl = $GLOBALS['TSFE']->config['config']['baseURL'];
|
||||
|
||||
$cacheTSFE[$pageUid] = $GLOBALS['TSFE'];
|
||||
}
|
||||
|
||||
$GLOBALS['TSFE'] = $cacheTSFE[$pageUid];
|
||||
|
||||
$lastTsSetupPid = $pageUid;
|
||||
}
|
||||
|
||||
$GLOBALS['TSFE']->page = $pageData;
|
||||
$GLOBALS['TSFE']->rootLine = $rootlineFull;
|
||||
$GLOBALS['TSFE']->cObj->data = $pageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check current page for blacklisting
|
||||
*
|
||||
* @param array $blacklist Blacklist configuration
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkPageForBlacklist(array $blacklist)
|
||||
{
|
||||
return GeneralUtility::checkUrlForBlacklisting(self::getCurrentUrl(), $blacklist);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if frontend page is cacheable
|
||||
*
|
||||
* @param array|null $conf Configuration
|
||||
* @return bool
|
||||
*/
|
||||
public static function isCacheable($conf = null)
|
||||
{
|
||||
$TSFE = self::getTsfe();
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'GET' || !empty($TSFE->fe_user->user['uid'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// don't parse if page is not cacheable
|
||||
if (empty($conf['allowNoStaticCachable']) && !$TSFE->isStaticCacheble()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip no_cache-pages
|
||||
if (empty($conf['allowNoCache']) && !empty($TSFE->no_cache)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current URL
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function getCurrentUrl()
|
||||
{
|
||||
$ret = null;
|
||||
|
||||
$TSFE = self::getTsfe();
|
||||
|
||||
if (!empty($TSFE->anchorPrefix)) {
|
||||
$ret = (string)$TSFE->anchorPrefix;
|
||||
} else {
|
||||
$ret = (string)$TSFE->siteScript;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TSFE
|
||||
*
|
||||
* @return \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController
|
||||
*/
|
||||
public static function getTsfe()
|
||||
{
|
||||
return $GLOBALS['TSFE'];
|
||||
}
|
||||
}
|
||||
463
typo3conf/ext/metaseo/Classes/Utility/GeneralUtility.php
Normal file
463
typo3conf/ext/metaseo/Classes/Utility/GeneralUtility.php
Normal file
@@ -0,0 +1,463 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Utility;
|
||||
|
||||
/**
|
||||
* General utility
|
||||
*/
|
||||
class GeneralUtility
|
||||
{
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Page Select
|
||||
*
|
||||
* @var \TYPO3\CMS\Frontend\Page\PageRepository
|
||||
*/
|
||||
protected static $sysPageObj;
|
||||
|
||||
/**
|
||||
* Rootline cache
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $rootlineCache = array();
|
||||
|
||||
|
||||
// ########################################################################
|
||||
// Public methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Get current language id
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public static function getLanguageId()
|
||||
{
|
||||
$ret = 0;
|
||||
|
||||
if (!empty($GLOBALS['TSFE']->tmpl->setup['config.']['sys_language_uid'])) {
|
||||
$ret = (int)$GLOBALS['TSFE']->tmpl->setup['config.']['sys_language_uid'];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current pid
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public static function getCurrentPid()
|
||||
{
|
||||
return $GLOBALS['TSFE']->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is any mountpoint in rootline
|
||||
*
|
||||
* @param integer|null $uid Page UID
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isMountpointInRootLine($uid = null)
|
||||
{
|
||||
$ret = false;
|
||||
|
||||
// Performance check, there must be an MP-GET value
|
||||
if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GET('MP')) {
|
||||
// Possible mount point detected, let's check the rootline
|
||||
foreach (self::getRootLine($uid) as $page) {
|
||||
if (!empty($page['_MOUNT_OL'])) {
|
||||
// Mountpoint detected in rootline
|
||||
$ret = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current root line
|
||||
*
|
||||
* @param integer|null $uid Page UID
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getRootLine($uid = null)
|
||||
{
|
||||
if ($uid === null) {
|
||||
#################
|
||||
# Current rootline
|
||||
#################
|
||||
if (empty(self::$rootlineCache['__CURRENT__'])) {
|
||||
// Current rootline
|
||||
$rootline = $GLOBALS['TSFE']->tmpl->rootLine;
|
||||
|
||||
// Filter rootline by siteroot
|
||||
$rootline = self::filterRootlineBySiteroot((array)$rootline);
|
||||
|
||||
self::$rootlineCache['__CURRENT__'] = $rootline;
|
||||
}
|
||||
|
||||
$ret = self::$rootlineCache['__CURRENT__'];
|
||||
} else {
|
||||
#################
|
||||
# Other rootline
|
||||
#################
|
||||
if (empty(self::$rootlineCache[$uid])) {
|
||||
// Fetch full rootline to TYPO3 root (0)
|
||||
$rootline = self::getSysPageObj()->getRootLine($uid);
|
||||
|
||||
// Filter rootline by siteroot
|
||||
$rootline = self::filterRootlineBySiteroot((array)$rootline);
|
||||
|
||||
self::$rootlineCache[$uid] = $rootline;
|
||||
}
|
||||
|
||||
$ret = self::$rootlineCache[$uid];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter rootline to get the real one up to siteroot page
|
||||
*
|
||||
* @param $rootline
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function filterRootlineBySiteroot(array $rootline)
|
||||
{
|
||||
$ret = array();
|
||||
|
||||
// Make sure sorting is right (first root, last page)
|
||||
ksort($rootline, SORT_NUMERIC);
|
||||
|
||||
//reverse rootline
|
||||
$rootline = array_reverse($rootline);
|
||||
|
||||
foreach ($rootline as $page) {
|
||||
$ret[] = $page;
|
||||
if (!empty($page['is_siteroot'])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$ret = array_reverse($ret);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sys page object
|
||||
*
|
||||
* @return \TYPO3\CMS\Frontend\Page\PageRepository
|
||||
*/
|
||||
protected static function getSysPageObj()
|
||||
{
|
||||
if (self::$sysPageObj === null) {
|
||||
/** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */
|
||||
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Extbase\\Object\\ObjectManager'
|
||||
);
|
||||
|
||||
/** @var \TYPO3\CMS\Frontend\Page\PageRepository $sysPageObj */
|
||||
$sysPageObj = $objectManager->get('TYPO3\\CMS\\Frontend\\Page\\PageRepository');
|
||||
|
||||
self::$sysPageObj = $sysPageObj;
|
||||
}
|
||||
|
||||
return self::$sysPageObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get domain
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getSysDomain()
|
||||
{
|
||||
static $ret = null;
|
||||
|
||||
if ($ret !== null) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$host = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('HTTP_HOST');
|
||||
$rootPid = self::getRootPid();
|
||||
|
||||
$query = 'SELECT *
|
||||
FROM sys_domain
|
||||
WHERE pid = ' . (int)$rootPid . '
|
||||
AND domainName = ' . DatabaseUtility::quote($host, 'sys_domain') . '
|
||||
AND hidden = 0';
|
||||
$ret = DatabaseUtility::getRow($query);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current root pid
|
||||
*
|
||||
* @param integer|null $uid Page UID
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public static function getRootPid($uid = null)
|
||||
{
|
||||
static $cache = array();
|
||||
$ret = null;
|
||||
|
||||
if ($uid === null) {
|
||||
#################
|
||||
# Current root PID
|
||||
#################
|
||||
$rootline = self::getRootLine();
|
||||
if (!empty($rootline[0])) {
|
||||
$ret = $rootline[0]['uid'];
|
||||
}
|
||||
} else {
|
||||
#################
|
||||
# Other root PID
|
||||
#################
|
||||
if (!isset($cache[$uid])) {
|
||||
$cache[$uid] = null;
|
||||
$rootline = self::getRootLine($uid);
|
||||
|
||||
if (!empty($rootline[0])) {
|
||||
$cache[$uid] = $rootline[0]['uid'];
|
||||
}
|
||||
}
|
||||
|
||||
$ret = $cache[$uid];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get root setting value
|
||||
*
|
||||
* @param string $name Name of configuration
|
||||
* @param mixed|NULL $defaultValue Default value
|
||||
* @param integer|NULL $rootPid Root Page Id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getRootSettingValue($name, $defaultValue = null, $rootPid = null)
|
||||
{
|
||||
$setting = self::getRootSetting($rootPid);
|
||||
|
||||
if (isset($setting[$name])) {
|
||||
$ret = $setting[$name];
|
||||
} else {
|
||||
$ret = $defaultValue;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get root setting row
|
||||
*
|
||||
* @param integer $rootPid Root Page Id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getRootSetting($rootPid = null)
|
||||
{
|
||||
static $ret = null;
|
||||
|
||||
if ($ret !== null) {
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($rootPid === null) {
|
||||
$rootPid = self::getRootPid();
|
||||
}
|
||||
|
||||
$query = 'SELECT *
|
||||
FROM tx_metaseo_setting_root
|
||||
WHERE pid = ' . (int)$rootPid . '
|
||||
AND deleted = 0
|
||||
LIMIT 1';
|
||||
$ret = DatabaseUtility::getRow($query);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get extension configuration
|
||||
*
|
||||
* @param string $name Name of config
|
||||
* @param boolean $default Default value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getExtConf($name, $default = null)
|
||||
{
|
||||
static $conf = null;
|
||||
$ret = $default;
|
||||
|
||||
if ($conf === null) {
|
||||
// Load ext conf
|
||||
$conf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['metaseo']);
|
||||
if (!is_array($conf)) {
|
||||
$conf = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($conf[$name])) {
|
||||
$ret = $conf[$name];
|
||||
}
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call hook and signal
|
||||
*
|
||||
* @param string $class Name of the class containing the signal
|
||||
* @param string $name Name of hook
|
||||
* @param mixed $obj Reference to be passed along (typically "$this"
|
||||
* - being a reference to the calling object) (REFERENCE!)
|
||||
* @param mixed|NULL $args Args
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function callHookAndSignal($class, $name, $obj, &$args = null)
|
||||
{
|
||||
static $hookConf = null;
|
||||
static $signalSlotDispatcher = null;
|
||||
|
||||
// Fetch hooks config for metaseo, minimize array lookups
|
||||
if ($hookConf === null) {
|
||||
$hookConf = array();
|
||||
if (isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks'])
|
||||
&& is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks'])
|
||||
) {
|
||||
$hookConf = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks'];
|
||||
}
|
||||
}
|
||||
|
||||
// Call hooks
|
||||
if (!empty($hookConf[$name]) && is_array($hookConf[$name])) {
|
||||
foreach ($hookConf[$name] as $_funcRef) {
|
||||
if ($_funcRef) {
|
||||
\TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction($_funcRef, $args, $obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call signal
|
||||
if ($signalSlotDispatcher === null) {
|
||||
/** @var \TYPO3\CMS\Extbase\Object\ObjectManager $objectManager */
|
||||
$objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Extbase\\Object\\ObjectManager'
|
||||
);
|
||||
|
||||
/** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */
|
||||
$signalSlotDispatcher = $objectManager->get('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher');
|
||||
}
|
||||
$signalSlotDispatcher->dispatch($class, $name, array($args, $obj));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generate full url
|
||||
*
|
||||
* Makes sure the url is absolute (http://....)
|
||||
*
|
||||
* @param string $url URL
|
||||
* @param string $domain Domain
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function fullUrl($url, $domain = null)
|
||||
{
|
||||
if (!preg_match('/^https?:\/\//i', $url)) {
|
||||
// Fix for root page link
|
||||
if ($url === '/') {
|
||||
$url = '';
|
||||
}
|
||||
|
||||
// remove first /
|
||||
if (strpos($url, '/') === 0) {
|
||||
$url = substr($url, 1);
|
||||
}
|
||||
|
||||
if ($domain !== null) {
|
||||
// specified domain
|
||||
$url = 'http://' . $domain . '/' . $url;
|
||||
} else {
|
||||
// domain from env
|
||||
$url = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . $url;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix url stuff
|
||||
$url = str_replace('?&', '?', $url);
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
// ########################################################################
|
||||
// Protected methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Check if url is blacklisted
|
||||
*
|
||||
* @param string $url URL
|
||||
* @param array $blacklistConf Blacklist configuration (list of regexp)
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkUrlForBlacklisting($url, array $blacklistConf)
|
||||
{
|
||||
// check for valid url
|
||||
if (empty($url)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$blacklistConf = (array)$blacklistConf;
|
||||
foreach ($blacklistConf as $blacklistRegExp) {
|
||||
if (preg_match($blacklistRegExp, $url)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
126
typo3conf/ext/metaseo/Classes/Utility/RootPageUtility.php
Normal file
126
typo3conf/ext/metaseo/Classes/Utility/RootPageUtility.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
|
||||
/**
|
||||
* Root page utility
|
||||
*/
|
||||
class RootPageUtility
|
||||
{
|
||||
|
||||
/**
|
||||
* Domain cache
|
||||
*
|
||||
* array(
|
||||
* rootPid => domainName
|
||||
* );
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $domainCache = array();
|
||||
|
||||
/**
|
||||
* Get sitemap index url
|
||||
*
|
||||
* @param integer $rootPid Root PID
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getSitemapIndexUrl($rootPid)
|
||||
{
|
||||
return self::getFrontendUrl($rootPid, SitemapUtility::PAGE_TYPE_SITEMAP_XML);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a frontend url
|
||||
*
|
||||
* @param integer $rootPid Root Page ID
|
||||
* @param integer $typeNum Type num
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getFrontendUrl($rootPid, $typeNum)
|
||||
{
|
||||
$domain = self::getDomain($rootPid);
|
||||
if (!empty($domain)) {
|
||||
$domain = 'http://' . $domain . '/';
|
||||
} else {
|
||||
$domain = Typo3GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
|
||||
}
|
||||
// "build", TODO: use typolink to use TYPO3 internals
|
||||
$url = $domain . 'index.php?id=' . (int)$rootPid . '&type=' . (int)$typeNum;
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get domain
|
||||
*
|
||||
* @param integer $rootPid Root PID
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function getDomain($rootPid)
|
||||
{
|
||||
// Use cached one if exists
|
||||
if (isset(self::$domainCache[$rootPid])) {
|
||||
return self::$domainCache[$rootPid];
|
||||
}
|
||||
|
||||
// Fetch domain name
|
||||
$query = 'SELECT domainName
|
||||
FROM sys_domain
|
||||
WHERE pid = ' . (int)$rootPid . '
|
||||
AND hidden = 0
|
||||
ORDER BY forced DESC,
|
||||
sorting
|
||||
LIMIT 1';
|
||||
$ret = DatabaseUtility::getOne($query);
|
||||
|
||||
// Remove possible slash at the end
|
||||
$ret = rtrim($ret, '/');
|
||||
|
||||
// Cache entry
|
||||
self::$domainCache[$rootPid] = $ret;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get robots.txt url
|
||||
*
|
||||
* @param integer $rootPid Root PID
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getRobotsTxtUrl($rootPid)
|
||||
{
|
||||
return self::getFrontendUrl($rootPid, SitemapUtility::PAGE_TYPE_ROBOTS_TXT);
|
||||
}
|
||||
}
|
||||
298
typo3conf/ext/metaseo/Classes/Utility/SitemapUtility.php
Normal file
298
typo3conf/ext/metaseo/Classes/Utility/SitemapUtility.php
Normal file
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* (c) 2013 Markus Blaschke (TEQneers GmbH & Co. KG) <blaschke@teqneers.de> (tq_seo)
|
||||
* 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 3 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 Metaseo\Metaseo\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
use TYPO3\CMS\Frontend\Page\PageRepository;
|
||||
|
||||
/**
|
||||
* Sitemap utility
|
||||
*/
|
||||
class SitemapUtility
|
||||
{
|
||||
|
||||
const SITEMAP_TYPE_PAGE = 0;
|
||||
const SITEMAP_TYPE_FILE = 1;
|
||||
|
||||
/* apply changes in Configuration/TypoScript/setup.txt */
|
||||
const PAGE_TYPE_SITEMAP_TXT = 841131; // sitemap.txt (EXT:metaseo)
|
||||
const PAGE_TYPE_SITEMAP_XML = 841132; // sitemap.xml (EXT:metaseo)
|
||||
const PAGE_TYPE_ROBOTS_TXT = 841133; // robots.txt (EXT:metaseo)
|
||||
|
||||
// ########################################################################
|
||||
// Attributes
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* List of blacklisted doktypes (from table pages)
|
||||
* @var array
|
||||
*/
|
||||
protected static $doktypeBlacklist = array(
|
||||
PageRepository::DOKTYPE_BE_USER_SECTION, // Backend Section (TYPO3 CMS)
|
||||
PageRepository::DOKTYPE_SPACER, // Menu separator (TYPO3 CMS)
|
||||
PageRepository::DOKTYPE_SYSFOLDER, // Folder (TYPO3 CMS)
|
||||
PageRepository::DOKTYPE_RECYCLER, // Recycler (TYPO3 CMS)
|
||||
);
|
||||
|
||||
/**
|
||||
* List of blacklisted rendering PAGE typenum (typoscript object)
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $pagetypeBlacklist = array(
|
||||
self::PAGE_TYPE_SITEMAP_TXT, // sitemap.txt (EXT:metaseo)
|
||||
self::PAGE_TYPE_SITEMAP_XML, // sitemap.xml (EXT:metaseo)
|
||||
self::PAGE_TYPE_ROBOTS_TXT, // robots.txt (EXT:metaseo)
|
||||
);
|
||||
|
||||
|
||||
// ########################################################################
|
||||
// Public methods
|
||||
// ########################################################################
|
||||
|
||||
/**
|
||||
* Insert into sitemap
|
||||
*
|
||||
* @param array $pageData page information
|
||||
*/
|
||||
public static function index(array $pageData)
|
||||
{
|
||||
static $cache = array();
|
||||
|
||||
// do not index empty urls
|
||||
if (empty($pageData['page_url'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Trim url
|
||||
$pageData['page_url'] = trim($pageData['page_url']);
|
||||
|
||||
// calc page hash
|
||||
$pageData['page_hash'] = md5($pageData['page_url']);
|
||||
$pageHash = $pageData['page_hash'];
|
||||
|
||||
// set default type if not set
|
||||
if (!isset($pageData['page_type'])) {
|
||||
$pageData['page_type'] = self::SITEMAP_TYPE_PAGE;
|
||||
}
|
||||
|
||||
// Escape/Quote data
|
||||
unset($pageDataValue);
|
||||
foreach ($pageData as &$pageDataValue) {
|
||||
if ($pageDataValue === null) {
|
||||
$pageDataValue = 'NULL';
|
||||
} elseif (is_int($pageDataValue) || is_numeric($pageDataValue)) {
|
||||
// Don't quote numeric/integers
|
||||
$pageDataValue = (int)$pageDataValue;
|
||||
} else {
|
||||
// String
|
||||
$pageDataValue = DatabaseUtility::quote($pageDataValue, 'tx_metaseo_sitemap');
|
||||
}
|
||||
}
|
||||
unset($pageDataValue);
|
||||
|
||||
// only process each page once to keep sql-statements at a normal level
|
||||
if (empty($cache[$pageHash])) {
|
||||
// $pageData is already quoted
|
||||
// TODO: INSERT INTO ... ON DUPLICATE KEY UPDATE?
|
||||
|
||||
$query = 'SELECT uid
|
||||
FROM tx_metaseo_sitemap
|
||||
WHERE page_uid = ' . $pageData['page_uid'] . '
|
||||
AND page_language = ' . $pageData['page_language'] . '
|
||||
AND page_hash = ' . $pageData['page_hash'] . '
|
||||
AND page_type = ' . $pageData['page_type'];
|
||||
$sitemapUid = DatabaseUtility::getOne($query);
|
||||
|
||||
if (!empty($sitemapUid)) {
|
||||
$query = 'UPDATE tx_metaseo_sitemap
|
||||
SET tstamp = ' . $pageData['tstamp'] . ',
|
||||
page_rootpid = ' . $pageData['page_rootpid'] . ',
|
||||
page_language = ' . $pageData['page_language'] . ',
|
||||
page_url = ' . $pageData['page_url'] . ',
|
||||
page_depth = ' . $pageData['page_depth'] . ',
|
||||
page_change_frequency = ' . $pageData['page_change_frequency'] . ',
|
||||
page_type = ' . $pageData['page_type'] . ',
|
||||
expire = ' . $pageData['expire'] . '
|
||||
WHERE uid = ' . (int)$sitemapUid;
|
||||
DatabaseUtility::exec($query);
|
||||
} else {
|
||||
// #####################################
|
||||
// INSERT
|
||||
// #####################################
|
||||
DatabaseUtility::connection()->exec_INSERTquery(
|
||||
'tx_metaseo_sitemap',
|
||||
$pageData,
|
||||
array_keys($pageData)
|
||||
);
|
||||
}
|
||||
|
||||
$cache[$pageHash] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear outdated and invalid pages from sitemap table
|
||||
*/
|
||||
public static function expire()
|
||||
{
|
||||
// #####################
|
||||
// Delete expired entries
|
||||
// #####################
|
||||
|
||||
$query = 'DELETE FROM tx_metaseo_sitemap
|
||||
WHERE is_blacklisted = 0
|
||||
AND expire <= ' . (int)time();
|
||||
DatabaseUtility::exec($query);
|
||||
|
||||
// #####################
|
||||
// Deleted or
|
||||
// excluded pages
|
||||
// #####################
|
||||
$query = 'SELECT ts.uid
|
||||
FROM tx_metaseo_sitemap ts
|
||||
LEFT JOIN pages p
|
||||
ON p.uid = ts.page_uid
|
||||
AND p.deleted = 0
|
||||
AND p.hidden = 0
|
||||
AND p.tx_metaseo_is_exclude = 0
|
||||
AND ' . DatabaseUtility::conditionNotIn('p.doktype', self::getDoktypeBlacklist()) . '
|
||||
WHERE p.uid IS NULL';
|
||||
|
||||
$deletedSitemapPages = DatabaseUtility::getColWithIndex($query);
|
||||
|
||||
// delete pages
|
||||
if (!empty($deletedSitemapPages)) {
|
||||
$query = 'DELETE FROM tx_metaseo_sitemap
|
||||
WHERE uid IN (' . implode(',', $deletedSitemapPages) . ')
|
||||
AND is_blacklisted = 0';
|
||||
DatabaseUtility::exec($query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of blacklisted doktypes (from table pages)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getDoktypeBlacklist()
|
||||
{
|
||||
return self::$doktypeBlacklist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of blacklisted PAGE typenum (typoscript object)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getPageTypeBlacklist()
|
||||
{
|
||||
$ret = self::$pagetypeBlacklist;
|
||||
|
||||
// Fetch from SetupTS (comma separated list)
|
||||
if (isset($GLOBALS['TSFE']->tmpl->setup['plugin.']['metaseo.']['sitemap.']['index.']['pageTypeBlacklist'])
|
||||
&& strlen(
|
||||
$GLOBALS['TSFE']
|
||||
->tmpl
|
||||
->setup['plugin.']['metaseo.']['sitemap.']['index.']['pageTypeBlacklist']
|
||||
) >= 1
|
||||
) {
|
||||
$pageTypeBlacklist = $GLOBALS['TSFE']->tmpl
|
||||
->setup['plugin.']['metaseo.']['sitemap.']['index.']['pageTypeBlacklist'];
|
||||
$pageTypeBlacklist = Typo3GeneralUtility::trimExplode(',', $pageTypeBlacklist);
|
||||
|
||||
$ret = array_merge($ret, $pageTypeBlacklist);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of sitemap pages
|
||||
*
|
||||
* @param integer $rootPid Root page id of tree
|
||||
* @param integer $languageId Limit to language id
|
||||
*
|
||||
* @return boolean|array
|
||||
*/
|
||||
public static function getList($rootPid, $languageId = null)
|
||||
{
|
||||
$sitemapList = array();
|
||||
$pageList = array();
|
||||
|
||||
$typo3Pids = array();
|
||||
|
||||
$query = 'SELECT ts.*
|
||||
FROM tx_metaseo_sitemap ts
|
||||
INNER JOIN pages p
|
||||
ON p.uid = ts.page_uid
|
||||
AND p.deleted = 0
|
||||
AND p.hidden = 0
|
||||
AND p.tx_metaseo_is_exclude = 0
|
||||
AND ' . DatabaseUtility::conditionNotIn('p.doktype', self::getDoktypeBlacklist()) . '
|
||||
WHERE ts.page_rootpid = ' . (int)$rootPid . '
|
||||
AND ts.is_blacklisted = 0';
|
||||
|
||||
if ($languageId !== null) {
|
||||
$query .= ' AND ts.page_language = ' . (int)$languageId;
|
||||
}
|
||||
$query .= ' ORDER BY
|
||||
ts.page_depth ASC,
|
||||
p.pid ASC,
|
||||
p.sorting ASC';
|
||||
$resultRows = DatabaseUtility::getAll($query);
|
||||
|
||||
if (!$resultRows) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($resultRows as $row) {
|
||||
$sitemapList[] = $row;
|
||||
|
||||
$sitemapPageId = $row['page_uid'];
|
||||
$typo3Pids[$sitemapPageId] = (int)$sitemapPageId;
|
||||
}
|
||||
|
||||
if (!empty($typo3Pids)) {
|
||||
$query = 'SELECT *
|
||||
FROM pages
|
||||
WHERE ' . DatabaseUtility::conditionIn('uid', $typo3Pids);
|
||||
$pageList = DatabaseUtility::getAllWithIndex($query, 'uid');
|
||||
|
||||
if (empty($pageList)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$ret = array(
|
||||
'tx_metaseo_sitemap' => $sitemapList,
|
||||
'pages' => $pageList
|
||||
);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
365
typo3conf/ext/metaseo/Classes/Utility/TypoScript.php
Normal file
365
typo3conf/ext/metaseo/Classes/Utility/TypoScript.php
Normal file
@@ -0,0 +1,365 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Copyright notice
|
||||
*
|
||||
* (c) 2015 Markus Blaschke <typo3@markus-blaschke.de> (metaseo)
|
||||
* 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 3 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 Metaseo\Metaseo\Utility;
|
||||
|
||||
use TYPO3\CMS\Core\Utility\GeneralUtility as Typo3GeneralUtility;
|
||||
|
||||
class TypoScript implements \Iterator
|
||||
{
|
||||
###########################################################################
|
||||
## Attributes
|
||||
###########################################################################
|
||||
|
||||
/**
|
||||
* TYPO3 TypoScript Data
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $tsData;
|
||||
|
||||
/**
|
||||
* TYPO3 TypoScript Data Type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tsType;
|
||||
|
||||
/**
|
||||
* Iterator position
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $iteratorPosition = false;
|
||||
|
||||
/**
|
||||
* cObj
|
||||
* @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
protected $cObj;
|
||||
|
||||
###########################################################################
|
||||
## Constructor
|
||||
###########################################################################
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param NULL|array $conf TypoScript node configuration
|
||||
* @param NULL|string $type TypoScript node type
|
||||
*/
|
||||
public function __construct($conf = null, $type = null)
|
||||
{
|
||||
if ($conf !== null) {
|
||||
$this->tsData = $conf;
|
||||
}
|
||||
|
||||
if ($type !== null) {
|
||||
$this->tsType = $type;
|
||||
}
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
## Iterator methods
|
||||
###########################################################################
|
||||
|
||||
/**
|
||||
* Rewind iterator position
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
reset($this->tsData);
|
||||
$this->iteratorNextNode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current node is a valid node
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->iteratorPosition && array_key_exists($this->iteratorPosition, $this->tsData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current iterator key
|
||||
*
|
||||
* @return string TypoScript path-node-key
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return substr($this->iteratorPosition, 0, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return current iterator node
|
||||
*
|
||||
* @return TypoScript
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
$nodePath = substr($this->iteratorPosition, 0, -1);
|
||||
|
||||
return $this->getNode($nodePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get TypoScript subnode
|
||||
*
|
||||
* @param string $tsNodePath TypoScript node-path
|
||||
*
|
||||
* @return TypoScript TypoScript subnode-object
|
||||
*/
|
||||
public function getNode($tsNodePath)
|
||||
{
|
||||
$ret = null;
|
||||
|
||||
// extract TypoScript-path information
|
||||
$nodeSections = explode('.', $tsNodePath);
|
||||
$nodeValueType = end($nodeSections);
|
||||
$nodeValueName = end($nodeSections) . '.';
|
||||
|
||||
// remove last node from sections because we already got the node name
|
||||
unset($nodeSections[key($nodeSections)]);
|
||||
|
||||
// walk though array to find node
|
||||
$nodeData = $this->tsData;
|
||||
if (!empty($nodeSections) && is_array($nodeSections)) {
|
||||
foreach ($nodeSections as $sectionName) {
|
||||
$sectionName .= '.';
|
||||
|
||||
if (is_array($nodeData) && array_key_exists($sectionName, $nodeData)) {
|
||||
$nodeData = $nodeData[$sectionName];
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch TypoScript configuration data
|
||||
$tsData = array();
|
||||
if (is_array($nodeData) && array_key_exists($nodeValueName, $nodeData)) {
|
||||
$tsData = $nodeData[$nodeValueName];
|
||||
}
|
||||
|
||||
// Fetch TypoScript configuration type
|
||||
$tsType = null;
|
||||
if (is_array($nodeData) && array_key_exists($nodeValueType, $nodeData)) {
|
||||
$tsType = $nodeData[$nodeValueType];
|
||||
}
|
||||
|
||||
// Clone object and set values
|
||||
$ret = clone $this;
|
||||
$ret->tsData = $tsData;
|
||||
$ret->tsType = $tsType;
|
||||
$ret->iteratorPosition = false;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Next iterator node
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
next($this->tsData);
|
||||
$this->iteratorNextNode();
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
## Public methods
|
||||
###########################################################################
|
||||
|
||||
/**
|
||||
* Search next iterator node
|
||||
*/
|
||||
public function iteratorNextNode()
|
||||
{
|
||||
// INIT
|
||||
$iteratorPosition = null;
|
||||
$this->iteratorPosition = false;
|
||||
$nextNode = false;
|
||||
|
||||
do {
|
||||
if ($nextNode) {
|
||||
next($this->tsData);
|
||||
}
|
||||
|
||||
$currentNode = current($this->tsData);
|
||||
|
||||
if ($currentNode !== false) {
|
||||
// get key
|
||||
$iteratorPosition = key($this->tsData);
|
||||
|
||||
// check if node is subnode or value
|
||||
if (substr($iteratorPosition, -1) == '.') {
|
||||
// next subnode fond
|
||||
$this->iteratorPosition = $iteratorPosition;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$iteratorPosition = false;
|
||||
$this->iteratorPosition = false;
|
||||
}
|
||||
|
||||
$nextNode = true;
|
||||
} while ($iteratorPosition !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value from node
|
||||
*
|
||||
* @param string $tsNodePath TypoScript node-path
|
||||
* @param mixed $defaultValue Default value
|
||||
*
|
||||
* @return mixed Node value (or default value)
|
||||
*/
|
||||
public function getValue($tsNodePath, $defaultValue = null)
|
||||
{
|
||||
$ret = $defaultValue;
|
||||
|
||||
// extract TypoScript-path information
|
||||
$nodeFound = true;
|
||||
$nodeSections = explode('.', $tsNodePath);
|
||||
$nodeValueName = end($nodeSections);
|
||||
|
||||
// remove last node from sections because we already got the node name
|
||||
unset($nodeSections[key($nodeSections)]);
|
||||
|
||||
// walk though array to find node
|
||||
$nodeData = $this->tsData;
|
||||
if (!empty($nodeSections) && is_array($nodeSections)) {
|
||||
foreach ($nodeSections as $sectionName) {
|
||||
$sectionName .= '.';
|
||||
|
||||
if (is_array($nodeData) && array_key_exists($sectionName, $nodeData)) {
|
||||
$nodeData = $nodeData[$sectionName];
|
||||
} else {
|
||||
$nodeFound = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check if we got the value of the node
|
||||
if ($nodeFound && is_array($nodeData) && array_key_exists($nodeValueName, $nodeData)) {
|
||||
$ret = $nodeData[$nodeValueName];
|
||||
}
|
||||
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert TypoScript to original array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->tsData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if TypoScript is empty/not set
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return empty($this->tsData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Render TypoScript Config
|
||||
*
|
||||
* @return mixed Result of cObj
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return $this->getCObj()->cObjGetSingle($this->tsType, $this->tsData);
|
||||
}
|
||||
|
||||
/**
|
||||
* StdWrap with TypoScript Configuration
|
||||
*
|
||||
* @param mixed $value Value for stdWrap
|
||||
*
|
||||
* @return mixed Result of stdWrap
|
||||
*/
|
||||
public function stdWrap($value = null)
|
||||
{
|
||||
return $this->getCObj()->stdWrap($value, $this->tsData);
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
## Protected methods
|
||||
###########################################################################
|
||||
|
||||
/**
|
||||
* Return instance of \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*
|
||||
* @return \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
|
||||
*/
|
||||
protected function getCObj()
|
||||
{
|
||||
if ($this->cObj === null) {
|
||||
$this->cObj = Typo3GeneralUtility::makeInstance(
|
||||
'TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer'
|
||||
);
|
||||
}
|
||||
|
||||
return $this->cObj;
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
## Private methods
|
||||
###########################################################################
|
||||
|
||||
###########################################################################
|
||||
## Accessors
|
||||
###########################################################################
|
||||
|
||||
public function setTypoScript(Array $conf)
|
||||
{
|
||||
$this->tsData = $conf;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTypoScriptType()
|
||||
{
|
||||
return $this->tsType;
|
||||
}
|
||||
|
||||
public function setTypoScriptType($value)
|
||||
{
|
||||
$this->tsType = (string)$value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user