Initial commit
29
typo3conf/ext/metaseo/.editorconfig
Normal file
@@ -0,0 +1,29 @@
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.php]
|
||||
indent_style = space
|
||||
|
||||
[{setup,constants,ext_conf_template}.txt]
|
||||
indent_style = space
|
||||
|
||||
[*.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.html]
|
||||
indent_style = tab
|
||||
|
||||
[*.rst]
|
||||
indent_style = tab
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
10
typo3conf/ext/metaseo/.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
.settings/
|
||||
.buildpath
|
||||
*.kdev4
|
||||
.project
|
||||
.remote_password_hash
|
||||
.remote_server
|
||||
.remote_username
|
||||
tmp
|
||||
*~
|
||||
.idea
|
||||
34
typo3conf/ext/metaseo/CHANGELOG.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# MetaSEO - Changelog
|
||||
|
||||
## MetaSEO 2.0
|
||||
|
||||
- Added TYPO3 7.x support
|
||||
- Implemented Signals
|
||||
- Implemented blacklist of PAGE typeNum in SetupTS
|
||||
- Implemented blacklist for index/noindex robots metatag
|
||||
- Implemented blacklist for canonical url
|
||||
- Implemented canonical url support for mounted pages, pointing to real page instead of mount path (disabled by default)
|
||||
- Implemented expiry date for sitemap entries (customizable with SetupTS or Connector)
|
||||
- Implemented pagetitle caching (if there is any USER_INT on the current page)
|
||||
- Removed own caching solution, using TYPO3 caching framework now
|
||||
- Fixed many bugs and issues
|
||||
- Fixed coding style (added .editorconfig)
|
||||
- Refactored whole extension
|
||||
|
||||
## Beta features
|
||||
|
||||
- If you have any issues with cached pagetitle: set `plugin.metaseo.pageTitle.caching = 0` to disable this feature.
|
||||
|
||||
### Migrate from 1.x to 2.x
|
||||
|
||||
- TypoScript Constant `plugin.metaseo.metaTags.useCanonical` changed to `plugin.metaseo.metaTags.canonicalUrl`
|
||||
- TypoScript Setup `plugin.metaseo.metaTags.useCanonical` changed to `plugin.metaseo.metaTags.canonicalUrl`
|
||||
- Names of Hooks changed, now camelCase
|
||||
|
||||
|
||||
## MetaSEO 1.0 (2014-04-20)
|
||||
|
||||
- Version 1.0.0
|
||||
- Fork of metaseo
|
||||
- Fixed several bugs and improved codebase
|
||||
- Fixed and improved manual (now reStructuredText)
|
||||
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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\Configuration\TCA;
|
||||
|
||||
/**
|
||||
* This File is include()d by TYPO3's ExtensionUtility. We'll get an exception when we remove it.
|
||||
* At some time we should find out what this file is actually good for.
|
||||
*/
|
||||
259
typo3conf/ext/metaseo/Configuration/TCA/Overrides/pages.php
Normal file
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
defined('TYPO3_MODE') or exit();
|
||||
|
||||
$tempColumns = array(
|
||||
'tx_metaseo_pagetitle' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_pagetitle',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_pagetitle_rel' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_pagetitle_rel',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_pagetitle_prefix' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_pagetitle_prefix',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_pagetitle_suffix' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_pagetitle_suffix',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_inheritance' => array(
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_inheritance',
|
||||
'config' => array(
|
||||
'type' => 'select',
|
||||
'items' => array(
|
||||
array(
|
||||
'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_inheritance.I.0',
|
||||
0
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_inheritance.I.1',
|
||||
1
|
||||
),
|
||||
),
|
||||
'size' => 1,
|
||||
'maxitems' => 1
|
||||
)
|
||||
),
|
||||
'tx_metaseo_is_exclude' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_is_exclude',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'check'
|
||||
)
|
||||
),
|
||||
'tx_metaseo_canonicalurl' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_canonicalurl',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
'wizards' => array(
|
||||
'_PADDING' => 2,
|
||||
'link' => array(
|
||||
'type' => 'popup',
|
||||
'title' => 'Link',
|
||||
'icon' => 'link_popup.gif',
|
||||
'module' => array(
|
||||
'name' => 'wizard_element_browser',
|
||||
'urlParameters' => array(
|
||||
'mode' => 'wizard',
|
||||
'act' => 'url'
|
||||
)
|
||||
),
|
||||
'params' => array(
|
||||
'blindLinkOptions' => 'mail',
|
||||
),
|
||||
'JSopenParams' => 'height=300,width=500,status=0,menubar=0,scrollbars=1'
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
'tx_metaseo_priority' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_priority',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'int',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_change_frequency' => array(
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_change_frequency',
|
||||
'config' => array(
|
||||
'type' => 'select',
|
||||
'items' => array(
|
||||
array(
|
||||
'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_change_frequency.I.0',
|
||||
0
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_change_frequency.I.1',
|
||||
1
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_change_frequency.I.2',
|
||||
2
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_change_frequency.I.3',
|
||||
3
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_change_frequency.I.4',
|
||||
4
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_change_frequency.I.5',
|
||||
5
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_change_frequency.I.6',
|
||||
6
|
||||
),
|
||||
array(
|
||||
'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_change_frequency.I.7',
|
||||
7
|
||||
),
|
||||
),
|
||||
'size' => 1,
|
||||
'maxitems' => 1
|
||||
)
|
||||
),
|
||||
'tx_metaseo_geo_lat' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_geo_lat',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_geo_long' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_geo_long',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_geo_place' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_geo_place',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_geo_region' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tx_metaseo_geo_region',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('pages', $tempColumns, 1);
|
||||
|
||||
// TCA Palettes
|
||||
$GLOBALS['TCA']['pages']['palettes']['tx_metaseo_pagetitle'] = array(
|
||||
'showitem' => 'tx_metaseo_pagetitle,--linebreak--,tx_metaseo_pagetitle_prefix,'
|
||||
. 'tx_metaseo_pagetitle_suffix,--linebreak--,tx_metaseo_inheritance',
|
||||
'canNotCollapse' => 1
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['pages']['palettes']['tx_metaseo_crawler'] = array(
|
||||
'showitem' => 'tx_metaseo_is_exclude,--linebreak--,tx_metaseo_canonicalurl',
|
||||
'canNotCollapse' => 1
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['pages']['palettes']['tx_metaseo_sitemap'] = array(
|
||||
'showitem' => 'tx_metaseo_priority,--linebreak--,tx_metaseo_change_frequency',
|
||||
'canNotCollapse' => 1
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['pages']['palettes']['tx_metaseo_geo'] = array(
|
||||
'showitem' => 'tx_metaseo_geo_lat,--linebreak--,tx_metaseo_geo_long,--linebreak--,'
|
||||
. 'tx_metaseo_geo_place,--linebreak--,tx_metaseo_geo_region',
|
||||
'canNotCollapse' => 1
|
||||
);
|
||||
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
|
||||
'pages',
|
||||
'tx_metaseo_pagetitle_rel',
|
||||
'1,4,7,3',
|
||||
'after:title'
|
||||
);
|
||||
|
||||
// Put it for standard page
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
|
||||
'pages',
|
||||
'--div--;LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tab.seo;,--palette--;'
|
||||
. 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.palette.pagetitle;tx_metaseo_pagetitle,'
|
||||
. '--palette--;LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.palette.geo;tx_metaseo_geo,'
|
||||
. '--palette--;LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.palette.crawler;'
|
||||
. 'tx_metaseo_crawler,--palette--;LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.palette.sitemap;tx_metaseo_sitemap',
|
||||
'1,4,7,3',
|
||||
'after:author_email'
|
||||
);
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
defined('TYPO3_MODE') or exit();
|
||||
|
||||
$tempColumns = array(
|
||||
'tx_metaseo_pagetitle' => array(
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages_language_overlay.tx_metaseo_pagetitle',
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_pagetitle_rel' => array(
|
||||
'exclude' => 1,
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages_language_overlay.tx_metaseo_pagetitle_rel',
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_pagetitle_prefix' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_pagetitle_prefix',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_pagetitle_suffix' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_pagetitle_suffix',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
)
|
||||
),
|
||||
'tx_metaseo_canonicalurl' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'pages.tx_metaseo_canonicalurl',
|
||||
'exclude' => 1,
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '30',
|
||||
'max' => '255',
|
||||
'checkbox' => '',
|
||||
'eval' => 'trim',
|
||||
'wizards' => array(
|
||||
'_PADDING' => 2,
|
||||
'link' => array(
|
||||
'type' => 'popup',
|
||||
'title' => 'Link',
|
||||
'icon' => 'link_popup.gif',
|
||||
'module' => array(
|
||||
'name' => 'wizard_element_browser',
|
||||
'urlParameters' => array(
|
||||
'mode' => 'wizard',
|
||||
'act' => 'url'
|
||||
)
|
||||
),
|
||||
'params' => array(
|
||||
'blindLinkOptions' => 'mail',
|
||||
),
|
||||
'JSopenParams' => 'height=300,width=500,status=0,menubar=0,scrollbars=1'
|
||||
),
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('pages_language_overlay', $tempColumns, 1);
|
||||
|
||||
// TCA Palettes
|
||||
$GLOBALS['TCA']['pages_language_overlay']['palettes']['tx_metaseo_pagetitle'] = array(
|
||||
'showitem' => 'tx_metaseo_pagetitle,--linebreak--,tx_metaseo_pagetitle_prefix,tx_metaseo_pagetitle_suffix',
|
||||
'canNotCollapse' => 1
|
||||
);
|
||||
|
||||
$GLOBALS['TCA']['pages_language_overlay']['palettes']['tx_metaseo_crawler'] = array(
|
||||
'showitem' => 'tx_metaseo_canonicalurl',
|
||||
'canNotCollapse' => 1
|
||||
);
|
||||
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
|
||||
'pages_language_overlay',
|
||||
'tx_metaseo_pagetitle_rel',
|
||||
'',
|
||||
'after:title'
|
||||
);
|
||||
|
||||
// Put it for standard page overlay
|
||||
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
|
||||
'pages_language_overlay',
|
||||
'--div--;LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.tab.seo;,--palette--;'
|
||||
. 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.palette.pagetitle;tx_metaseo_pagetitle,'
|
||||
. '--palette--;LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:pages.palette.crawler;'
|
||||
. 'tx_metaseo_crawler',
|
||||
'',
|
||||
'after:author_email'
|
||||
);
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
return array(
|
||||
'ctrl' => array(
|
||||
'title' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:tx_metaseo_setting_root',
|
||||
'label' => 'uid',
|
||||
'adminOnly' => true,
|
||||
'iconfile' => 'page',
|
||||
'hideTable' => true,
|
||||
'dividers2tabs' => true,
|
||||
),
|
||||
'interface' => array(
|
||||
'always_description' => true,
|
||||
'showRecordFieldList' => 'is_robotstxt,robotstxt',
|
||||
),
|
||||
'columns' => array(
|
||||
'is_sitemap' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.is_sitemap',
|
||||
'config' => array(
|
||||
'type' => 'check',
|
||||
),
|
||||
),
|
||||
'is_sitemap_page_indexer' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.is_sitemap_page_indexer',
|
||||
'config' => array(
|
||||
'type' => 'check',
|
||||
),
|
||||
),
|
||||
'is_sitemap_typolink_indexer' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.is_sitemap_typolink_indexer',
|
||||
'config' => array(
|
||||
'type' => 'check',
|
||||
),
|
||||
),
|
||||
'is_sitemap_language_lock' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.is_sitemap_language_lock',
|
||||
'config' => array(
|
||||
'type' => 'check',
|
||||
),
|
||||
),
|
||||
'sitemap_page_limit' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.sitemap_page_limit',
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '10',
|
||||
'max' => '10',
|
||||
'eval' => 'int',
|
||||
'range' => array(
|
||||
'upper' => '1000000',
|
||||
'lower' => '0',
|
||||
),
|
||||
),
|
||||
),
|
||||
'sitemap_priorty' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.sitemap_priorty',
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '6',
|
||||
'max' => '6',
|
||||
'eval' => 'tx_metaseo_backend_validation_float',
|
||||
),
|
||||
),
|
||||
'sitemap_priorty_depth_multiplier' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.sitemap_priorty_depth_multiplier',
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '6',
|
||||
'max' => '6',
|
||||
'eval' => 'tx_metaseo_backend_validation_float',
|
||||
),
|
||||
),
|
||||
'sitemap_priorty_depth_modificator' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.sitemap_priorty_depth_modificator',
|
||||
'config' => array(
|
||||
'type' => 'input',
|
||||
'size' => '6',
|
||||
'max' => '6',
|
||||
'eval' => 'tx_metaseo_backend_validation_float',
|
||||
),
|
||||
),
|
||||
'is_robotstxt' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.is_robotstxt',
|
||||
'config' => array(
|
||||
'type' => 'check',
|
||||
),
|
||||
),
|
||||
'is_robotstxt_sitemap_static' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.is_robotstxt_sitemap_static',
|
||||
'config' => array(
|
||||
'type' => 'check',
|
||||
),
|
||||
),
|
||||
'robotstxt' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.robotstxt',
|
||||
'config' => array(
|
||||
'type' => 'text',
|
||||
'cols' => '30',
|
||||
'rows' => '20',
|
||||
),
|
||||
),
|
||||
'robotstxt_default' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.robotstxt_default',
|
||||
'config' => array(
|
||||
'type' => 'user',
|
||||
'userFunc' => 'Metaseo\Metaseo\Hook\TCA\RobotsTxtDefault->main'
|
||||
),
|
||||
),
|
||||
'robotstxt_additional' => array(
|
||||
'label' => 'LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.robotstxt_additional',
|
||||
'config' => array(
|
||||
'type' => 'text',
|
||||
'cols' => '30',
|
||||
'rows' => '20',
|
||||
),
|
||||
),
|
||||
|
||||
),
|
||||
'types' => array(
|
||||
'0' => array(
|
||||
'showitem' => '--div--;LLL:EXT:metaseo/Resources/Private/Language/TCA/locallang.xlf:'
|
||||
. 'tx_metaseo_setting_root.tab.sitemap,is_sitemap;;pallette_sitemap,is_sitemap_language_lock,'
|
||||
. 'sitemap_page_limit,sitemap_priorty,sitemap_priorty_depth_multiplier,'
|
||||
. 'sitemap_priorty_depth_modificator,--div--;LLL:EXT:'
|
||||
. 'metaseo/Resources/Private/Language/TCA/locallang.xlf:tx_metaseo_setting_root.tab.robotstxt,'
|
||||
. 'is_robotstxt;;pallette_robotstxt',
|
||||
'canNotCollapse' => '1'
|
||||
),
|
||||
),
|
||||
'palettes' => array(
|
||||
'pallette_sitemap' => array(
|
||||
'showitem' => 'is_sitemap_page_indexer,is_sitemap_typolink_indexer',
|
||||
'canNotCollapse' => '1'
|
||||
),
|
||||
'pallette_robotstxt' => array(
|
||||
'showitem' => 'is_robotstxt_sitemap_static,--linebreak--,robotstxt,robotstxt_default,'
|
||||
. '--linebreak--,robotstxt_additional',
|
||||
'canNotCollapse' => '1'
|
||||
),
|
||||
),
|
||||
|
||||
);
|
||||
172
typo3conf/ext/metaseo/Configuration/TypoScript/constants.txt
Normal file
@@ -0,0 +1,172 @@
|
||||
###
|
||||
# This are the default TS-constants for metaseo
|
||||
##
|
||||
plugin.metaseo {
|
||||
# cat=plugin.metaseo.metaTags/page/01; type=string; label= Meta Description: Short description of your webpage.
|
||||
metaTags.description =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/02; type=string; label= Meta Keywords: Comma separated list of keywords.
|
||||
metaTags.keywords =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/03; type=string; label= Meta Copyright info: Copyright information (eg. "Me Myself and I, %YEAR%. All rights reserved.", %YEAR% will be substituted with the current year).
|
||||
metaTags.copyright =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/04; type=string; label= Meta Reply-to email: Enter the e-mail adress for contact issues
|
||||
metaTags.email =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/05; type=string; label= Meta Author: Enter name of author.
|
||||
metaTags.author =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/06; type=string; label= Meta Publisher: Enter name of publisher.
|
||||
metaTags.publisher =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/08; type=string; label= Distribution
|
||||
metaTags.distribution =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/08; type=options[,General,Mature,14 years,Restricted]; label= Rating
|
||||
metaTags.rating =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/10; type=int+; label= Revisit after: Number of days between search engine visits.
|
||||
metaTags.revisit =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/14; type=string; label= Geo Position Latitude: Latitude of webpage
|
||||
metaTags.geoPositionLatitude =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/15; type=string; label= Geo Position Longitude: Longitude of webpage
|
||||
metaTags.geoPositionLongitude =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/16; type=string; label= Geo Region: Region of webpage (eg. DE-BW)
|
||||
metaTags.geoRegion =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/17; type=string; label= Geo Placename: Placename of webpage (eg. Stuttgart)
|
||||
metaTags.geoPlacename =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/19; type=string; label= PICS-Label: Platform for Internet Content Selection Label, see http://www.w3.org/PICS/
|
||||
metaTags.picsLabel =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/enable/20; type=boolean; label= Publish LastUpdate-Time: Should the crawler be informed about the time a page was last updated.
|
||||
metaTags.useLastUpdate = 1
|
||||
|
||||
# cat=plugin.metaseo.metaTags/enable/22; type=boolean; label= Canonical Tag: Autogenerate Canonical-Metatag if possible.
|
||||
metaTags.canonicalUrl = 1
|
||||
|
||||
# cat=plugin.metaseo.metaTags/enable/23; type=boolean; label= Canonical Tag (Strict mode): Enable strict mode (all wrong GET-parameters will generate a canonical-tag to the self without GET-params).
|
||||
metaTags.canonicalUrl.strict = 1
|
||||
|
||||
# cat=plugin.metaseo.metaTags/enable/23; type=boolean; label= Canonical Tag (No MP mode): Link all mount point links to origin pages.
|
||||
metaTags.canonicalUrl.noMP = 0
|
||||
|
||||
# cat=plugin.metaseo.metaTags/enable/24; type=boolean; label= OpenGraph Tags: Enable generation of OpenGraph Tags
|
||||
metaTags.opengraph = 1
|
||||
|
||||
# cat=plugin.metaseo.metaTags/enable/25; type=boolean; label= Publish Page Expire Time: Anounce Expire Tag (TYPO3's enddate in content elements).
|
||||
metaTags.useExpire = 1
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/26; type=string; label= P3P Compact Policy: W3C P3P Compact Policy String.
|
||||
metaTags.p3pCP =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/page/27; type=string; label= P3P Policy Url: URL to your W3C P3P Policy file.
|
||||
metaTags.p3pPolicyUrl =
|
||||
|
||||
# cat=plugin.metaseo.metaTags/enable/28; type=boolean; label= Link generation: Automatic generate index, up, prev und next links (metatags).
|
||||
metaTags.linkGeneration = 1
|
||||
|
||||
# cat=plugin.metaseo.metaTags/enable/29; type=boolean; label= Meta Description: Enable Dublin Core (DC.) metatags
|
||||
metaTags.enableDC = 1
|
||||
|
||||
# cat=plugin.metaseo.crawler/page/01; type=boolean; label= Crawler Robots-Tag: Enable robot-metatag
|
||||
metaTags.robotsEnable = 1
|
||||
# cat=plugin.metaseo.crawler/page/02; type=boolean; label= Crawler Index: Should the crawler (eg. Google) index the page and subpages
|
||||
metaTags.robotsIndex = 1
|
||||
# cat=plugin.metaseo.crawler/page/03; type=boolean; label= Crawler Follow: Should the crawler (eg. Google) follow links
|
||||
metaTags.robotsFollow = 1
|
||||
# cat=plugin.metaseo.crawler/page/04; type=boolean; label= Crawler Archive: Should the crawler (eg. Google) put the content of the page into the archive (eg. Google Cache)
|
||||
metaTags.robotsArchive = 1
|
||||
# cat=plugin.metaseo.crawler/page/05; type=boolean; label= Crawler Snippet: Should the crawler (eg. Google) show the snippet in the search result
|
||||
metaTags.robotsSnippet = 1
|
||||
# cat=plugin.metaseo.crawler/page/06; type=boolean; label= Crawler Noimageindex: Should the crawler (eg. Google) not index images
|
||||
metaTags.robotsNoImageindex = 0
|
||||
# cat=plugin.metaseo.crawler/page/07; type=boolean; label= Crawler Notranslate: Should the crawler (eg. Google) not translate content
|
||||
metaTags.robotsNoTranslate = 0
|
||||
# cat=plugin.metaseo.crawler/page/08; type=boolean; label= Crawler ODP: Should the crawler (eg. Google) use the description from the OpenDirectoryProject
|
||||
metaTags.robotsOdp = 1
|
||||
# cat=plugin.metaseo.crawler/page/09; type=boolean; label= Crawler YDir: Should the crawler (eg. Google) use the description from the Yahoo Directory
|
||||
metaTags.robotsYdir = 1
|
||||
|
||||
# cat=plugin.metaseo.userAgent/ie/1; type=options[,Highest Version=edge,10.x=10,9.x=9,8.x=8,7.x=7,6.x=6,5.x=5]; label= IE Compatibility Mode: Compatibility mode for Microsoft Internet Explorer.
|
||||
userAgent.ieCompatibilityMode =
|
||||
|
||||
# cat=plugin.metaseo.services/enable/01; type=boolean; label= Enable Services if header is disabled: If config.disableAllHeaderCode = 1 then services are automatically disabled (eg. for ajax calls) to prevent duplicate hits in google analytics/piwik (and/or javascript issues)
|
||||
services.enableIfHeaderIsDisabled = 0
|
||||
|
||||
# cat=plugin.metaseo.services/page/02; type=string; label= Google Crawler Verification: Verification code for google webmaster tools
|
||||
metaTags.googleVerification =
|
||||
|
||||
# cat=plugin.metaseo.services/page/03; type=string; label= MSN Crawler Verification: Verification code for msn webmaster tools
|
||||
metaTags.msnVerification =
|
||||
|
||||
# cat=plugin.metaseo.services/page/04; type=string; label= Yahoo! Crawler Verification: Verification code for yahoo! webmaster tools
|
||||
metaTags.yahooVerification =
|
||||
|
||||
# cat=plugin.metaseo.services/page/05; type=string; label= Web Of Trust Verification: Verification code for Web of trust (mywot.com)
|
||||
metaTags.wotVerification =
|
||||
|
||||
# cat=plugin.metaseo.services/page/06; type=string; label= Google Analytics: Code for google analytics (eg. UA-12345456-1) (multiple codes, comma separated)
|
||||
services.googleAnalytics =
|
||||
# cat=plugin.metaseo.services/page/07; type=string; label= Google Analytics Download & Click Domain Name: "auto", "none", single domain support: "example.com", subdomain support: ".example.com"
|
||||
services.googleAnalytics.domainName =
|
||||
# cat=plugin.metaseo.services/page/08; type=boolean; label= Google Analytics Anonymize IP: Enable anonymize IP
|
||||
services.googleAnalytics.anonymizeIp = 0
|
||||
# cat=plugin.metaseo.services/page/09; type=boolean; label= Google Analytics Track Downloads: Track downloads (with javascript) (BETA!)
|
||||
services.googleAnalytics.trackDownloads = 0
|
||||
|
||||
# cat=plugin.metaseo.services/page/11; type=string; label= Piwik URL: Url to your piwik installation (eg. www.example.com/piwik/ - don't use http:// or https:// as prefix!)
|
||||
services.piwik.url =
|
||||
# cat=plugin.metaseo.services/page/12; type=string; label= Piwik Id: Id of your website (multiple ids, comma separated)
|
||||
services.piwik.id =
|
||||
# cat=plugin.metaseo.services/page/13; type=string; label= Piwik Download & Click Domain Name: single domain support: "example.com", subdomain support: ".example.com"
|
||||
services.piwik.domainName =
|
||||
# cat=plugin.metaseo.services/page/14; type=string; label= Piwik Cookie Domain Name: single domain support: "example.com", subdomain support: ".example.com"
|
||||
services.piwik.cookieDomainName =
|
||||
# cat=plugin.metaseo.services/page/15; type=boolean; label= Piwik DoNotTrack: Opt Out users with Mozilla's DoNotTrack browser setting
|
||||
services.piwik.doNotTrack = 1
|
||||
|
||||
# cat=plugin.metaseo.social/page/1; type=string; label= Google+ Direct Connect: Your Google+ Profile Page ID (see https://developers.google.com/+/plugins/badge/)
|
||||
social.googleplus.profilePageId =
|
||||
|
||||
# cat=plugin.metaseo.pageTitle/enable/01; type=boolean; label= Apply Tmpl-Sitetitle to absolute <title>: This enables the addition of the template-sitetitle to the rendered page-title (in absolute <title>-mode)
|
||||
pageTitle.applySitetitleToPagetitle = 0
|
||||
|
||||
# cat=plugin.metaseo.pageTitle/enable/02; type=boolean; label= Apply Tmpl-Sitetitle to prefix/suffix: This enables the addition of the template-sitetitle to the rendered page-title (in pagetitle-prefix/suffix-mode)
|
||||
pageTitle.applySitetitleToPrefixSuffix = 1
|
||||
|
||||
# cat=plugin.metaseo.pageTitle/enable/03; type=string; label= Sitetitle glue: String between title and sitetitle (from template)
|
||||
pageTitle.sitetitleGlue = :
|
||||
|
||||
# cat=plugin.metaseo.pageTitle/enable/04; type=boolean; label= Sitetitle glue spacer (before): Add spacer between title and glue (from template)
|
||||
pageTitle.sitetitleGlueSpaceBefore = 0
|
||||
|
||||
# cat=plugin.metaseo.pageTitle/enable/05; type=boolean; label= Sitetitle glue spacer (after): Add spacer between glue and sitetitle (from template)
|
||||
pageTitle.sitetitleGlueSpaceAfter = 1
|
||||
|
||||
# cat=plugin.metaseo.pageTitle/enable/06; type=options[Sitetitle-Pagetitle=0, Pagetitle-Sitetitle=1]; label= Sitetitle position: Position of template-sitetitle in title
|
||||
pageTitle.sitetitlePosition = 0
|
||||
|
||||
# cat=plugin.metaseo.pageTitle/enable/07; type=string; label= Sitetitle : Overwrite the template sitetitle with a custom one
|
||||
pageTitle.sitetitle =
|
||||
|
||||
# cat=plugin.metaseo.sitemap/page/02; type=int+; label= Default page priority (0-100)
|
||||
sitemap.pagePriority =
|
||||
|
||||
# cat=plugin.metaseo.sitemap/page/03; type=options[,Always=1,Hourly=2,Daily=3,Weekly=4,Monthly=5,Yearly=6,Never (archive)=7]; label= Default change frequency: Default change frequency for sitemap cache (will be cached!)
|
||||
sitemap.changeFrequency =
|
||||
|
||||
# cat=plugin.metaseo.sitemap/page/04; type=int+; label= Default expiration: Sitemap entry expiration in days
|
||||
sitemap.expiration = 60
|
||||
|
||||
# cat=plugin.metaseo.sitemap/index/01; type=boolean; label= Index not static cacheable pages: Allow to index not static cacheable pages
|
||||
sitemap.index.allowNoStaticCachable = 0
|
||||
|
||||
# cat=plugin.metaseo.sitemap/index/01; type=boolean; label= Index no_cache pages: Allow to index no_cache pages
|
||||
sitemap.index.allowNoCache = 0
|
||||
}
|
||||
593
typo3conf/ext/metaseo/Configuration/TypoScript/setup.txt
Normal file
@@ -0,0 +1,593 @@
|
||||
###
|
||||
# This is the default TS-setup for metaseo
|
||||
#
|
||||
# (see Section Reference in the manual for more options & parameters)
|
||||
#
|
||||
###
|
||||
|
||||
## title tag changer
|
||||
config.titleTagFunction = Metaseo\Metaseo\Page\Part\PagetitlePart->main
|
||||
|
||||
page {
|
||||
# MetaSEO: Metatags
|
||||
headerData.84113002 = USER
|
||||
headerData.84113002 {
|
||||
userFunc = Metaseo\Metaseo\Page\Part\MetatagPart->main
|
||||
}
|
||||
|
||||
# MetaSEO: Pager Footer
|
||||
84113002 = USER
|
||||
84113002 {
|
||||
userFunc = Metaseo\Metaseo\Page\Part\FooterPart->main
|
||||
}
|
||||
}
|
||||
|
||||
# TypoScript added by extension "metaseo"
|
||||
plugin.metaseo =
|
||||
plugin.metaseo {
|
||||
# Page title generator
|
||||
pageTitle =
|
||||
pageTitle {
|
||||
# Caching of page title
|
||||
caching = 1
|
||||
|
||||
applySitetitleToPagetitle = {$plugin.metaseo.pageTitle.applySitetitleToPagetitle}
|
||||
applySitetitleToPrefixSuffix = {$plugin.metaseo.pageTitle.applySitetitleToPrefixSuffix}
|
||||
sitetitleGlue = {$plugin.metaseo.pageTitle.sitetitleGlue}
|
||||
sitetitleGlueSpaceBefore = {$plugin.metaseo.pageTitle.sitetitleGlueSpaceBefore}
|
||||
sitetitleGlueSpaceAfter = {$plugin.metaseo.pageTitle.sitetitleGlueSpaceAfter}
|
||||
sitetitlePosition = {$plugin.metaseo.pageTitle.sitetitlePosition}
|
||||
sitetitle = {$plugin.metaseo.pageTitle.sitetitle}
|
||||
|
||||
# list of stdWraps for advanced page title manipulations
|
||||
stdWrap =
|
||||
stdWrap {
|
||||
# stdWrap for raw page title (before processing)
|
||||
before =
|
||||
before {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for sitetitle (the title from the template, not from the page)
|
||||
sitetitle =
|
||||
sitetitle {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for processed page title (after processing)
|
||||
after =
|
||||
after {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Page metatag generator
|
||||
metaTags =
|
||||
metaTags {
|
||||
enableDC = {$plugin.metaseo.metaTags.enableDC}
|
||||
description = {$plugin.metaseo.metaTags.description}
|
||||
keywords = {$plugin.metaseo.metaTags.keywords}
|
||||
copyright = {$plugin.metaseo.metaTags.copyright}
|
||||
email = {$plugin.metaseo.metaTags.email}
|
||||
author = {$plugin.metaseo.metaTags.author}
|
||||
publisher = {$plugin.metaseo.metaTags.publisher}
|
||||
language = {$plugin.metaseo.metaTags.language}
|
||||
distribution = {$plugin.metaseo.metaTags.distribution}
|
||||
rating = {$plugin.metaseo.metaTags.rating}
|
||||
revisit = {$plugin.metaseo.metaTags.revisit}
|
||||
|
||||
p3pCP = {$plugin.metaseo.metaTags.p3pCP}
|
||||
p3pPolicyUrl = {$plugin.metaseo.metaTags.p3pPolicyUrl}
|
||||
|
||||
linkGeneration = {$plugin.metaseo.metaTags.linkGeneration}
|
||||
|
||||
robotsEnable = {$plugin.metaseo.metaTags.robotsEnable}
|
||||
robotsIndex = {$plugin.metaseo.metaTags.robotsIndex}
|
||||
|
||||
robotsIndex {
|
||||
# blacklist (RegExp, eg /typo3/)
|
||||
blacklist {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
robotsFollow = {$plugin.metaseo.metaTags.robotsFollow}
|
||||
robotsArchive = {$plugin.metaseo.metaTags.robotsArchive}
|
||||
robotsSnippet = {$plugin.metaseo.metaTags.robotsSnippet}
|
||||
robotsNoImageindex = {$plugin.metaseo.metaTags.robotsNoImageindex}
|
||||
robotsNoTranslate = {$plugin.metaseo.metaTags.robotsNoTranslate}
|
||||
robotsOdp = {$plugin.metaseo.metaTags.robotsOdp}
|
||||
robotsYdir = {$plugin.metaseo.metaTags.robotsYdir}
|
||||
|
||||
geoPositionLatitude = {$plugin.metaseo.metaTags.geoPositionLatitude}
|
||||
geoPositionLongitude = {$plugin.metaseo.metaTags.geoPositionLongitude}
|
||||
geoRegion = {$plugin.metaseo.metaTags.geoRegion}
|
||||
geoPlacename = {$plugin.metaseo.metaTags.geoPlacename}
|
||||
|
||||
googleVerification = {$plugin.metaseo.metaTags.googleVerification}
|
||||
msnVerification = {$plugin.metaseo.metaTags.msnVerification}
|
||||
yahooVerification = {$plugin.metaseo.metaTags.yahooVerification}
|
||||
wotVerification = {$plugin.metaseo.metaTags.wotVerification}
|
||||
|
||||
picsLabel = {$plugin.metaseo.metaTags.picsLabel}
|
||||
|
||||
useLastUpdate = {$plugin.metaseo.metaTags.useLastUpdate}
|
||||
|
||||
# canonical tag generator settings
|
||||
canonicalUrl = {$plugin.metaseo.metaTags.canonicalUrl}
|
||||
canonicalUrl {
|
||||
strict = {$plugin.metaseo.metaTags.canonicalUrl.strict}
|
||||
noMP = {$plugin.metaseo.metaTags.canonicalUrl.noMP}
|
||||
|
||||
# Default typolink configuration for canonical link
|
||||
typolink {
|
||||
|
||||
}
|
||||
|
||||
# blacklist (RegExp, eg /typo3/)
|
||||
blacklist {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
# OpenGraph metatags
|
||||
opengraph = {$plugin.metaseo.metaTags.opengraph}
|
||||
opengraph {
|
||||
site_name = TEXT
|
||||
site_name {
|
||||
data = TSFE:tmpl|sitetitle
|
||||
}
|
||||
|
||||
title = TEXT
|
||||
title {
|
||||
field = title
|
||||
}
|
||||
|
||||
type = article
|
||||
admins =
|
||||
email = {$plugin.metaseo.metaTags.email}
|
||||
phone_number =
|
||||
fax_number =
|
||||
latitude = {$plugin.metaseo.metaTags.geoPositionLatitude}
|
||||
longitude = {$plugin.metaseo.metaTags.geoPositionLongitude}
|
||||
street-address =
|
||||
locality = {$plugin.metaseo.metaTags.geoPlacename}
|
||||
region = {$plugin.metaseo.metaTags.geoRegion}
|
||||
postal-code =
|
||||
country-name =
|
||||
}
|
||||
|
||||
useExpire = {$plugin.metaseo.metaTags.useExpire}
|
||||
|
||||
ieCompatibilityMode = {$plugin.metaseo.userAgent.ieCompatibilityMode}
|
||||
|
||||
# basic configuration for metatag information
|
||||
conf =
|
||||
conf {
|
||||
description_page.field = description
|
||||
keywords_page.field = keywords
|
||||
title_page.field = title
|
||||
author_page.field = author
|
||||
email_page.field = author_email
|
||||
|
||||
tx_metaseo_geo_lat.field = tx_metaseo_geo_lat
|
||||
tx_metaseo_geo_long.field = tx_metaseo_geo_long
|
||||
tx_metaseo_geo_place.field = tx_metaseo_geo_place
|
||||
tx_metaseo_geo_region.field = tx_metaseo_geo_region
|
||||
|
||||
lastUpdate_page = TEXT
|
||||
lastUpdate_page {
|
||||
data = page:lastUpdated
|
||||
stdWrap.ifEmpty.data = register : SYS_LASTCHANGED
|
||||
date = c
|
||||
}
|
||||
}
|
||||
|
||||
# section links (start, up, next, prev)
|
||||
sectionLinks =
|
||||
sectionLinks {
|
||||
prev = HMENU
|
||||
prev {
|
||||
special = browse
|
||||
special {
|
||||
items = prev
|
||||
prev.fields.title =
|
||||
}
|
||||
|
||||
1 = TMENU
|
||||
1.NO {
|
||||
wrapItemAndSub = {field:uid}
|
||||
wrapItemAndSub.insertData = 1
|
||||
doNotLinkIt = 1
|
||||
}
|
||||
}
|
||||
|
||||
next = HMENU
|
||||
next {
|
||||
special = browse
|
||||
special {
|
||||
items = next
|
||||
next.fields.title =
|
||||
}
|
||||
|
||||
1 = TMENU
|
||||
1.NO {
|
||||
wrapItemAndSub = {field:uid}
|
||||
wrapItemAndSub.insertData = 1
|
||||
doNotLinkIt = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# list of stdWraps for advanced metatag manipulations
|
||||
stdWrap =
|
||||
stdWrap {
|
||||
# stdWrap for title
|
||||
title =
|
||||
title {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for description
|
||||
description =
|
||||
description {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for keywords
|
||||
keywords =
|
||||
keywords {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for copyright
|
||||
copyright =
|
||||
copyright {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for language
|
||||
language =
|
||||
language {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for email
|
||||
email =
|
||||
email {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for author
|
||||
author =
|
||||
author {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for publisher
|
||||
publisher =
|
||||
publisher {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for distribution
|
||||
distribution =
|
||||
distribution {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for rating
|
||||
rating =
|
||||
rating {
|
||||
|
||||
}
|
||||
|
||||
# stdWrap for lastUpdate
|
||||
lastUpdate =
|
||||
lastUpdate {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Advanced services (google analytics, piwik ...)
|
||||
services =
|
||||
services {
|
||||
# Google Analytics configuration
|
||||
googleAnalytics = {$plugin.metaseo.services.googleAnalytics}
|
||||
googleAnalytics {
|
||||
# show google analytics if user is logged in be (default is disable, we don't want to track be-users)
|
||||
showIfBeLogin = 0
|
||||
|
||||
anonymizeIp = {$plugin.metaseo.services.googleAnalytics.anonymizeIp}
|
||||
domainName = {$plugin.metaseo.services.googleAnalytics.domainName}
|
||||
|
||||
trackDownloads = {$plugin.metaseo.services.googleAnalytics.trackDownloads}
|
||||
trackDownloadsScript = EXT:metaseo/Resources/Public/Frontend/JavaScript/GoogleAnalyticsTrackDownload.js
|
||||
|
||||
customizationCode =
|
||||
enableIfHeaderIsDisabled = {$plugin.metaseo.services.enableIfHeaderIsDisabled}
|
||||
|
||||
## google analytics template code
|
||||
template = COA
|
||||
template {
|
||||
10 = FLUIDTEMPLATE
|
||||
10 {
|
||||
file = EXT:metaseo/Resources/Private/Templates/PageParts/ServiceGoogleAnalytics.html
|
||||
variables {
|
||||
gaCode = TEXT
|
||||
gaCode.field = gaCode
|
||||
|
||||
gaCustomizationCode = TEXT
|
||||
gaCustomizationCode.field = gaCustomizationCode
|
||||
|
||||
gaIsAnonymize = TEXT
|
||||
gaIsAnonymize.field = gaIsAnonymize
|
||||
|
||||
gaDomainName = TEXT
|
||||
gaDomainName.field = gaDomainName
|
||||
|
||||
gaUseUniversalAnalytics = TEXT
|
||||
gaUseUniversalAnalytics.field = gaUseUniversalAnalytics
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Piwik configuration
|
||||
piwik =
|
||||
piwik {
|
||||
# show piwik if user is logged in be (default is disable, we don't want to track be-users)
|
||||
showIfBeLogin = 0
|
||||
url = {$plugin.metaseo.services.piwik.url}
|
||||
id = {$plugin.metaseo.services.piwik.id}
|
||||
|
||||
domainName = {$plugin.metaseo.services.piwik.domainName}
|
||||
cookieDomainName = {$plugin.metaseo.services.piwik.cookieDomainName}
|
||||
doNotTrack = {$plugin.metaseo.services.piwik.doNotTrack}
|
||||
customizationCode =
|
||||
|
||||
enableIfHeaderIsDisabled = {$plugin.metaseo.services.enableIfHeaderIsDisabled}
|
||||
|
||||
## piwik template code
|
||||
template = COA
|
||||
template {
|
||||
10 = FLUIDTEMPLATE
|
||||
10 {
|
||||
file = EXT:metaseo/Resources/Private/Templates/PageParts/ServicePiwik.html
|
||||
variables {
|
||||
piwikUrl = TEXT
|
||||
piwikUrl.field = piwikUrl
|
||||
|
||||
piwikId = TEXT
|
||||
piwikId.field = piwikId
|
||||
|
||||
piwikCustomizationCode = TEXT
|
||||
piwikCustomizationCode.field = piwikCustomizationCode
|
||||
|
||||
piwikDomainName = TEXT
|
||||
piwikDomainName.field = piwikDomainName
|
||||
|
||||
piwikCookieDomainName = TEXT
|
||||
piwikCookieDomainName.field = piwikCookieDomainName
|
||||
|
||||
piwikDoNotTrack = TEXT
|
||||
piwikDoNotTrack.field = piwikDoNotTrack
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Social services (Google+,...)
|
||||
social =
|
||||
social {
|
||||
googlePlus =
|
||||
googlePlus {
|
||||
profilePageId = {$plugin.metaseo.social.googleplus.profilePageId}
|
||||
}
|
||||
}
|
||||
|
||||
# Sitemap indexer and generator
|
||||
sitemap =
|
||||
sitemap {
|
||||
pagePriority = {$plugin.metaseo.sitemap.pagePriority}
|
||||
changeFrequency = {$plugin.metaseo.sitemap.changeFrequency}
|
||||
expiration = {$plugin.metaseo.sitemap.expiration}
|
||||
|
||||
# indexer settings
|
||||
index {
|
||||
# blacklist (RegExp, eg /typo3/)
|
||||
blacklist {
|
||||
|
||||
}
|
||||
|
||||
# Blacklist for SetupTS PAGE object typeNums
|
||||
pageTypeBlacklist =
|
||||
|
||||
allowNoStaticCachable = {$plugin.metaseo.sitemap.index.allowNoStaticCachable}
|
||||
allowNoCache = {$plugin.metaseo.sitemap.index.allowNoCache}
|
||||
|
||||
# Whitelist of allowed file extensions
|
||||
fileExtension {
|
||||
# PDF
|
||||
1 = pdf
|
||||
|
||||
# Microsoft Office
|
||||
2 = doc,docx,xls,xlsx,ppt,pptx
|
||||
|
||||
# OpenOffice
|
||||
3 = odt,odp,ods,odg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Robots.txt configuration
|
||||
robotsTxt =
|
||||
robotsTxt {
|
||||
# Default robots.txt if no config is found
|
||||
default = COA
|
||||
default {
|
||||
10 = TEXT
|
||||
10 {
|
||||
value (
|
||||
User-agent: *
|
||||
Disallow: /fileadmin/_temp_/
|
||||
Disallow: /t3lib/
|
||||
Disallow: /typo3/
|
||||
Disallow: /typo3_src/
|
||||
Disallow: /typo3conf/
|
||||
Disallow: /clear.gif
|
||||
Allow: /typo3/sysext/frontend/Resources/Public/*
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
90 = TEXT
|
||||
90 {
|
||||
value (
|
||||
Sitemap: %sitemap%
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
# Extra robots.txt, will added even if robots.txt is found
|
||||
extra = COA
|
||||
extra {
|
||||
|
||||
}
|
||||
|
||||
# Robots.txt marker (search/replace, eg. %name%)
|
||||
marker =
|
||||
marker {
|
||||
sitemap = TEXT
|
||||
sitemap {
|
||||
typolink {
|
||||
parameter.data = leveluid:0
|
||||
parameter.wrap = |,841132
|
||||
returnLast = url
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# MetaSEO TXT Sitemap
|
||||
metaSeoSitemapTxt = PAGE
|
||||
metaSeoSitemapTxt {
|
||||
typeNum = 841131
|
||||
|
||||
config {
|
||||
linkVars < config.linkVars
|
||||
linkVars := removeFromList(type)
|
||||
}
|
||||
|
||||
10 = USER_INT
|
||||
10 {
|
||||
userFunc = Metaseo\Metaseo\Page\SitemapTxtPage->main
|
||||
}
|
||||
|
||||
config {
|
||||
disableAllHeaderCode = 1
|
||||
additionalHeaders = Content-type:text/plain;charset=UTF-8
|
||||
xhtml_cleaning = 0
|
||||
|
||||
## disable static documents and stuff
|
||||
simulateStaticDocuments = 0
|
||||
tx_realurl_enable = 0
|
||||
tx_cooluri_enable = 0
|
||||
sourceopt.enabled = 0
|
||||
|
||||
## disable indexed search
|
||||
index_enable = 0
|
||||
|
||||
## disable features
|
||||
insertDmailerBoundaries = 0
|
||||
admPanel = 0
|
||||
stat = 0
|
||||
jumpurl_enable = 0
|
||||
debug = 0
|
||||
message_preview = #
|
||||
}
|
||||
}
|
||||
|
||||
# MetaSEO XML Sitemap
|
||||
metaSeoSitemapXml = PAGE
|
||||
metaSeoSitemapXml {
|
||||
typeNum = 841132
|
||||
|
||||
config {
|
||||
linkVars < config.linkVars
|
||||
linkVars := removeFromList(type)
|
||||
}
|
||||
|
||||
10 = USER_INT
|
||||
10 {
|
||||
userFunc = Metaseo\Metaseo\Page\SitemapXmlPage->main
|
||||
}
|
||||
|
||||
config {
|
||||
disableAllHeaderCode = 1
|
||||
additionalHeaders = Content-type:application/xml;charset=UTF-8
|
||||
xhtml_cleaning = 0
|
||||
|
||||
## disable static documents and stuff
|
||||
simulateStaticDocuments = 0
|
||||
tx_realurl_enable = 0
|
||||
tx_cooluri_enable = 0
|
||||
sourceopt.enabled = 0
|
||||
|
||||
## disable indexed search
|
||||
index_enable = 0
|
||||
|
||||
## disable features
|
||||
insertDmailerBoundaries = 0
|
||||
admPanel = 0
|
||||
stat = 0
|
||||
jumpurl_enable = 0
|
||||
debug = 0
|
||||
message_preview = <!-- -->
|
||||
}
|
||||
}
|
||||
|
||||
# MetaSEO Robots.txt
|
||||
metaSeoRobotsTxt = PAGE
|
||||
metaSeoRobotsTxt {
|
||||
typeNum = 841133
|
||||
|
||||
10 = USER_INT
|
||||
10 {
|
||||
userFunc = Metaseo\Metaseo\Page\RobotsTxtPage->main
|
||||
}
|
||||
|
||||
config {
|
||||
disableAllHeaderCode = 1
|
||||
additionalHeaders = Content-type:text/plain;charset=UTF-8
|
||||
xhtml_cleaning = 0
|
||||
|
||||
## disable static documents and stuff
|
||||
simulateStaticDocuments = 0
|
||||
tx_realurl_enable = 0
|
||||
tx_cooluri_enable = 0
|
||||
sourceopt.enabled = 0
|
||||
|
||||
## disable indexed search
|
||||
index_enable = 0
|
||||
|
||||
## disable features
|
||||
insertDmailerBoundaries = 0
|
||||
admPanel = 0
|
||||
stat = 0
|
||||
jumpurl_enable = 0
|
||||
debug = 0
|
||||
message_preview = #
|
||||
}
|
||||
}
|
||||
|
||||
#####
|
||||
# Ext: news
|
||||
####
|
||||
|
||||
plugin.tx_news.settings.detail.registerProperties := addToList(keywords,title,teaser,authoremail)
|
||||
@@ -0,0 +1,251 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _admin-manual:
|
||||
|
||||
Administrator Manual
|
||||
====================
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
- Install Extension via Extension Manager.
|
||||
- Include “static extension template” (Template → Info/Modify → Edit the whole template record → “Include static (from extensions):” and select “MetaSEO”)
|
||||
- *Optional:* If you want to import your settings from the predecessor "tq_seo" install the "metaseo_tqseo_import" extension and run the importer.
|
||||
- Modify your metatags via constants editor
|
||||
|
||||
Indexed Sitemap
|
||||
---------------
|
||||
|
||||
The sitemap will automatically collect all cacheable sites and provides a XML- and plaintext-output – that's why it is “indexed”.
|
||||
|
||||
The XML-Sitemap (eg. for Google) is available with: index.php?type=841132
|
||||
The TXT-Sitemap is available with: index.php?type=841131
|
||||
|
||||
If you have more than one tree in your TYPO3 you will have to add the root-PID to your Sitemap, e.g.:
|
||||
|
||||
- Tree #1 with PID 123: index.php?id=123&type=841132
|
||||
- Tree #2 with PID 234: index.php?id=234&type=841132
|
||||
|
||||
If you have also enabled “sitemap_ObeySysLanguage” in the extension configuration you also have to add the language-id for your Sitemap - eg. for separated language-domain e.g. example.com (only english pages) and example.de (only german pages).
|
||||
|
||||
The sitemap will index ALL cacheable pages with full extension support (like tt_news and all other “clean” extensions).
|
||||
If your extension doesn't use cHash or use no_cache the output WILL NOT be included in the sitemap (and also will not be indexed by index_search).
|
||||
|
||||
The sitemap indexes all generate “typolinks” (BETA).
|
||||
|
||||
**Warning:**
|
||||
The MetaSEO Sitemap relies on the TYPO3 caching system. If an extension (or configuration – e.g. RealURL configuration) breaks the caching system and makes TSFE non-cacheable (TSFE->no_cache) the sites will NOT be INDEXED!
|
||||
Make sure no extension will set no_cache and the cHash of your link is valid. This is the only way to get just valid URLs into your sitemap.
|
||||
|
||||
This sitemap supports both, pibase and extbase extensions without problems. However the developer must take care of the cHash-handling.
|
||||
|
||||
Robots.txt
|
||||
----------
|
||||
The robots.txt can be generated with type 841133, e.g.:
|
||||
index.php?type=841133
|
||||
|
||||
If possible and enabled the robots.txt builder will automatically add the link to the sitemap generator or the static sitemap files (will require TYPO3 scheduler task to generate the static sitemap).
|
||||
|
||||
Scheduler Tasks
|
||||
---------------
|
||||
|
||||
============================================= =============================================================== ======================
|
||||
Scheduler Task Description Frequency
|
||||
============================================= =============================================================== ======================
|
||||
MetaSEO Cleanup This task cleans up old database entries in the One run per day
|
||||
tx_metaseo_sitemap table.
|
||||
|
||||
MetaSEO sitemap.txt builder This task builds a real sitemap.txt file in the One run per day
|
||||
upload directory.
|
||||
|
||||
- Directory: uploads/tx_metaseo/sitemap_txt/
|
||||
- Sitemap: sitemap-r{ROOTPID}.txt.gz
|
||||
|
||||
If language domain support is active:
|
||||
|
||||
- Sitemap: sitemap-r{ROOTPID}-l{LANG}.txt.gz
|
||||
|
||||
{ROOTPID} is the Page-UID from the root pages in
|
||||
your TYPO3 installations.
|
||||
|
||||
{LANG} is the language id (only active if language
|
||||
domains are active).
|
||||
|
||||
Hint: These files are already gzipped.
|
||||
|
||||
MetaSEO sitemap.xml builder This task builds a real sitemap.xml files in the One run per day
|
||||
upload directory.
|
||||
|
||||
- Directory: uploads/tx_metaseo/sitemap_xml/
|
||||
- Sitemap-Index: index-r{ROOTPID}.xml.gz
|
||||
- Sitemap-Page: sitemap-r{ROOTPID}-p{PAGE}.xml.gz
|
||||
|
||||
If language domain support is active:
|
||||
|
||||
- Sitemap-Index: index-r{ROOTPID}-l{LANG}.xml.gz
|
||||
- Sitemap-Page: sitemap-r{ROOTPID}-l{LANG}-p{PAGE}.xml.gz
|
||||
|
||||
{ROOTPID} is the Page-UID from the root pages in your
|
||||
TYPO3 installations.
|
||||
|
||||
{PAGE} is the current page of the sitemap.
|
||||
|
||||
{LANG} is the language id (only active if language
|
||||
domains are active).
|
||||
|
||||
The index will refer to all page sitemaps so you only
|
||||
have to reference to the sitemap index.
|
||||
|
||||
Hint: These files are already gzipped.
|
||||
============================================= =============================================================== ======================
|
||||
|
||||
|
||||
RealURL Configuration
|
||||
---------------------
|
||||
|
||||
If you want to activate a “real” sitemap.xml feature (eg. http://example.com/sitemap.xml), configure realurl like this:
|
||||
|
||||
::
|
||||
|
||||
<?php
|
||||
$TYPO3_CONF_VARS['EXTCONF']['realurl']['_DEFAULT'] = array(
|
||||
|
||||
'init' => array(
|
||||
// ...
|
||||
),
|
||||
|
||||
|
||||
'preVars' => array(
|
||||
// ...
|
||||
),
|
||||
|
||||
'fixedPostVars' => array(
|
||||
// ...
|
||||
),
|
||||
|
||||
'postVarSets' => array(
|
||||
'_DEFAULT' => array(
|
||||
|
||||
// TT-NEWS (example configuration)
|
||||
'date' => array(
|
||||
array(
|
||||
'GETvar' => 'tx_ttnews[year]' ,
|
||||
),
|
||||
array(
|
||||
'GETvar' => 'tx_ttnews[month]' ,
|
||||
'valueMap' => array(
|
||||
'january' => '01',
|
||||
'february' => '02',
|
||||
'march' => '03',
|
||||
'april' => '04',
|
||||
'may' => '05',
|
||||
'june' => '06',
|
||||
'july' => '07',
|
||||
'august' => '08',
|
||||
'september' => '09',
|
||||
'october' => '10',
|
||||
'november' => '11',
|
||||
'december' => '12',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'GETvar' => 'tx_ttnews[day]',
|
||||
),
|
||||
),
|
||||
|
||||
// news pagebrowser
|
||||
'browse' => array(
|
||||
array(
|
||||
'GETvar' => 'tx_ttnews[pointer]',
|
||||
),
|
||||
),
|
||||
|
||||
// news categories
|
||||
'news-category' => array (
|
||||
array(
|
||||
'GETvar' => 'tx_ttnews[cat]',
|
||||
'lookUpTable' => array(
|
||||
'table' => 'tt_news_cat',
|
||||
'id_field' => 'uid',
|
||||
'alias_field' => 'title',
|
||||
'addWhereClause' => ' AND NOT deleted',
|
||||
'useUniqueCache' => 1,
|
||||
'useUniqueCache_conf' => array(
|
||||
'strtolower' => 1,
|
||||
'spaceCharacter' => '-',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// news articles
|
||||
'article' => array(
|
||||
array(
|
||||
'GETvar' => 'tx_ttnews[tt_news]',
|
||||
'lookUpTable' => array(
|
||||
'table' => 'tt_news',
|
||||
'id_field' => 'uid',
|
||||
'alias_field' => 'title',
|
||||
'addWhereClause' => ' AND NOT deleted',
|
||||
'useUniqueCache' => 1,
|
||||
'useUniqueCache_conf' => array(
|
||||
'strtolower' => 1,
|
||||
'spaceCharacter' => '-',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// ... other extensions ...
|
||||
),
|
||||
),
|
||||
|
||||
'fileName' => array(
|
||||
'defaultToHTMLsuffixOnPrev' => 1,
|
||||
'index' => array(
|
||||
// ...
|
||||
|
||||
'sitemap.xml' => array(
|
||||
'keyValues' => array(
|
||||
'type' => 841132,
|
||||
),
|
||||
),
|
||||
|
||||
'sitemap.txt' => array(
|
||||
'keyValues' => array(
|
||||
'type' => 841131,
|
||||
),
|
||||
),
|
||||
|
||||
'robots.txt' => array(
|
||||
'keyValues' => array(
|
||||
'type' => 841133,
|
||||
),
|
||||
),
|
||||
|
||||
'_DEFAULT' => array(
|
||||
'keyValues' => array(
|
||||
'type' => 0,
|
||||
)
|
||||
),
|
||||
|
||||
),
|
||||
),
|
||||
|
||||
'pagePath' => array(
|
||||
'type' => 'user',
|
||||
'userFunc' => 'EXT:realurl/class.tx_realurl_advanced.php:&tx_realurl_advanced->main',
|
||||
'spaceCharacter' => '-',
|
||||
'segTitleFieldList' => 'tx_realurl_pathsegment,alias,nav_title,title',
|
||||
'languageGetVar' => 'L',
|
||||
'expireDays' => 30,
|
||||
'rootpage_id' => 1,
|
||||
),
|
||||
|
||||
);
|
||||
60
typo3conf/ext/metaseo/Documentation/BackendModules/Index.rst
Normal file
@@ -0,0 +1,60 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _backend-modules:
|
||||
|
||||
Backend Modules
|
||||
===============
|
||||
|
||||
SEO Page Module (Website -> SEO)
|
||||
--------------------------------
|
||||
|
||||
.. figure:: ../Images/Introduction/ModuleSeoMetatags.png
|
||||
:scale: 80%
|
||||
:alt: Backend Module - SEO Metatags
|
||||
|
||||
The SEO page module provides an overview for all seo relevant information (including possibility to edit this information on click).
|
||||
|
||||
============================== ==========================================================
|
||||
Module Description
|
||||
============================== ==========================================================
|
||||
Metatags Overview for all relevant metatags
|
||||
|
||||
Geo position Overview for geo positioning
|
||||
|
||||
SearchEngines Overview for all relevant search engine settings
|
||||
including sitemap stuff
|
||||
|
||||
URL Handling Overview for all relevant url handling stuff including
|
||||
RealURL support and possibility to simulate the url.
|
||||
|
||||
Pagetitle Overview for all relevant pagetitle information and
|
||||
possibility to simulate the pagetitle.
|
||||
|
||||
Pagetitle simulator (Slow!) Simulates the pagetitle generation for the current
|
||||
selected tree.
|
||||
============================== ==========================================================
|
||||
|
||||
|
||||
SEO Control Center (SEO -> Control Center)
|
||||
------------------------------------------
|
||||
|
||||
.. figure:: ../Images/Introduction/ModuleSeoControlCenter.png
|
||||
:scale: 80%
|
||||
:alt: Backend Module - SEO Control Center
|
||||
|
||||
The SEO control center lists all your root-pages in your TYPO3 installation. For each root page you can control specific sitemap and robots.txt settings.
|
||||
|
||||
SEO Sitemap (SEO -> Sitemap)
|
||||
----------------------------
|
||||
|
||||
.. figure:: ../Images/Introduction/ModuleSeoSitemap.png
|
||||
:scale: 80%
|
||||
:alt: Backend Module - SEO Sitemap
|
||||
|
||||
The SEO sitemap module provides access to the indexed sitemap list.
|
||||
23
typo3conf/ext/metaseo/Documentation/ChangeLog/Index.rst
Normal file
@@ -0,0 +1,23 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _changelog:
|
||||
|
||||
Changelog
|
||||
=========
|
||||
|
||||
============= ==============================================================================
|
||||
Version Changes
|
||||
============= ==============================================================================
|
||||
1.0.0 **Fork of Fork of predecessor "tq_seo"**
|
||||
|
||||
- Major improvements of features and codebase
|
||||
- Fixed several major and minor bugs
|
||||
- Fixed manual (now reStructuredText)
|
||||
- Fixed sitemap url generation in TYPO3 scheduler
|
||||
============= ==============================================================================
|
||||
282
typo3conf/ext/metaseo/Documentation/Constants/Index.rst
Normal file
@@ -0,0 +1,282 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _constants:
|
||||
|
||||
Constants
|
||||
=========
|
||||
|
||||
MetaTags
|
||||
--------
|
||||
============================== ========================================================== =================
|
||||
Constant Description Default
|
||||
============================== ========================================================== =================
|
||||
Last Update time Publish the update time of the current page *enabled*
|
||||
|
||||
Detect Language Publish the current TYPO3-FE-language as metatag *enabled*
|
||||
|
||||
Canonical Tag Publish canonical link if possible *enabled*
|
||||
(TYPO3-cache is enabled and cHash is valid)
|
||||
or if user entered canonical tag into page options. *disabled*
|
||||
|
||||
Canonical Tag (Strict mode) Enable strict mode (all wrong GET-parameters will *enabled*
|
||||
generate a canonical-tag to the self without GET-params).
|
||||
|
||||
e.g. /index.php?id=123&foo=bar would generate a
|
||||
Canonical-Tag pointing to /index.php?id=123
|
||||
if the cHash is wrong or caching is disabled
|
||||
|
||||
Canonical Tag (No MP mode) Prevent canonical links to contain mountpoint information. *disabled*
|
||||
Useful if some pages would count as duplicate content
|
||||
because of mountpoints.
|
||||
|
||||
Publish Page Expire Time Publish expire date from the “End Date” of the page. *enabled*
|
||||
Currently only used for Google.
|
||||
|
||||
Link generation Automatic generate index and up/next/prev-links. *enabled*
|
||||
|
||||
Enable Dublin Core (DC.) tags Enable/Disable output of dublin core (DC) metatags *enabled*
|
||||
|
||||
Description Default description of your pages.
|
||||
|
||||
Overwritten by description of page
|
||||
|
||||
Keywords Default list of keywords
|
||||
|
||||
Overwritten by keywords of page
|
||||
|
||||
Copyright info Copyright information of your page
|
||||
|
||||
Reply-to email E-Mail address for contact
|
||||
|
||||
Author Default author
|
||||
|
||||
Overwritten by author of page
|
||||
|
||||
Publisher Publisher of the website
|
||||
|
||||
Language Overwrite language detection
|
||||
|
||||
Rating Rating of the website
|
||||
|
||||
Distribution Distribution of your website
|
||||
|
||||
Revisit after Number of days between search engine visits
|
||||
|
||||
Geo Location Geo location of your web page with latitude,
|
||||
longitude, region and placename
|
||||
|
||||
PICS-label Platform for Internet Content Selection
|
||||
|
||||
- http://www.w3.org/PICS/labels.html
|
||||
|
||||
P3P Compact Policy Your P3P Compact Policy.
|
||||
|
||||
More information about P3P:
|
||||
|
||||
- http://www.w3.org/P3P/
|
||||
- http://www.w3.org/TR/P3P/
|
||||
- https://en.wikipedia.org/wiki/P3P
|
||||
- http://www.p3pwriter.com/LRN_111.asp
|
||||
|
||||
P3P Policy Url Link (full URL) to your P3P Policy File
|
||||
============================== ========================================================== =================
|
||||
|
||||
Some metatags also have markers which could be build in, following metatags supports markers:
|
||||
|
||||
- Title
|
||||
- Description
|
||||
- Keywords
|
||||
- Copyright
|
||||
- Publisher
|
||||
|
||||
Following Markers are available:
|
||||
|
||||
============================== ========================================================== =================
|
||||
Marker Description Example value
|
||||
============================== ========================================================== =================
|
||||
%YEAR% Replacement for the current year 2014
|
||||
============================== ========================================================== =================
|
||||
|
||||
UserAgent
|
||||
---------
|
||||
============================== ========================================================== =================
|
||||
Constant Description Default
|
||||
============================== ========================================================== =================
|
||||
IE Compatibility Mode Compatibility mode for Microsoft Internet Explorer
|
||||
============================== ========================================================== =================
|
||||
|
||||
|
||||
Crawler
|
||||
-------
|
||||
============================== ========================================================== =================
|
||||
Constant Description Default
|
||||
============================== ========================================================== =================
|
||||
Crawler Robots-Tag Enable crawler "robot"-tag (and all other settings below) *enabled*
|
||||
|
||||
Index Should the crawler index your website? *enabled*
|
||||
|
||||
Follow Should the crawler follow links on your website? *enabled*
|
||||
|
||||
Archive Is the crawler allowed to archive the page *enabled*
|
||||
(e.g. Google cache)
|
||||
|
||||
Snippet Should the crawler use the snippet/description *enabled*
|
||||
in search results
|
||||
|
||||
ODP Should the crawler use the OpenDirectoryProject to *enabled*
|
||||
display the description in search results
|
||||
|
||||
YDir Should the crawler use the YahooDirectory to *enabled*
|
||||
display the description in search results
|
||||
============================== ========================================================== =================
|
||||
|
||||
|
||||
Services
|
||||
--------
|
||||
============================== =============================================================== =================
|
||||
Constant Description Default
|
||||
============================== =============================================================== =================
|
||||
Crawler Verification Verification code for Google, MSN and Yahoo
|
||||
webmaster tools and Web of trust
|
||||
|
||||
Google Analytics The google analytics code for using on your site
|
||||
Multiple GA Codes possible, comma separated
|
||||
(Will not be shown in frontend if BE-user is logged in,
|
||||
can be re-enabled in BE-Login-Mode:
|
||||
plugin.metaseo.services.googleAnalytics.showIfBeLogin = 1)
|
||||
|
||||
GA Cookie Domain Name If you want to limit the current google analytics to
|
||||
one domain (or subdomain) set the domain name here, eg.:
|
||||
|
||||
- “auto” (default in google analytics)
|
||||
- “none”
|
||||
- single domain (eg. “example.com”)
|
||||
- subdomain (eg. “.example.com”)
|
||||
|
||||
GA Anonymize IP Anonymize the last part of the IP *disabled*
|
||||
(may be required in some countries)
|
||||
|
||||
GA Track Downloads Try to track downloads with google analytics. *disabled*
|
||||
|
||||
See res/ga-track-download.js for more details
|
||||
|
||||
Currently supported files:
|
||||
|
||||
- doc,docx,xls,ppt,odt,ods,pdf,zip,tar,gz,txt,vsd,vxd,
|
||||
rar,exe,wma,mov,avi,ogg,ogm,mkv,wmv,mp3,webm
|
||||
|
||||
Piwik URL Url to your Piwik installation
|
||||
|
||||
(without http:// and https://)
|
||||
|
||||
Piwik ID Tracking id of your website in your piwik
|
||||
Multiple Piwik IDs possible, comma separated
|
||||
|
||||
Piwik Download & Click Domain Specifies which domains are internal domains:
|
||||
|
||||
- single domain (eg. “example.com”)
|
||||
- subdomain (eg. “.example.com”)
|
||||
|
||||
For more information visit:
|
||||
|
||||
- https://developer.piwik.org/api-reference/tracking-javascript
|
||||
|
||||
Piwik Cookie Domain Name Specifies the domain name for the tracking cookie:
|
||||
|
||||
- single domain (eg. “example.com”)
|
||||
- subdomain (eg. “.example.com”)
|
||||
|
||||
For more information visit:
|
||||
|
||||
- https://developer.piwik.org/api-reference/tracking-javascript
|
||||
|
||||
Piwik DoNotTrack Opt out users with Mozilla's DoNotTrack *enabled*
|
||||
browser setting
|
||||
============================== =============================================================== =================
|
||||
|
||||
|
||||
Social
|
||||
------
|
||||
============================== ========================================================== =================
|
||||
Constant Description Default
|
||||
============================== ========================================================== =================
|
||||
Google+ Direct Connect Your Google+ profile page ID
|
||||
|
||||
see https://developers.google.com/+/web/badge/
|
||||
============================== ========================================================== =================
|
||||
|
||||
PageTitle
|
||||
---------
|
||||
========================================= ========================================================== ======================
|
||||
Constant Description Default
|
||||
========================================= ========================================================== ======================
|
||||
Apply tmpl-sitetitle to absolute <title> There is a prefix/suffix for your pagetitle defined *disabled*
|
||||
in your root template settings.
|
||||
|
||||
If you use the SEO-Absolute-Pagetitle settings you
|
||||
can disable this suffix/prefix here.
|
||||
|
||||
Apply tmpl-sitetitle to prefix/suffix There is a prefix/suffix for your pagetitle defined *enabled*
|
||||
in your root template settings.
|
||||
|
||||
If you use the SEO-Pagetitle-Suffix/Prefix settings you
|
||||
can disable this suffix/prefix here.
|
||||
|
||||
Sitetitle glue Glue between Pagetitle (from Page) and :
|
||||
Sitetitle (from template)
|
||||
|
||||
Sitetitle glue spacer (before) Add spacer before glue string *disabled*
|
||||
|
||||
Sitetitle glue spacer (after) Add spacer after glue string *enabled*
|
||||
|
||||
Sitetitle position Position of Sitetitle (from template) Sitetitle-Pagetitle
|
||||
Possible options: (0)
|
||||
|
||||
Sitetitle-Pagetitle (eg. Example Company: About us)
|
||||
Pagetitle-Sitetitle (eg. About us: Example Company)
|
||||
|
||||
Sitetitle Overwrite the template sitetitle with a custom one
|
||||
========================================= ========================================================== ======================
|
||||
|
||||
Sitemap
|
||||
-------
|
||||
================================= ========================================================== =================
|
||||
Constant Description Default
|
||||
================================= ========================================================== =================
|
||||
Enable Enables output (if set on root-pid of tree) and *enabled*
|
||||
indexing for the whole subtree
|
||||
|
||||
Page limit Limit pages on sitemap-xml-pages *10000*
|
||||
|
||||
Limit to current language Limit output of the sitemap to the current language. *disabled*
|
||||
This will enable multi-language-domain sitemaps. eg:
|
||||
|
||||
- www.example.com (FE-Language is english) will output
|
||||
only english pages
|
||||
- www.example.de (FE-Language is german) will output
|
||||
only german pages
|
||||
|
||||
This option was ported from the extension configuration
|
||||
and will replace this configuration.
|
||||
|
||||
Default change frequency Default change frequency for sitemap cache
|
||||
(will be cached!)
|
||||
|
||||
Page priority Default page priority if the page has no own 1
|
||||
priority set
|
||||
|
||||
Page priority will be calculated by:
|
||||
|
||||
( [page priority] – [priority modificator] ) *
|
||||
( 1/[page depth] * [page multiplier] )
|
||||
|
||||
Page priority depth multiplier Page depth multiplier, see formula in page priority 1
|
||||
|
||||
Page priority depth modificator Page depth modificator, see formula in page priority 1
|
||||
================================= ========================================================== =================
|
||||
291
typo3conf/ext/metaseo/Documentation/DeveloperManual/Index.rst
Normal file
@@ -0,0 +1,291 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _developer-manual:
|
||||
|
||||
Developer Manual
|
||||
================
|
||||
|
||||
TypoScript Setup
|
||||
----------------
|
||||
|
||||
Advanced manipulations (stdWrap support)
|
||||
----------------------------------------
|
||||
|
||||
If you want to modify some things you can use stdWraps
|
||||
|
||||
MetaTags
|
||||
^^^^^^^^
|
||||
|
||||
============================================= ========================================================== ======================
|
||||
TypoScript Node Description Type
|
||||
============================================= ========================================================== ======================
|
||||
plugin.metaseo.metaTags.stdWrap.title Manipulation for title *stdWrap*
|
||||
|
||||
plugin.metaseo.metaTags.stdWrap.description Manipulation for description *stdWrap*
|
||||
|
||||
plugin.metaseo.metaTags.stdWrap.keywords Manipulation for keywords *stdWrap*
|
||||
|
||||
plugin.metaseo.metaTags.stdWrap.copyright Manipulation for copyright *stdWrap*
|
||||
|
||||
plugin.metaseo.metaTags.stdWrap.language Manipulation for language *stdWrap*
|
||||
|
||||
plugin.metaseo.metaTags.stdWrap.email Manipulation for email *stdWrap*
|
||||
|
||||
plugin.metaseo.metaTags.stdWrap.author Manipulation for author *stdWrap*
|
||||
|
||||
plugin.metaseo.metaTags.stdWrap.publisher Manipulation for publisher *stdWrap*
|
||||
|
||||
plugin.metaseo.metaTags.stdWrap.distribution Manipulation for distribution *stdWrap*
|
||||
|
||||
plugin.metaseo.metaTags.stdWrap.rating Manipulation for rating *stdWrap*
|
||||
|
||||
plugin.metaseo.metaTags.stdWrap.lastUpdate Manipulation for last update (date) *stdWrap*
|
||||
============================================= ========================================================== ======================
|
||||
|
||||
PageTitle
|
||||
^^^^^^^^^
|
||||
|
||||
============================================= ========================================================== ======================
|
||||
TypoScript Node Description Type
|
||||
============================================= ========================================================== ======================
|
||||
plugin.metaseo.pageTitle.caching Enables caching of page title. *boolean*
|
||||
If the page is fully cacheable you don't have to enable
|
||||
this option.
|
||||
If you use USER_INTs and one USER plugin changes page
|
||||
title (eg. via Connector) than this is not working
|
||||
because the output of the USER plugin is cached and
|
||||
the Connector not called again with the second hit.
|
||||
The caching fixes that issue.
|
||||
|
||||
plugin.metaseo.pageTitle.stdWrap.before Manipulation of the raw page title *stdWrap*
|
||||
(before MetaSEO processing)
|
||||
|
||||
plugin.metaseo.pageTitle.stdWrap.after Manipulation of the processed page title *stdWrap*
|
||||
(after MetaSEO processing)
|
||||
|
||||
plugin.metaseo.pageTitle.stdWrap.sitetitle Manipulation of the sitetitle *stdWrap*
|
||||
(from the TS-Setup-Template)
|
||||
============================================= ========================================================== ======================
|
||||
|
||||
|
||||
Google Analyitics / Piwik customizations
|
||||
----------------------------------------
|
||||
|
||||
Customization codes (fast/simple)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can add additional javascript code to the default Google Analytics and/or Piwik integration.
|
||||
|
||||
========================================================== ========================================================== ======================
|
||||
TypoScript Node Description Type
|
||||
========================================================== ========================================================== ======================
|
||||
plugin.metaseo.services.googleAnalytics.customizationCode Customization code for Google Analytics TS-Content Object
|
||||
(*TEXT*, *COA*, ...)
|
||||
|
||||
plugin.metaseo.services.piwik.customizationCode Customization code for Piwik TS-Content Object
|
||||
(*TEXT*, *COA*, ...)
|
||||
========================================================== ========================================================== ======================
|
||||
|
||||
Example for Google Analytics in TypoScript-Setup:
|
||||
|
||||
::
|
||||
|
||||
plugin.metaseo.services.googleAnalytics.customizationCode = COA
|
||||
plugin.metaseo.services.googleAnalytics.customizationCode {
|
||||
10 = TEXT
|
||||
10.value (
|
||||
_gaq.push(['_setClientInfo', false]);
|
||||
_gaq.push(['_setAllowHash', false]);
|
||||
_gaq.push(['_setDetectFlash', false]);
|
||||
_gaq.push(['_setDetectTitle', false]);
|
||||
)
|
||||
}
|
||||
|
||||
Template customization (advanced)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The Google Analytics and Piwik integration is done by using a FLUIDTEMPLATE object in TypoScript. If you don't like the integration and want to modify the integration feel free to use your own templates and pass your own variables to FLUIDTEMPLATE.
|
||||
|
||||
========================================================== ========================================================== ======================
|
||||
TypoScript Node Description Type
|
||||
========================================================== ========================================================== ======================
|
||||
plugin.metaseo.services.googleAnalytics.template Template rendering object for Google Analytics *COA*
|
||||
(contains a FLUIDTEMPLATE)
|
||||
|
||||
plugin.metaseo.services.piwik.template Template rendering object for Piwik *COA*
|
||||
(contains a FLUIDTEMPLATE)
|
||||
========================================================== ========================================================== ======================
|
||||
|
||||
It's quite easy, for more information read:
|
||||
|
||||
- https://docs.typo3.org/typo3cms/TyposcriptReference/ContentObjects/Fluidtemplate/Index.html
|
||||
- https://typo3.org/documentation/article/the-fluidtemplate-cobject
|
||||
|
||||
Example for your own Google Analytics Template:
|
||||
|
||||
::
|
||||
|
||||
## Google Analytics template
|
||||
plugin.metaseo.services.googleAnalytics.template.10.file = fileadmin/templates/service-ga.html
|
||||
|
||||
## if you need some variables you also can set these:
|
||||
plugin.metaseo.services.googleAnalytics.template.10.variables {
|
||||
myOwnStuff = TEXT
|
||||
myOwnStuff.value = foobar
|
||||
}
|
||||
|
||||
|
||||
|
||||
Sitemap
|
||||
-------
|
||||
========================================================== ========================================================== ======================
|
||||
TypoScript Node Description Type
|
||||
========================================================== ========================================================== ======================
|
||||
plugin.metaseo.sitemap.index.blacklist List of Regular Expression for blacklisting URLs while List
|
||||
indexing, eg.
|
||||
|
||||
10 = /typo3/
|
||||
20 = /foobar/
|
||||
30 = /imprint/i
|
||||
40 = /[a-z]/
|
||||
|
||||
plugin.metaseo.sitemap.index.pageTypeBlacklist List of blacklisted page typeNums (SetupTS PAGE objects) String, comma separated
|
||||
|
||||
plugin.metaseo.sitemap.index.fileExtension List of allowed file extensions for indexing List
|
||||
|
||||
Default:
|
||||
1 = pdf
|
||||
2 = doc,docx,xls,xlsx,ppt,pptx
|
||||
3 = odt,odp,ods,odg
|
||||
|
||||
========================================================== ========================================================== ======================
|
||||
|
||||
|
||||
Hooks
|
||||
-----
|
||||
|
||||
All hooks are also available as Extbase Signal. Please use signals instead of hooks.
|
||||
|
||||
::
|
||||
|
||||
<?php
|
||||
// ----------------------------------------------------------------------------
|
||||
// Example of MetaSEO Hooks
|
||||
//
|
||||
// Example integrations (eg. in localconf.php or ext_localconf.php):
|
||||
//
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['metatagSetup'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_metatagSetup';
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['metatagOutput'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_metatagOutput';
|
||||
//
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['pageTitleSetup'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_pagetitleSetup';
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['pageTitleOutput'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_pagetitleOutput';
|
||||
//
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['pageFooterSetup'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_pagefooterSetup';
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['pageFooterOutput'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_pagefooterOutput';
|
||||
//
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['sitemapIndexPage'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_sitemapIndexPage';
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['sitemapIndexLink'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_sitemapIndexLink';
|
||||
//
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['sitemapSetup'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_sitemapSetup';
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['sitemapTextOutput'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_sitemapTextOutput';
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['sitemapXmlIndexSitemapList'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_sitemapXmlIndexSitemapList';
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['sitemapXmlIndexOutput'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_sitemapXmlIndexOutput';
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['sitemapXmlPageOutput'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_sitemapXmlPageOutput';
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['sitemapClear'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_sitemapClear';
|
||||
//
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['robotsTxtMarker'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_robotsTxtMarker';
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['robotsTxtOutput'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_robotsTxtOutput';
|
||||
//
|
||||
// $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['metaseo']['hooks']['httpHeaderOutput'][] = 'EXT:metaseo/examples/hooks.php:user_metaseo_hook->hook_httpHeaderOutput';
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class user_metaseo_hook {
|
||||
|
||||
public function hook_metatagSetup(&$args, $obj) {
|
||||
// Hook for metatag setup
|
||||
}
|
||||
|
||||
public function hook_metatagOutput(&$args, $obj) {
|
||||
// Hook for metatag output
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public function hook_pagetitleSetup(&$args, $obj) {
|
||||
// Hook for pagetitle setup
|
||||
}
|
||||
|
||||
public function hook_pagetitleOutput(&$args, $obj) {
|
||||
// Hook for pagetitle output
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public function hook_pagefooterSetup(&$args, $obj) {
|
||||
// Hook for page footer setup
|
||||
}
|
||||
|
||||
public function hook_pagefooterOutput(&$args, $obj) {
|
||||
// Hook for page footer output
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public function hook_sitemapIndexPage(&$args) {
|
||||
// Hook for sitemap page indexer
|
||||
}
|
||||
|
||||
public function hook_sitemapIndexLink(&$args) {
|
||||
// Hook for sitemap link indexer
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public function hook_sitemapSetup(&$args, $obj) {
|
||||
// Hook for sitemap setup
|
||||
}
|
||||
|
||||
public function hook_sitemapTextOutput(&$args, $obj) {
|
||||
// Hook for xml text output
|
||||
}
|
||||
|
||||
public function hook_sitemapXmlIndexOutput(&$args, $obj) {
|
||||
// Hook for xml index-page output
|
||||
}
|
||||
|
||||
public function hook_sitemapXmlIndexSitemapList(&$args, $obj) {
|
||||
// Hook for manipulation sitemap.xml index page sitemap list
|
||||
}
|
||||
|
||||
public function hook_sitemapXmlPageOutput(&$args, $obj) {
|
||||
// Hook for xml page output
|
||||
}
|
||||
|
||||
public function hook_sitemapClear(&$args, $obj) {
|
||||
// Hook for sitemap clearing (truncating via clear-cache hook)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public function hook_robotsTxtMarker(&$args, $obj) {
|
||||
// Hook for robots.txt marker list
|
||||
}
|
||||
|
||||
public function hook_robotsTxtOutput(&$args, $obj) {
|
||||
// Hook for robots.txt output
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
public function hook_httpHeaderOutput($args, $obj) {
|
||||
// Hook for http header output
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
}
|
||||
82
typo3conf/ext/metaseo/Documentation/FaqManual/Index.rst
Normal file
@@ -0,0 +1,82 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
.. _faq-manual:
|
||||
|
||||
Frequently Asked Questions (FAQ)
|
||||
================================
|
||||
|
||||
General
|
||||
-------
|
||||
|
||||
| **Problem:**
|
||||
| Is this extension multi-language and/or multi-tree ready?
|
||||
| **Solution:**
|
||||
| Check it out, there should be no problems at all with multi-language multi-tree installations of TYPO3 CMS.
|
||||
|
|
||||
| **Problem:**
|
||||
| In my TYPO3 the feature XYZ of this extension doesn't work. What's wrong?
|
||||
| **Solution:**
|
||||
| The metaseo-Extension has been written carefully. We want to deliver correct pages and extensions with the power of TYPO3's caching system (and those extensions are the fastest). For some features (e.g. sitemap, canonical-tag) we have to trust in the caching-system – it's the only way to make sure that we don't deliver wrong information to search engines. If our extension doesn't work correctly, something could also be wrong with the configuration of your TYPO3 – the configuration variables, setupTS or a conflict or a problem with other extensions.
|
||||
|
||||
Indexed Sitemap
|
||||
---------------
|
||||
|
||||
| **Problem:**
|
||||
| When I want to open my sitemap I get an error "The page is not configured! [type=841131|841132|841133][]. This means that there is no TypoScript object of type PAGE with typeNum=841131|841132|841133 configured."
|
||||
| **Solution:**
|
||||
| Make sure you have configured MetaSEO "Include static" as described in the installation manual.
|
||||
|
|
||||
| **Problem:**
|
||||
| The sitemap is empty.
|
||||
| **Solution:**
|
||||
| Check if the “tx_metaseo_sitemap” database-table was created! We're using MySQL's InnoDB table engine so you have to make sure that your MySQL server comes with InnoDB-support (if your hoster does not provide InnoDB you should look out for another hoster!).
|
||||
|
|
||||
| **Problem:**
|
||||
| My sitemap is still empty, but the database is ok.
|
||||
| **Solution:**
|
||||
| Maybe you disabled the whole TYPO3 cache (config.no_cache=1 or something else)? Enable the cache – this will also speed up your TYPO3 instance.
|
||||
|
|
||||
| **Problem:**
|
||||
| The pages which my extension created are not available in the sitemap!
|
||||
| **Solution:**
|
||||
| You have to make sure that all generated pages are cacheable. The extension must be able to pass a valid cHash-token!
|
||||
|
|
||||
| **Problem:**
|
||||
| In the sitemap-database are thousands of pages but there is only one site in my XML-Sitemap.
|
||||
| **Solution:**
|
||||
| That's correct. MetaSEO always uses “Sitemap Groups” (as defined in http://www.sitemaps.org/protocol.html#index), each group can contain about 50.000 pages/URLs so if we have more than 50.000 URLs we have to use sitemap groups. Visit the URL defined in the LOC-tag and you will see that the sub-sitemap will contain all your stored URLs.
|
||||
|
|
||||
| **Problem:**
|
||||
| The generated pages from my extension still are not included in the sitemap!
|
||||
| **Solution:**
|
||||
| Have you enabled RealURL? Please check the RealURL configuration if you have specified values that are not passed with your URL. All variables that are not passed with the URL will result in a NO-CACHE.
|
||||
|
|
||||
| **Problem:**
|
||||
| The sitemap is still not working! No page is indexed and the table tx_metaseo_sitemap is empty!
|
||||
| **Solution:**
|
||||
| Double check your installation and disable all third party extensions. Make sure that no extension disables the TYPO3-cache! RealUrl (if properly configured) and TemplaVoila are working perfectly together with MetaSEO sitemap but some old extensions might break the TYPO3 caching system and you will not notice it. Our sitemap indexer relies on the indexing system to make sure that only valid urls are stored and delivered to search engines like google.
|
||||
|
|
||||
| **Problem:**
|
||||
| I want to limit each sitemap to its domain (eg. example.com for english pages, example.de for german pages). Is this possible?
|
||||
| **Solution:**
|
||||
| Yes, just enable the “Enable language-domain support” in seo control center in your website/rootpage settings (replaces the old extension configuration sitemap_ObeySysLanguage and TypoScript constants setting).
|
||||
|
|
||||
| **Problem:**
|
||||
| My tt_news entries are not indexed, what's wrong?
|
||||
| **Solution:**
|
||||
| You're using realurl? Then check your realurl_conf.php. Errors (or misconfiguration) in the realurl-configuration will produce uncacheable sites (and you will not notice it). The most common issue is the configuration of the parameter “tx_ttnews[swords]” in the postVarSets-area. Remove it, you don't need it.
|
||||
|
||||
|
||||
Others
|
||||
------
|
||||
|
||||
| **Problem:**
|
||||
| I want to customize my Google Analytics and/or Piwik integration.
|
||||
| **Solution:**
|
||||
| You can modify the code of the Google Analytics and Piwik integration with TypoScript. Feel free to use plugin.metaseo.services.googleAnalytics.customizationCode (STDWRAP) or plugin.metaseo.services.piwik.customizationCode (STDWRAP). Also you can modify the FLUIDTEMPLATE and assign custom variables.
|
||||
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 11 KiB |
21
typo3conf/ext/metaseo/Documentation/Includes.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. This is 'Includes.txt'. It is included at the very top of each and
|
||||
every ReST source file in this documentation project (= manual).
|
||||
|
||||
|
||||
.. ==================================================
|
||||
.. DEFINE SOME TEXT ROLES
|
||||
.. --------------------------------------------------
|
||||
|
||||
.. role:: typoscript(code)
|
||||
|
||||
.. role:: ts(typoscript)
|
||||
:class: typoscript
|
||||
|
||||
.. role:: php(code)
|
||||
|
||||
.. highlight:: php
|
||||
67
typo3conf/ext/metaseo/Documentation/Index.rst
Normal file
@@ -0,0 +1,67 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: Includes.txt
|
||||
|
||||
|
||||
.. _start:
|
||||
|
||||
=============================================================
|
||||
MetaSEO
|
||||
=============================================================
|
||||
|
||||
.. only:: html
|
||||
|
||||
:Classification:
|
||||
metaseo
|
||||
|
||||
:Version:
|
||||
|release|
|
||||
|
||||
:Language:
|
||||
en
|
||||
|
||||
:Description:
|
||||
Search Engine Optimization (SEO),
|
||||
Indexed Google-Sitemap (TXT- and XML-Sitemap) for all Extensions (pibase, extbase),
|
||||
Metatags, Canonical-URL, Pagetitle manipulations, Crawler verification,
|
||||
Piwik and Google Analytics support and some more... multi-language- and multi-tree-support
|
||||
|
||||
:Keywords:
|
||||
metatag,metatags,seo,sitemap,google,searchengine,tqseo,tq_seo,metaseo,pagetitle
|
||||
|
||||
:Copyright:
|
||||
2014
|
||||
|
||||
:Author:
|
||||
Markus Blaschke
|
||||
|
||||
:Email:
|
||||
typo3@markus-blaschke.de
|
||||
|
||||
:License:
|
||||
This document is published under the Open Content License
|
||||
available from http://www.opencontent.org/opl.shtml
|
||||
|
||||
:Rendered:
|
||||
|today|
|
||||
|
||||
The content of this document is related to TYPO3,
|
||||
a GNU/GPL CMS/Framework available from `typo3.org <https://typo3.org>`_.
|
||||
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 5
|
||||
:glob:
|
||||
|
||||
Introduction/Index
|
||||
Constants/Index
|
||||
BackendModules/Index
|
||||
AdministratorManual/Index
|
||||
DeveloperManual/Index
|
||||
FaqManual/Index
|
||||
ChangeLog/Index
|
||||
142
typo3conf/ext/metaseo/Documentation/Introduction/Index.rst
Normal file
@@ -0,0 +1,142 @@
|
||||
.. ==================================================
|
||||
.. FOR YOUR INFORMATION
|
||||
.. --------------------------------------------------
|
||||
.. -*- coding: utf-8 -*- with BOM.
|
||||
|
||||
.. include:: ../Includes.txt
|
||||
|
||||
|
||||
What does it do?
|
||||
================
|
||||
|
||||
This extensions handles multiple page metatags and pagetitle manipulations in TYPO3. It's a replacement and major improvement for the “metatags” and this extension is the successor of the popular "tq_seo" extension.
|
||||
|
||||
The following features are supported:
|
||||
|
||||
- Indexed XML sitemap for Google and other search engines (with support for ALL extensions, pibase and extbase, not only tt_news)
|
||||
- Real sitemap builder via TYPO3 scheduler
|
||||
- Metatags
|
||||
- Manipulation of Metatags via stdWrap (Beta)
|
||||
- Automatic fetching metatags from tt_news (single-display module)
|
||||
- Pagetitle manipulations
|
||||
- Manipulation of pagetitle via stdWrap (Beta)
|
||||
- Multi-language and/or multi-tree TYPO3 installations
|
||||
|
||||
Backend modules:
|
||||
|
||||
- SEO page module
|
||||
- SEO control center module
|
||||
- SEO sitemap module
|
||||
|
||||
The following metatags are supported:
|
||||
|
||||
- Language (auto-detected)
|
||||
- Description
|
||||
- Keyword
|
||||
- Copyright information
|
||||
- Reply-To E-Mail-Address
|
||||
- Author and publisher
|
||||
- Rating and distribution
|
||||
- Revisit
|
||||
- Geo-location information
|
||||
- Searchengine crawler instructions
|
||||
- Google Analytics (with anonymized IP and download link tracking, asynchronous implementation since 4.0)
|
||||
- Piwik integration (asynchronous implementation since 4.0)
|
||||
- Google, MSN, Yahoo and WebOfTrust Verification
|
||||
- Google+ Direct Connect
|
||||
- Canonical URL (Custom URL or autogenerated to current page)
|
||||
- IE Compatibility-Mode
|
||||
- Google Expire Date
|
||||
- Index, up, prev und next link-metatags
|
||||
- P3P-HTTP-Headers
|
||||
- OpenGraph (WIP)
|
||||
- Blacklist for sitemap, CanonicalURL and searchengine index/noindex switching
|
||||
|
||||
The following pagetitle transformations are supported:
|
||||
|
||||
- Prefix and suffix (inheritable)
|
||||
- Absolute pagetitle without any prefix and suffix
|
||||
- Sitetitle glue options
|
||||
- Sitetitle positon
|
||||
|
||||
Screenshots
|
||||
-----------
|
||||
|
||||
|
||||
Backend Modules
|
||||
^^^^^^^^^^^^^^^
|
||||
.. figure:: ../Images/Introduction/ModuleSeoMetatags.png
|
||||
:scale: 80%
|
||||
:alt: Backend Module - SEO Metatags
|
||||
|
||||
Backend Module "SEO Metatags"
|
||||
|
||||
|
||||
.. figure:: ../Images/Introduction/ModuleSeoControlCenter.png
|
||||
:scale: 80%
|
||||
:alt: Backend Module - SEO Control Center
|
||||
|
||||
Backend Module "SEO Control Center"
|
||||
|
||||
.. figure:: ../Images/Introduction/ModuleSeoSitemap.png
|
||||
:scale: 80%
|
||||
:alt: Backend Module - SEO Sitemap
|
||||
|
||||
Backend Module "SEO Sitemap"
|
||||
|
||||
|
||||
Constants
|
||||
^^^^^^^^^
|
||||
|
||||
.. figure:: ../Images/Introduction/ConstantsMetatags.png
|
||||
:scale: 80%
|
||||
:alt: Constants Editor - Metatags
|
||||
|
||||
Constants Editor of metatags
|
||||
|
||||
|
||||
.. figure:: ../Images/Introduction/ConstantsPagetitle.png
|
||||
:scale: 80%
|
||||
:alt: Constants Editor - Pagetitle
|
||||
|
||||
Constants Editor of pagetitle settings
|
||||
|
||||
|
||||
.. figure:: ../Images/Introduction/ConstantsCrawler.png
|
||||
:scale: 80%
|
||||
:alt: Constants Editor - Crawler
|
||||
|
||||
Constants Editor of crawler (google) settings
|
||||
|
||||
|
||||
.. figure:: ../Images/Introduction/ConstantsServices.png
|
||||
:scale: 80%
|
||||
:alt: Constants Editor - Services
|
||||
|
||||
Constants Editor of services settings
|
||||
|
||||
|
||||
Found a bug?
|
||||
------------
|
||||
|
||||
Just send me a mail to typo3@markus-blaschke.de
|
||||
or just enter the bug into the bugtracker at https://github.com/mblaschke/TYPO3-metaseo
|
||||
|
||||
Thanks to...
|
||||
------------
|
||||
|
||||
- TEQneers GmbH & Co. KG for sponsoring the predecessor "tq_seo"
|
||||
- jweiland.net especially Wolfgang Wagner for all the tutorials
|
||||
- Pierre Arlt
|
||||
- Riccardo De Contardi
|
||||
- Rico Sonntag
|
||||
- Ralle Büchnitz
|
||||
- Manfred Egger
|
||||
- Carsten Hager
|
||||
- Thomas Deuling
|
||||
- Thomas Mayer
|
||||
- Florian Duffner
|
||||
- Georg Tiefenbrunn
|
||||
- Arne-Kolja Bachstein
|
||||
- all other contributors and bug reporters
|
||||
- famfamfam for these cool silk icons http://www.famfamfam.com/lab/icons/silk/
|
||||
24
typo3conf/ext/metaseo/Documentation/Settings.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
# This is the project specific Settings.yml file.
|
||||
# Place Sphinx specific build information here.
|
||||
# Settings given here will replace the settings of 'conf.py'.
|
||||
|
||||
---
|
||||
conf.py:
|
||||
copyright: 2014
|
||||
project: MetaSEO
|
||||
version: 1.0
|
||||
release: 1.0.0
|
||||
html_theme_options:
|
||||
github_repository: mblaschke/TYPO3-metaseo
|
||||
github_branch: develop
|
||||
latex_documents:
|
||||
- - Index
|
||||
- metaseo.tex
|
||||
- MetaSEO
|
||||
- Markus Blaschke
|
||||
- manual
|
||||
latex_elements:
|
||||
papersize: a4paper
|
||||
pointsize: 10pt
|
||||
preamble: \usepackage{typo3}
|
||||
...
|
||||
156
typo3conf/ext/metaseo/Documentation/_make/Makefile
Normal file
@@ -0,0 +1,156 @@
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS = -c . -a -E -w ./_not_versioned/warnings.txt
|
||||
SPHINXBUILD = sphinx-build
|
||||
PAPER = a4
|
||||
BUILDDIR = build
|
||||
|
||||
# Internal variables.
|
||||
PAPEROPT_a4 = -D latex_paper_size=a4
|
||||
PAPEROPT_letter = -D latex_paper_size=letter
|
||||
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) ..
|
||||
# the i18n builder cannot share the environment and doctrees with the others
|
||||
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) ..
|
||||
|
||||
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " html to make standalone HTML files"
|
||||
@echo " dirhtml to make HTML files named index.html in directories"
|
||||
@echo " singlehtml to make a single large HTML file"
|
||||
@echo " pickle to make pickle files"
|
||||
@echo " json to make JSON files"
|
||||
@echo " htmlhelp to make HTML files and a HTML help project"
|
||||
@echo " qthelp to make HTML files and a qthelp project"
|
||||
@echo " devhelp to make HTML files and a Devhelp project"
|
||||
@echo " epub to make an epub"
|
||||
@echo " pdf to make PDF using rst2pdf"
|
||||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
|
||||
@echo " latexpdf to make LaTeX files and run them through pdflatex"
|
||||
@echo " text to make text files"
|
||||
@echo " man to make manual pages"
|
||||
@echo " texinfo to make Texinfo files"
|
||||
@echo " info to make Texinfo files and run them through makeinfo"
|
||||
@echo " gettext to make PO message catalogs"
|
||||
@echo " changes to make an overview of all changed/added/deprecated items"
|
||||
@echo " linkcheck to check all external links for integrity"
|
||||
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
|
||||
|
||||
clean:
|
||||
-rm -rf $(BUILDDIR)/*
|
||||
|
||||
html:
|
||||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
|
||||
|
||||
dirhtml:
|
||||
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
|
||||
|
||||
singlehtml:
|
||||
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
|
||||
@echo
|
||||
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
|
||||
|
||||
pickle:
|
||||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
|
||||
@echo
|
||||
@echo "Build finished; now you can process the pickle files."
|
||||
|
||||
json:
|
||||
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
|
||||
@echo
|
||||
@echo "Build finished; now you can process the JSON files."
|
||||
|
||||
htmlhelp:
|
||||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run HTML Help Workshop with the" \
|
||||
".hhp project file in $(BUILDDIR)/htmlhelp."
|
||||
|
||||
qthelp:
|
||||
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
|
||||
@echo
|
||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
|
||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
|
||||
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Projectname.qhcp"
|
||||
@echo "To view the help file:"
|
||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Projectname.qhc"
|
||||
|
||||
devhelp:
|
||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
|
||||
@echo
|
||||
@echo "Build finished."
|
||||
@echo "To view the help file:"
|
||||
@echo "# mkdir -p $$HOME/.local/share/devhelp/Projectname"
|
||||
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Projectname"
|
||||
@echo "# devhelp"
|
||||
|
||||
epub:
|
||||
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
|
||||
@echo
|
||||
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
|
||||
|
||||
pdf:
|
||||
$(SPHINXBUILD) -b pdf $(ALLSPHINXOPTS) $(BUILDDIR)/pdf
|
||||
@echo
|
||||
@echo "Build finished. The PDF is in $(BUILDDIR)/pdf."
|
||||
|
||||
latex:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo
|
||||
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
|
||||
@echo "Run \`make' in that directory to run these through (pdf)latex" \
|
||||
"(use \`make latexpdf' here to do that automatically)."
|
||||
|
||||
latexpdf:
|
||||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
|
||||
@echo "Running LaTeX files through pdflatex..."
|
||||
$(MAKE) -C $(BUILDDIR)/latex all-pdf
|
||||
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
|
||||
|
||||
text:
|
||||
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
|
||||
@echo
|
||||
@echo "Build finished. The text files are in $(BUILDDIR)/text."
|
||||
|
||||
man:
|
||||
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
|
||||
@echo
|
||||
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
|
||||
|
||||
texinfo:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo
|
||||
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
|
||||
@echo "Run \`make' in that directory to run these through makeinfo" \
|
||||
"(use \`make info' here to do that automatically)."
|
||||
|
||||
info:
|
||||
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
|
||||
@echo "Running Texinfo files through makeinfo..."
|
||||
make -C $(BUILDDIR)/texinfo info
|
||||
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
|
||||
|
||||
gettext:
|
||||
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
|
||||
@echo
|
||||
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
|
||||
|
||||
changes:
|
||||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
|
||||
@echo
|
||||
@echo "The overview file is in $(BUILDDIR)/changes."
|
||||
|
||||
linkcheck:
|
||||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
|
||||
@echo
|
||||
@echo "Link check complete; look for any errors in the above output " \
|
||||
"or in $(BUILDDIR)/linkcheck/output.txt."
|
||||
|
||||
doctest:
|
||||
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
|
||||
@echo "Testing of doctests in the sources finished, look at the " \
|
||||
"results in $(BUILDDIR)/doctest/output.txt."
|
||||
7
typo3conf/ext/metaseo/Documentation/_make/_not_versioned/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# this is file .gitignore
|
||||
|
||||
# ignore everything in this directory
|
||||
*
|
||||
|
||||
# but do not ignore this this file
|
||||
!.gitignore
|
||||
7
typo3conf/ext/metaseo/Documentation/_make/build/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# this is file .gitignore
|
||||
|
||||
# ignore everything in this directory
|
||||
*
|
||||
|
||||
# but do not ignore this this file
|
||||
!.gitignore
|
||||
423
typo3conf/ext/metaseo/Documentation/_make/conf.py
Normal file
@@ -0,0 +1,423 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# MetaSEO Import from tq_seo documentation build configuration file, created by
|
||||
# TYPO3 extension sphinx on Tue, 01 Apr 2014 17:53:40 +0200.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- PHP highlighting configuration --------------------------------------------
|
||||
|
||||
from sphinx.highlighting import lexers
|
||||
if lexers:
|
||||
from pygments.lexers.web import PhpLexer
|
||||
lexers['php'] = PhpLexer(startinline=True)
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.ifconfig']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['../_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'Index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'MetaSEO Import from tq_seo'
|
||||
copyright = u'2014, Markus Blaschke'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.0'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.0.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
today_fmt = '%Y-%m-%d %H:%M'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_make']
|
||||
exclude_trees = ['_make']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['../_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'metaseo_tqseo_importdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
'preamble': '\\usepackage{typo3}'
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('Index', 'metaseo_tqseo_import.tex', u'MetaSEO Import from tq_seo',
|
||||
u'Markus Blaschke', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for rst2pdf output ------------------------------------------------
|
||||
|
||||
# Grouping the document tree into PDF files. List of tuples
|
||||
# (source start file, target name, title, author, options).
|
||||
#
|
||||
# If there is more than one author, separate them with \\.
|
||||
# For example: r'Guido van Rossum\\Fred L. Drake, Jr., editor'
|
||||
#
|
||||
# The options element is a dictionary that lets you override
|
||||
# this config per-document.
|
||||
# For example,
|
||||
# ('index', u'MyProject', u'My Project', u'Author Name',
|
||||
# dict(pdf_compressed = True))
|
||||
# would mean that specific document would be compressed
|
||||
# regardless of the global pdf_compressed setting.
|
||||
pdf_documents = [
|
||||
('Index', 'metaseo_tqseo_import', u'MetaSEO Import from tq_seo',
|
||||
u'Markus Blaschke'),
|
||||
]
|
||||
|
||||
# A comma-separated list of custom stylesheets. Example:
|
||||
pdf_stylesheets = ['sphinx','kerning','a4']
|
||||
|
||||
# A list of folders to search for stylesheets. Example:
|
||||
pdf_style_path = ['.', '_styles']
|
||||
|
||||
# Create a compressed PDF
|
||||
# Use True/False or 1/0
|
||||
# Example: compressed=True
|
||||
#pdf_compressed = False
|
||||
|
||||
# A colon-separated list of folders to search for fonts. Example:
|
||||
# pdf_font_path = ['/usr/share/fonts', '/usr/share/texmf-dist/fonts/']
|
||||
|
||||
# Language to be used for hyphenation support
|
||||
#pdf_language = "en_US"
|
||||
|
||||
# Mode for literal blocks wider than the frame. Can be
|
||||
# overflow, shrink or truncate
|
||||
#pdf_fit_mode = "shrink"
|
||||
|
||||
# Section level that forces a break page.
|
||||
# For example: 1 means top-level sections start in a new page
|
||||
# 0 means disabled
|
||||
#pdf_break_level = 0
|
||||
|
||||
# When a section starts in a new page, force it to be 'even', 'odd',
|
||||
# or just use 'any'
|
||||
#pdf_breakside = 'any'
|
||||
|
||||
# Insert footnotes where they are defined instead of
|
||||
# at the end.
|
||||
#pdf_inline_footnotes = True
|
||||
|
||||
# verbosity level. 0 1 or 2
|
||||
#pdf_verbosity = 0
|
||||
|
||||
# If false, no index is generated.
|
||||
#pdf_use_index = True
|
||||
|
||||
# If false, no modindex is generated.
|
||||
#pdf_use_modindex = True
|
||||
|
||||
# If false, no coverpage is generated.
|
||||
#pdf_use_coverpage = True
|
||||
|
||||
# Name of the cover page template to use
|
||||
#pdf_cover_template = 'sphinxcover.tmpl'
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#pdf_appendices = []
|
||||
|
||||
# Enable experimental feature to split table cells. Use it
|
||||
# if you get "DelayedTable too big" errors
|
||||
#pdf_splittables = False
|
||||
|
||||
# Set the default DPI for images
|
||||
#pdf_default_dpi = 72
|
||||
|
||||
# Enable rst2pdf extension modules (default is only vectorpdf)
|
||||
# you need vectorpdf if you want to use sphinx's graphviz support
|
||||
#pdf_extensions = ['vectorpdf']
|
||||
|
||||
# Page template name for "regular" pages
|
||||
#pdf_page_template = 'cutePage'
|
||||
|
||||
# Show Table Of Contents at the beginning?
|
||||
#pdf_use_toc = True
|
||||
|
||||
# How many levels deep should the table of contents be?
|
||||
pdf_toc_depth = 9999
|
||||
|
||||
# Add section number to section references
|
||||
pdf_use_numbered_links = False
|
||||
|
||||
# Background images fitting mode
|
||||
pdf_fit_background_mode = 'scale'
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('Index', 'metaseo_tqseo_import', u'MetaSEO Import from tq_seo',
|
||||
[u'Markus Blaschke'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output ------------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('Index', 'metaseo_tqseo_import', u'MetaSEO Import from tq_seo',
|
||||
u'Markus Blaschke', 'MetaSEO Import from tq_seo', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
|
||||
|
||||
#=================================================
|
||||
#
|
||||
# TYPO3 codeblock BEGIN:
|
||||
#
|
||||
# Insert this codeblock at the end of your Sphinx
|
||||
# builder configuration file 'conf.py'.
|
||||
# This may enable TYPO3 specific features like
|
||||
# TYPO3 themes. It makes Yaml settings files work.
|
||||
#
|
||||
#-------------------------------------------------
|
||||
|
||||
if 1 and "TYPO3 specific":
|
||||
|
||||
try:
|
||||
t3DocTeam
|
||||
except NameError:
|
||||
t3DocTeam = {}
|
||||
|
||||
try:
|
||||
import t3sphinx
|
||||
html_theme_path.insert(0, t3sphinx.themes_dir)
|
||||
html_theme = 'typo3sphinx'
|
||||
except:
|
||||
html_theme = 'default'
|
||||
|
||||
t3DocTeam['conf_py_file'] = None
|
||||
try:
|
||||
t3DocTeam['conf_py_file'] = __file__
|
||||
except:
|
||||
import inspect
|
||||
t3DocTeam['conf_py_file'] = inspect.getfile(
|
||||
inspect.currentframe())
|
||||
|
||||
t3DocTeam['conf_py_package_dir'] = os.path.abspath(os.path.dirname(
|
||||
t3DocTeam['conf_py_file']))
|
||||
t3DocTeam['relpath_to_master_doc'] = '..'
|
||||
t3DocTeam['relpath_to_logdir'] = '_not_versioned'
|
||||
t3DocTeam['path_to_logdir'] = os.path.join(
|
||||
t3DocTeam['conf_py_package_dir'],
|
||||
t3DocTeam['relpath_to_logdir'])
|
||||
t3DocTeam['pathToYamlSettings'] = os.path.join(
|
||||
t3DocTeam['conf_py_package_dir'],
|
||||
t3DocTeam['relpath_to_master_doc'], 'Settings.yml')
|
||||
try:
|
||||
t3DocTeam['pathToGlobalYamlSettings'] = \
|
||||
t3sphinx.pathToGlobalYamlSettings
|
||||
except:
|
||||
t3DocTeam['pathToGlobalYamlSettings'] = None
|
||||
if not t3DocTeam['pathToGlobalYamlSettings']:
|
||||
t3DocTeam['pathToGlobalYamlSettings'] = os.path.join(
|
||||
t3DocTeam['conf_py_package_dir'], 'GlobalSettings.yml')
|
||||
try:
|
||||
__function = t3sphinx.yamlsettings.processYamlSettings
|
||||
except:
|
||||
__function = None
|
||||
if not __function:
|
||||
try:
|
||||
import yamlsettings
|
||||
__function = yamlsettings.processYamlSettings
|
||||
except:
|
||||
__function = None
|
||||
if __function:
|
||||
__function(globals(), t3DocTeam)
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
# TYPO3 codeblock END.
|
||||
#
|
||||
#=================================================
|
||||
22
typo3conf/ext/metaseo/Documentation/_make/make-html.bat
Normal file
@@ -0,0 +1,22 @@
|
||||
@echo off
|
||||
echo.
|
||||
echo.
|
||||
|
||||
echo Building single file HTML version in build/singlehtml ...
|
||||
call make.bat singlehtml
|
||||
echo.
|
||||
echo.
|
||||
|
||||
echo Building HTML version in build/html ...
|
||||
call make.bat html
|
||||
echo.
|
||||
echo.
|
||||
|
||||
echo Starting build/html/Index.html in browser ...
|
||||
start build\html\Index.html
|
||||
echo.
|
||||
echo.
|
||||
|
||||
|
||||
echo Finished.
|
||||
pause
|
||||
194
typo3conf/ext/metaseo/Documentation/_make/make.bat
Normal file
@@ -0,0 +1,194 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Command file for Sphinx documentation
|
||||
|
||||
if "%SPHINXOPTS%" == "" (
|
||||
set SPHINXOPTS=-c . -a -E -w ./_not_versioned/warnings.txt
|
||||
)
|
||||
if "%SPHINXBUILD%" == "" (
|
||||
set SPHINXBUILD=/home/mblaschke/public_html/t3intro/typo3temp/tx_sphinx/sphinx-doc/bin/sphinx-build
|
||||
)
|
||||
set PAPER=a4
|
||||
set BUILDDIR=build
|
||||
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% ..
|
||||
set I18NSPHINXOPTS=%SPHINXOPTS% ..
|
||||
if NOT "%PAPER%" == "" (
|
||||
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
|
||||
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
|
||||
)
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo.Please use `make ^<target^>` where ^<target^> is one of
|
||||
echo. html to make standalone HTML files
|
||||
echo. dirhtml to make HTML files named index.html in directories
|
||||
echo. singlehtml to make a single large HTML file
|
||||
echo. pickle to make pickle files
|
||||
echo. json to make JSON files
|
||||
echo. htmlhelp to make HTML files and a HTML help project
|
||||
echo. qthelp to make HTML files and a qthelp project
|
||||
echo. devhelp to make HTML files and a Devhelp project
|
||||
echo. epub to make an epub
|
||||
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
|
||||
echo. text to make text files
|
||||
echo. man to make manual pages
|
||||
echo. texinfo to make Texinfo files
|
||||
echo. gettext to make PO message catalogs
|
||||
echo. changes to make an overview over all changed/added/deprecated items
|
||||
echo. linkcheck to check all external links for integrity
|
||||
echo. doctest to run all doctests embedded in the documentation if enabled
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "clean" (
|
||||
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
|
||||
del /q /s %BUILDDIR%\*
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "html" (
|
||||
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "dirhtml" (
|
||||
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "singlehtml" (
|
||||
%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "pickle" (
|
||||
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the pickle files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "json" (
|
||||
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can process the JSON files.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "htmlhelp" (
|
||||
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run HTML Help Workshop with the ^
|
||||
.hhp project file in %BUILDDIR%/htmlhelp.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "qthelp" (
|
||||
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^
|
||||
.qhcp project file in %BUILDDIR%/qthelp, like this:
|
||||
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Projectname.qhcp
|
||||
echo.To view the help file:
|
||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Projectname.ghc
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "devhelp" (
|
||||
%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "epub" (
|
||||
%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The epub file is in %BUILDDIR%/epub.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "latex" (
|
||||
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "text" (
|
||||
%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The text files are in %BUILDDIR%/text.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "man" (
|
||||
%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The manual pages are in %BUILDDIR%/man.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "texinfo" (
|
||||
%SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "gettext" (
|
||||
%SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "changes" (
|
||||
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.The overview file is in %BUILDDIR%/changes.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "linkcheck" (
|
||||
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Link check complete; look for any errors in the above output ^
|
||||
or in %BUILDDIR%/linkcheck/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "doctest" (
|
||||
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
|
||||
if errorlevel 1 exit /b 1
|
||||
echo.
|
||||
echo.Testing of doctests in the sources finished, look at the ^
|
||||
results in %BUILDDIR%/doctest/output.txt.
|
||||
goto end
|
||||
)
|
||||
|
||||
:end
|
||||
3
typo3conf/ext/metaseo/Documentation/_make/readme.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
This directory is only used by developers to run a syntax check for the rst files.
|
||||
|
||||
The conf.py is not used for production purposes. Instead, use /Documentation/Settings.yml
|
||||
7
typo3conf/ext/metaseo/Documentation/_static/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# this is file .gitignore
|
||||
|
||||
# ignore everything in this directory
|
||||
*
|
||||
|
||||
# but do not ignore this this file
|
||||
!.gitignore
|
||||
674
typo3conf/ext/metaseo/LICENSE
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
82
typo3conf/ext/metaseo/README.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# MetaSEO - Search Engine Optimization for TYPO3
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
[](https://isitmaintained.com/project/mblaschke/typo3-metaseo "Average time to resolve an issue")
|
||||
[](https://isitmaintained.com/project/mblaschke/typo3-metaseo "Percentage of issues still open")
|
||||
|
||||
|
||||
[](https://insight.sensiolabs.com/projects/19914ab4-1f0f-4be0-9215-410fba880af2)
|
||||
|
||||
|
||||
This extension provides an indexed google/xml-sitemap, enhanced metatag-support and pagetitle-manipulations for TYPO3 CMS.
|
||||
It's a replacement for the "metatag"-extension and the successor of "tq_seo".
|
||||
|
||||
* Manual: https://docs.typo3.org/typo3cms/extensions/metaseo/
|
||||
* Git: https://github.com/mblaschke/TYPO3-metaseo
|
||||
* Support: https://github.com/mblaschke/TYPO3-metaseo/issues
|
||||
|
||||
## Version status
|
||||
|
||||
* Version **1.x**:
|
||||
|
||||
+ Branch **master**
|
||||
+ TYPO3 Version: 6.2.x
|
||||
+ Composer: dev-master
|
||||
|
||||
* Version **2.x**:
|
||||
|
||||
+ Branch **develop**
|
||||
+ TYPO3 Version: 6.2.x - 7.4.x
|
||||
+ Composer: dev-develop
|
||||
|
||||
For version specific information see [Changelog for MetaSEO](CHANGELOG.md)
|
||||
|
||||
|
||||
## Composer Support
|
||||
|
||||
MetaSEO (stable) is available **from TYPO3 TER** and also available with composer ::
|
||||
|
||||
{
|
||||
"repositories": [
|
||||
{ "type": "composer", "url": "https://composer.typo3.org/" }
|
||||
],
|
||||
.......
|
||||
"require": {
|
||||
"typo3/cms": "6.2.*",
|
||||
"typo3-ter/metaseo": "*"
|
||||
}
|
||||
}
|
||||
|
||||
Or (unstable, don't blame me for bugs - but feel free to report bugs) directly **from Github** ::
|
||||
|
||||
{
|
||||
"repositories": [
|
||||
{ "type": "composer", "url": "https://composer.typo3.org/" },
|
||||
{ "type": "vcs", "url": "https://github.com/mblaschke/TYPO3-metaseo.git" },
|
||||
],
|
||||
.......
|
||||
"require": {
|
||||
"typo3/cms": "6.2.*",
|
||||
"mblaschke/metaseo": "dev-master"
|
||||
}
|
||||
}
|
||||
|
||||
## Found a bug? Got problems?
|
||||
|
||||
Please send us following information for easier bug hunting:
|
||||
|
||||
* MetaSEO version
|
||||
* TYPO3 version
|
||||
* PHP version
|
||||
* Hoster and/or Linux distribution
|
||||
|
||||
## Contribution
|
||||
|
||||
If you want to contribute make sure you have an Editorconfig-Plugin installed in your IDE.
|
||||
See [.editorconfig](.editorconfig) for indentation.
|
||||
|
||||
This TYPO3 Extension is using [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) as coding style.
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<xliff version="1.0">
|
||||
<file source-language="en" target-language="de" datatype="plaintext" original="messages" date="2014-11-08T14:45:21Z"
|
||||
product-name="metaseo">
|
||||
<header/>
|
||||
<body>
|
||||
<trans-unit id="mlang_tabs_tab" xml:space="preserve" approved="yes">
|
||||
<source>Control Center</source>
|
||||
<target>Kontrollzentrum</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="mlang_labels_tabdescr" xml:space="preserve" approved="yes">
|
||||
<source>MetaSEO Control center, sitemap configuration and rootpage settings</source>
|
||||
<target>MetaSEO-Kontrollzentrum, Sitemap- und Rootpage-Einstellungen</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||