From df6c67a7e9223ea78baf9aff2f327a77540f65b9 Mon Sep 17 00:00:00 2001 From: Alex Hupe Date: Sat, 7 Feb 2026 17:20:52 +0100 Subject: [PATCH 1/2] Port to OXID eShop 6.5+ with PHP 8 compatibility - Upgrade metadata from 1.1 to 2.1 - Replace classmap autoloading with PSR-4 namespaces (Toxid\) - Restructure to OXID 6.x module directory layout (Application/, Core/) - Replace old extend paths with fully qualified class names - Replace 'files' array with 'controllers' array - Add smartyPluginDirectories for Smarty plugin registration - Fix PHP 8 compatibility (null coalescing, type hints, return types) - Replace azure theme template with generic wave-compatible template - Add SSL URL rewriting support for alternative source URLs - Add 301/302/303/307 redirect handling with URL rewriting - Add configurable cache TTL with file cache support - Add SSL certificate verification toggle - Update admin configuration template - Remove deprecated events system and content widget Tested with OXID eShop 6.5.5 CE, PHP 8.1, WordPress as CMS backend. Co-Authored-By: Claude Opus 4.6 --- Application/Controller/Admin/ToxidSetup.php | 10 + .../Controller/Admin/ToxidSetupList.php | 10 + .../Controller/Admin/ToxidSetupMain.php | 72 ++ Application/Controller/ToxidController.php | 62 ++ .../views/admin/de/toxid_admin_lang.php | 29 + .../views/admin/tpl/toxid_setup_main.tpl | 180 ++++ Application/views/tpl/page/toxid/toxid.tpl | 25 + CMS-templates/TYPO3/TYPO3-Demo-Config.txt | 66 -- .../wp-content/themes/toxid/footer.php | 25 - .../wp-content/themes/toxid/header.php | 15 - .../wp-content/themes/toxid/sidebar.php | 0 .../wp-content/themes/toxid/style.css | 16 - composer.json | 32 +- composer.lock | 991 ------------------ controller/admin/toxid_setup.php | 5 - controller/admin/toxid_setup_list.php | 6 - controller/admin/toxid_setup_main.php | 62 -- controller/toxid_curl.php | 114 -- core/SeoDecoder.php | 115 ++ core/SmartyParser.php | 20 + core/UtilsView.php | 21 + core/ViewConfig.php | 25 + core/facades/toxid_curl_smarty_parser.php | 11 - core/toxid_curl_events.php | 54 - core/toxid_curl_oxseodecoder.php | 150 --- core/toxid_curl_oxutilsview.php | 30 - core/toxid_curl_oxviewconfig.php | 55 - core/toxidcurl.php | 746 ++++++------- metadata.php | 103 +- phpunit.xml | 32 - smarty/plugins/function.toxid_load.php | 118 +-- tests/core/toxidcurlTest.php | 21 - tests/data/de/index.html | 16 - tests/data/de/subpage.html | 16 - tests/data/en/index.html | 16 - tests/data/en/subpage.html | 16 - .../blocks/_formparams_admin_formparams.tpl | 5 - views/admin/de/module_options.php | 16 - views/admin/de/toxid_admin_lang.php | 43 - views/admin/en/module_options.php | 16 - views/admin/en/toxid_admin_lang.php | 43 - views/admin/tpl/toxid_setup_main.tpl | 249 ----- views/azure/product.tpl | 6 - views/azure/toxid_curl.tpl | 19 - views/widgets/toxid_content_widget.tpl | 1 - widgets/toxid_curl_content_widget.php | 48 - 46 files changed, 975 insertions(+), 2756 deletions(-) create mode 100644 Application/Controller/Admin/ToxidSetup.php create mode 100644 Application/Controller/Admin/ToxidSetupList.php create mode 100644 Application/Controller/Admin/ToxidSetupMain.php create mode 100644 Application/Controller/ToxidController.php create mode 100644 Application/views/admin/de/toxid_admin_lang.php create mode 100644 Application/views/admin/tpl/toxid_setup_main.tpl create mode 100644 Application/views/tpl/page/toxid/toxid.tpl delete mode 100644 CMS-templates/TYPO3/TYPO3-Demo-Config.txt delete mode 100644 CMS-templates/Wordpress/wp-content/themes/toxid/footer.php delete mode 100644 CMS-templates/Wordpress/wp-content/themes/toxid/header.php delete mode 100644 CMS-templates/Wordpress/wp-content/themes/toxid/sidebar.php delete mode 100644 CMS-templates/Wordpress/wp-content/themes/toxid/style.css delete mode 100644 composer.lock delete mode 100644 controller/admin/toxid_setup.php delete mode 100644 controller/admin/toxid_setup_list.php delete mode 100644 controller/admin/toxid_setup_main.php delete mode 100644 controller/toxid_curl.php create mode 100644 core/SeoDecoder.php create mode 100644 core/SmartyParser.php create mode 100644 core/UtilsView.php create mode 100644 core/ViewConfig.php delete mode 100644 core/facades/toxid_curl_smarty_parser.php delete mode 100644 core/toxid_curl_events.php delete mode 100644 core/toxid_curl_oxseodecoder.php delete mode 100644 core/toxid_curl_oxutilsview.php delete mode 100644 core/toxid_curl_oxviewconfig.php delete mode 100644 phpunit.xml delete mode 100644 tests/core/toxidcurlTest.php delete mode 100644 tests/data/de/index.html delete mode 100644 tests/data/de/subpage.html delete mode 100644 tests/data/en/index.html delete mode 100644 tests/data/en/subpage.html delete mode 100644 views/admin/blocks/_formparams_admin_formparams.tpl delete mode 100644 views/admin/de/module_options.php delete mode 100644 views/admin/de/toxid_admin_lang.php delete mode 100644 views/admin/en/module_options.php delete mode 100644 views/admin/en/toxid_admin_lang.php delete mode 100644 views/admin/tpl/toxid_setup_main.tpl delete mode 100644 views/azure/product.tpl delete mode 100644 views/azure/toxid_curl.tpl delete mode 100644 views/widgets/toxid_content_widget.tpl delete mode 100644 widgets/toxid_curl_content_widget.php diff --git a/Application/Controller/Admin/ToxidSetup.php b/Application/Controller/Admin/ToxidSetup.php new file mode 100644 index 0000000..d378041 --- /dev/null +++ b/Application/Controller/Admin/ToxidSetup.php @@ -0,0 +1,10 @@ +_aViewData['aToxidCurlSource'] = $oConf->getShopConfVar('aToxidCurlSource'); + $this->_aViewData['aToxidCurlSourceSsl'] = $oConf->getShopConfVar('aToxidCurlSourceSsl'); + $this->_aViewData['aToxidSearchUrl'] = $oConf->getShopConfVar('aToxidSearchUrl'); + $this->_aViewData['aToxidCurlUrlParams'] = $oConf->getShopConfVar('aToxidCurlUrlParams'); + $this->_aViewData['aToxidCurlSeoSnippets'] = $oConf->getShopConfVar('aToxidCurlSeoSnippets'); + $this->_aViewData['toxidDontRewriteRelUrls'] = $oConf->getShopConfVar('toxidDontRewriteRelUrls'); + $this->_aViewData['toxidDontRewriteFileExtension'] = $oConf->getShopConfVar('toxidDontRewriteFileExtension'); + $this->_aViewData['toxidRewriteUrlEncoded'] = $oConf->getShopConfVar('toxidRewriteUrlEncoded'); + $this->_aViewData['toxidDontRewriteUrls'] = $oConf->getShopConfVar('toxidDontRewriteUrls'); + $this->_aViewData['bToxidDontPassPostVarsToCms'] = $oConf->getShopConfVar('bToxidDontPassPostVarsToCms'); + $this->_aViewData['bToxidRedirect301ToStartpage'] = $oConf->getShopConfVar('bToxidRedirect301ToStartpage'); + $this->_aViewData['toxidCacheTtl'] = $oConf->getShopConfVar('toxidCacheTtl'); + $this->_aViewData['toxidError404Link'] = $oConf->getShopConfVar('toxidError404Link'); + $this->_aViewData['aToxidNotFoundUrl'] = $oConf->getShopConfVar('aToxidNotFoundUrl'); + $this->_aViewData['aToxidCurlUrlAdminParams'] = $oConf->getShopConfVar('aToxidCurlUrlAdminParams'); + $this->_aViewData['toxidAllowedCmsRequestParams'] = $oConf->getShopConfVar('toxidAllowedCmsRequestParams'); + $this->_aViewData['toxidDontVerifySSLCert'] = $oConf->getShopConfVar('toxidDontVerifySSLCert'); + + return parent::render(); + } + + /** + * Saves the settings + */ + public function save(): void + { + $oConf = Registry::getConfig(); + $aParams = $oConf->getRequestParameter("editval"); + $sShopId = $oConf->getShopId(); + + if (!is_array($aParams)) { + return; + } + + $oConf->saveShopConfVar('arr', 'aToxidCurlSource', $aParams['aToxidCurlSource'] ?? [], $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('arr', 'aToxidCurlSourceSsl', $aParams['aToxidCurlSourceSsl'] ?? [], $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('arr', 'aToxidSearchUrl', $aParams['aToxidSearchUrl'] ?? [], $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('arr', 'aToxidCurlUrlParams', $aParams['aToxidCurlUrlParams'] ?? [], $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('arr', 'aToxidCurlSeoSnippets', $aParams['aToxidCurlSeoSnippets'] ?? [], $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('str', 'toxidDontRewriteRelUrls', $aParams['toxidDontRewriteRelUrls'] ?? '', $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('str', 'toxidDontRewriteFileExtension', $aParams['toxidDontRewriteFileExtension'] ?? '', $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('str', 'toxidCacheTtl', $aParams['toxidCacheTtl'] ?? '', $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('str', 'toxidError404Link', $aParams['toxidError404Link'] ?? '', $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('arr', 'aToxidNotFoundUrl', $aParams['aToxidNotFoundUrl'] ?? [], $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('bl', 'toxidRewriteUrlEncoded', $aParams['toxidRewriteUrlEncoded'] ?? 0, $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('bl', 'toxidDontRewriteUrls', $aParams['toxidDontRewriteUrls'] ?? 0, $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('bl', 'bToxidDontPassPostVarsToCms', $aParams['bToxidDontPassPostVarsToCms'] ?? 0, $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('bl', 'bToxidRedirect301ToStartpage', $aParams['bToxidRedirect301ToStartpage'] ?? 0, $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('arr', 'aToxidCurlUrlAdminParams', $aParams['aToxidCurlUrlAdminParams'] ?? [], $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('str', 'toxidAllowedCmsRequestParams', $aParams['toxidAllowedCmsRequestParams'] ?? '', $sShopId, self::CONFIG_MODULE_NAME); + $oConf->saveShopConfVar('bl', 'toxidDontVerifySSLCert', $aParams['toxidDontVerifySSLCert'] ?? 0, $sShopId, self::CONFIG_MODULE_NAME); + } +} diff --git a/Application/Controller/ToxidController.php b/Application/Controller/ToxidController.php new file mode 100644 index 0000000..3dff873 --- /dev/null +++ b/Application/Controller/ToxidController.php @@ -0,0 +1,62 @@ +_sPageTitle; + } + + /** + * Template variable getter. Returns meta description from CMS + */ + public function getMetaDescription() + { + $sDescription = strip_tags(Registry::get(ToxidCurl::class)->_sPageDescription ?? ''); + + if ($sDescription) { + $this->_sMetaDescription = $sDescription; + } + + return $this->_sMetaDescription; + } + + /** + * Template variable getter. Returns meta keywords from CMS + */ + public function getMetaKeywords() + { + $sKeywords = strip_tags(Registry::get(ToxidCurl::class)->_sPageKeywords ?? ''); + + if ($sKeywords) { + $this->_sMetaKeywords = $sKeywords; + } + + return $this->_sMetaKeywords; + } + + /** + * Render the CMS page + */ + public function render() + { + return parent::render(); + } +} diff --git a/Application/views/admin/de/toxid_admin_lang.php b/Application/views/admin/de/toxid_admin_lang.php new file mode 100644 index 0000000..09fcee9 --- /dev/null +++ b/Application/views/admin/de/toxid_admin_lang.php @@ -0,0 +1,29 @@ + 'UTF-8', + 'toxid_setup' => 'TOXID Einstellungen', + 'toxid_setup_main' => 'TOXID Grundeinstellungen', + 'TOXID_SOURCE' => 'CMS URL', + 'TOXID_SOURCE_SSL' => 'CMS SSL-URL', + 'TOXID_SEO_SNIPPET' => 'URL Identifier / SEO-Snippet', + 'TOXID_SEARCH_URL' => 'URL zum Aufruf der Suche (optional)', + 'TOXID_NOT_FOUND_URL' => '404 Not found URL (optional)', + 'TOXID_PARAM' => 'TOXID URL-Parameter', + 'TOXID_PREVIEW_PARAM' => 'Admin URL-Parameter (z.B. Blog Preview)', + 'TOXID_CMS_PARAMS' => 'Erlaubte, CMS spezifische Parameter (kommaseparierte Liste)', + 'TOXID_DONT_REWRITE' => 'URLs nicht umschreiben', + 'TOXID_DONT_PASSTHROUGH' => 'POST-Parameter nicht an CMS durchreichen', + 'TOXID_DONT_REWRITE_REL_URLS' => 'URLs fuer bestimmte "rel" Attributwerte nicht umschreiben (kommaseparierte Liste)', + 'TOXID_DONT_REWRITE_URLS_WITH_FILE_EXTENSIONS' => 'URLs fuer bestimmte Dateiendungen nicht umschreiben (kommaseparierte Liste)', + 'TOXID_ERROR_404_LINK' => 'Redirect-URL bei 404 Fehler (optional)', + 'TOXID_REWRITE_URLENCODED' => 'URL-kodierte Links umschreiben', + 'TOXID_REDIRECT_301_TO_STARTPAGE' => 'Bei 301 auf Startseite weiterleiten', + 'TOXID_GENERAL' => 'Allgemein', + 'TOXID_CACHE' => 'Cache', + 'TOXID_CACHE_TTL' => 'Cache-Lebenszeit (TTL) in Sekunden', + 'HELP_TOXID_CACHE_TTL' => '0 => unendlich
kein Wert => Cache deaktiviert', + 'TOXID_DONT_VERIFY_SSL_CERTIFICATE' => 'SSL-Zertifikat nicht ueberpruefen', +]; diff --git a/Application/views/admin/tpl/toxid_setup_main.tpl b/Application/views/admin/tpl/toxid_setup_main.tpl new file mode 100644 index 0000000..d4dbcf9 --- /dev/null +++ b/Application/views/admin/tpl/toxid_setup_main.tpl @@ -0,0 +1,180 @@ +[{include file="headitem.tpl" title="TOXID cURL Konfiguration"}] + + +[{if $readonly}] +[{assign var="readonly" value="readonly disabled"}] +[{else}] +[{assign var="readonly" value=""}] +[{/if}] +
+ [{$oViewConf->getHiddenSid()}] + + + + + + +
+
+ [{$oViewConf->getHiddenSid()}] + + + +
+
+ TOXID cURL - CMS Integration +
+
+

Integrates CMS content (WordPress, TYPO3 etc.) into OXID eShop via cURL/XML.

+
+
+
+
+
+
+ Spracheinstellungen +
+
+ [{foreach from=$languages key=lang item=olang}] +
+ [{$olang->name}] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CMS Quell-URL: + +
CMS Quell-URL (SSL): + +
Such-URL: + +
URL-Parameter: + +
URL Identifier / SEO-Snippet: + +
Preview-Parameter (Admin): + +
404 Fallback-URL: + +
+
+ [{/foreach}] +
+ Allgemein + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Erlaubte CMS Request-Parameter: + +
Nicht umschreiben (rel-Werte): + +
Nicht umschreiben (Dateiendungen): + +
404 Redirect-Link: + +
+ + + URL-kodierte Links umschreiben +
+ + + URL-Umschreibung deaktivieren +
+ + + POST-Variablen nicht an CMS weiterleiten +
+ + + 301-Redirects zur Startseite +
+ + + SSL-Zertifikat nicht verifizieren +
+
+
+ Cache + + + + + +
Cache TTL (Sekunden): + + (Standard-TTL, kann pro Snippet im Template ueberschrieben werden) +
+
+
+
+
+
+
+ +
+ +[{include file="bottomnaviitem.tpl"}] +[{include file="bottomitem.tpl"}] diff --git a/Application/views/tpl/page/toxid/toxid.tpl b/Application/views/tpl/page/toxid/toxid.tpl new file mode 100644 index 0000000..6c1a5a7 --- /dev/null +++ b/Application/views/tpl/page/toxid/toxid.tpl @@ -0,0 +1,25 @@ +[{assign var='toxid' value=$oViewConf->getToxid()}] + +[{capture append="oxidBlock_content"}] +
+ [{* CMS navigation (e.g. WordPress categories) as sidebar *}] + [{assign var="toxidNav" value=$toxid->getCmsSnippet('navigation', false, null, 1800)}] + [{if $toxidNav}] +
+
+ [{$toxidNav}] +
+
+
+ [{else}] +
+ [{/if}] + [{* CMS content (article list or single article) *}] +
+ [{$toxid->getCmsSnippet('content')}] +
+
+
+[{/capture}] + +[{include file="layout/page.tpl" blContentPage=true}] diff --git a/CMS-templates/TYPO3/TYPO3-Demo-Config.txt b/CMS-templates/TYPO3/TYPO3-Demo-Config.txt deleted file mode 100644 index ff25b5e..0000000 --- a/CMS-templates/TYPO3/TYPO3-Demo-Config.txt +++ /dev/null @@ -1,66 +0,0 @@ -#+++localconf.php+++# -$TYPO3_CONF_VARS['BE']['forceCharset'] = 'utf-8'; - -#+++TYPOScript+++# -######### HAUPTNAVIGATION ########## -lib.mainnav = HMENU -lib.mainnav.wrap = -#lib.mainnav.wrap = | -lib.mainnav { - 1 = TMENU - 1.wrap = - 1.noBlur = 1 - 1.NO.wrapItemAndSub =
  • |
  • - 2 < .1 - 2.wrap = - 3 < .1 -} - -########## CONTENT ########## -lib.content = COA -lib.content.wrap = -lib.content.10 < styles.content.get - -lib.metadata = COA -lib.metadata { - wrap = | - 10 = TEXT - 10.cObject = TEXT - 10.cObject { - data = register:newsKeywords - ifEmpty.field = keywords - wrap = - } - 20 = TEXT - 20.cObject = TEXT - 20.cObject { - data = register:newsTitle - ifEmpty.field = title - wrap = <![CDATA[|]]> - } - 30 = TEXT - 30.cObject = TEXT - 30.cObject { - data = register:newsSubheader - ifEmpty.field = description - wrap = - } -} - -########## PAGE ########## -page = PAGE -page.typeNum = 0 -page.config { - renderCharset = utf-8 -# metaCharset = utf-8 - disableAllHeaderCode = 1 - additionalHeaders = Content-type:text/xml;charset=utf-8 - absRefPrefix = http://192.168.141.128/typo3/ - simulateStaticDocuments = 0 - baseURL = http://192.168.141.128/typo3/ - tx_realurl_enable = 1 -} -page.10 < lib.mainnav -page.20 < lib.content -page.30 < lib.metadata -page.wrap = | \ No newline at end of file diff --git a/CMS-templates/Wordpress/wp-content/themes/toxid/footer.php b/CMS-templates/Wordpress/wp-content/themes/toxid/footer.php deleted file mode 100644 index 1eb4429..0000000 --- a/CMS-templates/Wordpress/wp-content/themes/toxid/footer.php +++ /dev/null @@ -1,25 +0,0 @@ - -]]> - - -]]>
    -
    - - -
    -
    - -]]> \ No newline at end of file diff --git a/CMS-templates/Wordpress/wp-content/themes/toxid/header.php b/CMS-templates/Wordpress/wp-content/themes/toxid/header.php deleted file mode 100644 index 565e30b..0000000 --- a/CMS-templates/Wordpress/wp-content/themes/toxid/header.php +++ /dev/null @@ -1,15 +0,0 @@ - section and everything up till
    - * - * @package WordPress - * @subpackage Twenty_Twelve - * @since Twenty Twelve 1.0 - */ -echo ''; -?> - 'primary', 'menu_class' => 'nav-menu' ) ); ?> -]]>=7.4" + }, + "autoload": { + "psr-4": { + "Toxid\\": "" + } + }, + "extra": { + "oxideshop": { + "target-directory": "toxid_curl" + } + } } diff --git a/composer.lock b/composer.lock deleted file mode 100644 index fc16392..0000000 --- a/composer.lock +++ /dev/null @@ -1,991 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "3e050f9dd09463bbbddc2a7036b17d2a", - "packages": [], - "packages-dev": [ - { - "name": "pdepend/pdepend", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/pdepend/pdepend.git", - "reference": "b74f2bb68e86104cd97dfb8d74209692c9b465ce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/b74f2bb68e86104cd97dfb8d74209692c9b465ce", - "reference": "b74f2bb68e86104cd97dfb8d74209692c9b465ce", - "shasum": "" - }, - "require": { - "symfony/config": "@stable", - "symfony/dependency-injection": "@stable", - "symfony/filesystem": "@stable" - }, - "require-dev": { - "phpunit/phpunit": "3.*@stable", - "squizlabs/php_codesniffer": "@stable" - }, - "bin": [ - "src/bin/pdepend" - ], - "type": "library", - "autoload": { - "psr-0": { - "PDepend\\": "src/main/php/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Official version of pdepend to be handled with Composer", - "time": "2014-05-21 09:48:10" - }, - { - "name": "phpmd/oxmd", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/OXID-eSales/oxmd.git", - "reference": "0aab49108b256ff76202f13def73ab3f732ee946" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/OXID-eSales/oxmd/zipball/0aab49108b256ff76202f13def73ab3f732ee946", - "reference": "0aab49108b256ff76202f13def73ab3f732ee946", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "phpmd/phpmd": "2.0.*" - }, - "require-dev": { - "phpunit/phpunit": "@stable" - }, - "bin": [ - "src/bin/oxmd" - ], - "type": "library", - "autoload": { - "psr-0": { - "PHPMD\\OXMD": "src/main/php/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Official PHPMD OXID extension.", - "time": "2014-05-21 13:25:15" - }, - { - "name": "phpmd/phpmd", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/phpmd/phpmd.git", - "reference": "68ced5452910d3555a38720bd87f5f2356c5a003" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/68ced5452910d3555a38720bd87f5f2356c5a003", - "reference": "68ced5452910d3555a38720bd87f5f2356c5a003", - "shasum": "" - }, - "require": { - "pdepend/pdepend": "2.0.*", - "php": ">=5.3.0", - "symfony/config": "@stable", - "symfony/dependency-injection": "@stable", - "symfony/filesystem": "@stable" - }, - "bin": [ - "src/bin/phpmd" - ], - "type": "library", - "autoload": { - "psr-0": { - "PHPMD\\": "src/main/php", - "PDepend\\": "vendor/pdepend/pdepend/src/main/php/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "../../pdepend/pdepend/src/main/php", - "src/main/php" - ], - "license": [ - "BSD-3-Clause" - ], - "description": "Official version of PHPMD handled with Composer.", - "time": "2014-05-21 12:45:23" - }, - { - "name": "phpunit/php-code-coverage", - "version": "2.0.8", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "58401826c8cfc8fd689b60026e91c337df374bca" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/58401826c8cfc8fd689b60026e91c337df374bca", - "reference": "58401826c8cfc8fd689b60026e91c337df374bca", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-file-iterator": "~1.3.1", - "phpunit/php-text-template": "~1.2.0", - "phpunit/php-token-stream": "~1.2.2", - "sebastian/environment": "~1.0.0", - "sebastian/version": "~1.0.3" - }, - "require-dev": { - "ext-xdebug": ">=2.1.4", - "phpunit/phpunit": "~4.0.14" - }, - "suggest": { - "ext-dom": "*", - "ext-xdebug": ">=2.2.1", - "ext-xmlwriter": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "time": "2014-05-26 14:55:24" - }, - { - "name": "phpunit/php-file-iterator", - "version": "1.3.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "File/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "time": "2013-10-10 15:34:57" - }, - { - "name": "phpunit/php-text-template", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "Text/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "time": "2014-01-30 17:20:04" - }, - { - "name": "phpunit/php-timer", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "time": "2013-08-02 07:42:54" - }, - { - "name": "phpunit/php-token-stream", - "version": "1.2.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/ad4e1e23ae01b483c16f600ff1bebec184588e32", - "reference": "ad4e1e23ae01b483c16f600ff1bebec184588e32", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, - "autoload": { - "classmap": [ - "PHP/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", - "keywords": [ - "tokenizer" - ], - "time": "2014-03-03 05:10:30" - }, - { - "name": "phpunit/phpunit", - "version": "4.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "939cb801b3b2aa253aedd0b279f40bb8f35cec91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/939cb801b3b2aa253aedd0b279f40bb8f35cec91", - "reference": "939cb801b3b2aa253aedd0b279f40bb8f35cec91", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-spl": "*", - "php": ">=5.3.3", - "phpunit/php-code-coverage": "~2.0", - "phpunit/php-file-iterator": "~1.3.1", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "~1.0.2", - "phpunit/phpunit-mock-objects": "~2.1", - "sebastian/comparator": "~1.0", - "sebastian/diff": "~1.1", - "sebastian/environment": "~1.0", - "sebastian/exporter": "~1.0", - "sebastian/version": "~1.0", - "symfony/yaml": "~2.0" - }, - "suggest": { - "phpunit/php-invoker": "~1.1" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "", - "../../symfony/yaml/" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "http://www.phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "time": "2014-06-11 14:15:47" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "2.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "1a894a16b6c15fcdc5ef2b110f0e6233952c9b0f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/1a894a16b6c15fcdc5ef2b110f0e6233952c9b0f", - "reference": "1a894a16b6c15fcdc5ef2b110f0e6233952c9b0f", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.1" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2014-06-07 16:22:57" - }, - { - "name": "sebastian/comparator", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", - "reference": "f7069ee51fa9fb6c038e16a9d0e3439f5449dcf2", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.1", - "sebastian/exporter": "~1.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "time": "2014-05-02 07:05:58" - }, - { - "name": "sebastian/diff", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", - "reference": "1e091702a5a38e6b4c1ba9ca816e3dd343df2e2d", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2013-08-03 16:46:33" - }, - { - "name": "sebastian/environment", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/79517609ec01139cd7e9fded0dd7ce08c952ef6a", - "reference": "79517609ec01139cd7e9fded0dd7ce08c952ef6a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "4.0.*@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "time": "2014-02-18 16:17:19" - }, - { - "name": "sebastian/exporter", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", - "reference": "1f9a98e6f5dfe0524cb8c6166f7c82f3e9ae1529", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "4.0.*@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net", - "role": "Lead" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "time": "2014-02-16 08:26:31" - }, - { - "name": "sebastian/version", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", - "reference": "b6e1f0cf6b9e1ec409a0d3e2f2a5fb0998e36b43", - "shasum": "" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "time": "2014-03-07 15:35:33" - }, - { - "name": "symfony/config", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Config", - "source": { - "type": "git", - "url": "https://github.com/symfony/Config.git", - "reference": "9c8caadb38ecc69ac35ab31af4d1996944b5a09f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/9c8caadb38ecc69ac35ab31af4d1996944b5a09f", - "reference": "9c8caadb38ecc69ac35ab31af4d1996944b5a09f", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/filesystem": "~2.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Config\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Config Component", - "homepage": "http://symfony.com", - "time": "2014-04-22 08:11:23" - }, - { - "name": "symfony/dependency-injection", - "version": "v2.5.0", - "target-dir": "Symfony/Component/DependencyInjection", - "source": { - "type": "git", - "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "5dfb4c2b74c4976efe1efa783370da656a2dd742" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/5dfb4c2b74c4976efe1efa783370da656a2dd742", - "reference": "5dfb4c2b74c4976efe1efa783370da656a2dd742", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/config": "~2.2", - "symfony/expression-language": "~2.4", - "symfony/yaml": "~2.0" - }, - "suggest": { - "symfony/config": "", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\DependencyInjection\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony DependencyInjection Component", - "homepage": "http://symfony.com", - "time": "2014-05-12 09:28:39" - }, - { - "name": "symfony/filesystem", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Filesystem", - "source": { - "type": "git", - "url": "https://github.com/symfony/Filesystem.git", - "reference": "98e831eac836a0a5911626ce82684155f21d0e4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/98e831eac836a0a5911626ce82684155f21d0e4d", - "reference": "98e831eac836a0a5911626ce82684155f21d0e4d", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Filesystem\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "http://symfony.com", - "time": "2014-04-16 10:36:21" - }, - { - "name": "symfony/yaml", - "version": "v2.5.0", - "target-dir": "Symfony/Component/Yaml", - "source": { - "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "b4b09c68ec2f2727574544ef0173684281a5033c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/b4b09c68ec2f2727574544ef0173684281a5033c", - "reference": "b4b09c68ec2f2727574544ef0173684281a5033c", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Yaml\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org", - "role": "Lead Developer" - }, - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "http://symfony.com", - "time": "2014-05-16 14:25:18" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "phpunit/phpunit": 0, - "phpmd/oxmd": 0 - }, - "platform": [], - "platform-dev": [] -} diff --git a/controller/admin/toxid_setup.php b/controller/admin/toxid_setup.php deleted file mode 100644 index f5a488d..0000000 --- a/controller/admin/toxid_setup.php +++ /dev/null @@ -1,5 +0,0 @@ -_aViewData['aToxidCurlSource'] = $oConf->getShopConfVar('aToxidCurlSource'); - $this->_aViewData['aToxidCurlSourceSsl'] = $oConf->getShopConfVar('aToxidCurlSourceSsl'); - $this->_aViewData['aToxidSearchUrl'] = $oConf->getShopConfVar('aToxidSearchUrl'); - $this->_aViewData['aToxidCurlUrlParams'] = $oConf->getShopConfVar('aToxidCurlUrlParams'); - $this->_aViewData['aToxidCurlSeoSnippets'] = $oConf->getShopConfVar('aToxidCurlSeoSnippets'); - $this->_aViewData['toxidDontRewriteRelUrls'] = $oConf->getShopConfVar('toxidDontRewriteRelUrls'); - $this->_aViewData['toxidDontRewriteFileExtension'] = $oConf->getShopConfVar('toxidDontRewriteFileExtension'); - $this->_aViewData['toxidRewriteUrlEncoded'] = $oConf->getShopConfVar('toxidRewriteUrlEncoded'); - $this->_aViewData['toxidDontRewriteUrls'] = $oConf->getShopConfVar('toxidDontRewriteUrls'); - $this->_aViewData['bToxidDontPassPostVarsToCms'] = $oConf->getShopConfVar('bToxidDontPassPostVarsToCms'); - $this->_aViewData['bToxidRedirect301ToStartpage'] = $oConf->getShopConfVar('bToxidRedirect301ToStartpage'); - $this->_aViewData['toxidCacheTtl'] = $oConf->getShopConfVar('toxidCacheTtl'); - $this->_aViewData['toxidError404Link'] = $oConf->getShopConfVar('toxidError404Link'); - $this->_aViewData['aToxidNotFoundUrl'] = $oConf->getShopConfVar('aToxidNotFoundUrl'); - $this->_aViewData['aToxidCurlUrlAdminParams'] = $oConf->getShopConfVar('aToxidCurlUrlAdminParams'); - $this->_aViewData['toxidAllowedCmsRequestParams'] = $oConf->getShopConfVar('toxidAllowedCmsRequestParams'); - $this->_aViewData['toxidDontVerifySSLCert'] = $oConf->getShopConfVar('toxidDontVerifySSLCert'); - - return parent::render(); - } - - /** - * Saves the settings - * - * @return void - */ - public function save() - { - $oConf = oxRegistry::getConfig(); - $aParams = $oConf->getRequestParameter("editval"); - $sShopId = $oConf->getShopId(); - - $oConf->saveShopConfVar('arr', 'aToxidCurlSource', $aParams['aToxidCurlSource'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('arr', 'aToxidCurlSourceSsl', $aParams['aToxidCurlSourceSsl'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('arr', 'aToxidSearchUrl', $aParams['aToxidSearchUrl'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('arr', 'aToxidCurlUrlParams', $aParams['aToxidCurlUrlParams'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('arr', 'aToxidCurlSeoSnippets', $aParams['aToxidCurlSeoSnippets'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('str', 'toxidDontRewriteRelUrls', $aParams['toxidDontRewriteRelUrls'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('str', 'toxidDontRewriteFileExtension', $aParams['toxidDontRewriteFileExtension'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('str', 'toxidCacheTtl', $aParams['toxidCacheTtl'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('str', 'toxidError404Link', $aParams['toxidError404Link'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('arr', 'aToxidNotFoundUrl', $aParams['aToxidNotFoundUrl'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('bl', 'toxidRewriteUrlEncoded', $aParams['toxidRewriteUrlEncoded'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('bl', 'toxidDontRewriteUrls', $aParams['toxidDontRewriteUrls'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('bl', 'bToxidDontPassPostVarsToCms', $aParams['bToxidDontPassPostVarsToCms'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('bl', 'bToxidRedirect301ToStartpage', $aParams['bToxidRedirect301ToStartpage'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('arr', 'aToxidCurlUrlAdminParams', $aParams['aToxidCurlUrlAdminParams'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('str', 'toxidAllowedCmsRequestParams', $aParams['toxidAllowedCmsRequestParams'], $sShopId, self::CONFIG_MODULE_NAME); - $oConf->saveShopConfVar('bl', 'toxidDontVerifySSLCert', $aParams['toxidDontVerifySSLCert'], $sShopId, self::CONFIG_MODULE_NAME); - } -} diff --git a/controller/toxid_curl.php b/controller/toxid_curl.php deleted file mode 100644 index 8eb51cb..0000000 --- a/controller/toxid_curl.php +++ /dev/null @@ -1,114 +0,0 @@ -_initialized = true; - } - - public function getInit() - { - return $this->_initialized; - } - - - /** - * Template variable getter. Returns tag title - * - * @return string - */ - public function getTitle() - { - $sTitle = oxRegistry::get('toxidCurl')->_sPageTitle; - return $sTitle; - } - - /** - * Template variable getter. Returns meta description - * - * @return string - */ - public function getMetaDescription() - { - $this->_xMetaDescription = strip_tags(oxRegistry::get('toxidCurl')->_sPageDescription); - if ( $this->_sMetaDescription === null ) { - $this->_sMetaDescription = false; - - // set special meta description ? - if ( ( $sDescription = $this->_xMetaDescription ) ) { - $this->_sMetaDescription = $sDescription; - } else { - $this->_sMetaDescription = $this->_prepareMetaDescription( $this->_xMetaDescription ); - } - } - - return $this->_sMetaDescription; - } - - /** - * Template variable getter. Returns meta keywords - * - * @return string - */ - public function getMetaKeywords() - { - $this->_xMetaKeywords = strip_tags(oxRegistry::get('toxidCurl')->_sPageKeywords); - if ( $this->_sMetaKeywords === null ) { - $this->_sMetaKeywords = false; - - // set special meta keywords ? - if ( ( $sKeywords = $this->_xMetaKeywords ) ) { - $this->_sMetaKeywords = $sKeywords; - } else { - $this->_sMetaKeywords = $this->_prepareMetaKeyword( $this->_xMetaKeywords, true ); - } - } - - return $this->_sMetaKeywords; - } - - /** - * regular render function - */ - public function render() - { - if ( version_compare(oxRegistry::getConfig()->getVersion(), '4.5.0') < 0 ) { - $this->_sThisTemplate = 'toxid_curl.tpl'; - } - return parent::render(); - } - -} - diff --git a/core/SeoDecoder.php b/core/SeoDecoder.php new file mode 100644 index 0000000..60b5e20 --- /dev/null +++ b/core/SeoDecoder.php @@ -0,0 +1,115 @@ +isToxidUrl($sSeoUrl)) { + $aRet = []; + $aRet['cl'] = 'toxid'; + $aRet['lang'] = $this->decodedUrl['toxidLang']; + $toxidUrl = $this->decodedUrl['toxidUrl']; + + Registry::getLang()->setBaseLanguage($aRet['lang']); + $this->getConfig()->setConfigParam('sToxidCurlPage', $toxidUrl); + + return $aRet; + } + if (isset($this->decodedUrl['params'])) { + return $this->decodedUrl['params']; + } + if (isset($this->decodedUrl['url'])) { + Registry::getUtils()->redirect($this->getConfig()->getShopURL() . $this->decodedUrl['url'], false); + } + + return false; + } + + /** + * Decode SEO snippet URL for TOXID + */ + protected function detectToxidAndLang($sSeoUrl) + { + $seoSnippets = $this->getConfig()->getConfigParam('aToxidCurlSeoSnippets'); + + if (!is_array($seoSnippets)) { + return false; + } + + foreach ($seoSnippets as $langId => $snippet) { + if ($snippet === '' || $snippet === null) { + continue; + } + if (strpos($sSeoUrl, $snippet . '/') !== false) { + $aUrlSplit = explode($snippet . '/', $sSeoUrl); + return [ + 'lang' => $langId, + 'url' => $aUrlSplit[1] ?? '', + ]; + } + } + + return false; + } + + /** + * Check for TOXID URL + */ + private function isToxidUrl($sSeoUrl): bool + { + $decodedToxidUrl = $this->detectToxidAndLang($sSeoUrl); + if (false !== $decodedToxidUrl) { + $this->decodedUrl['toxidUrl'] = $decodedToxidUrl['url']; + $languageId = Registry::getLang()->getBaseLanguage(); + $this->decodedUrl['toxidLang'] = $this->processToxidLangByUrl($languageId, $this->decodedUrl['toxidUrl']); + + return true; + } + + $aParams = parent::decodeUrl($sSeoUrl); + if (false !== $aParams) { + $this->decodedUrl['params'] = $aParams; + return false; + } + + $sUrl = $this->_decodeOldUrl($sSeoUrl); + if (false !== $sUrl) { + $this->decodedUrl['url'] = $sUrl; + return false; + } + + $sUrl = $this->_decodeSimpleUrl($sSeoUrl); + if (null !== $sUrl) { + $this->decodedUrl['url'] = $sUrl; + return false; + } + + // If nothing matched, treat as TOXID URL + $this->decodedUrl['toxidUrl'] = $sSeoUrl; + $languageId = Registry::getLang()->getBaseLanguage(); + $this->decodedUrl['toxidLang'] = $this->processToxidLangByUrl($languageId, $this->decodedUrl['toxidUrl']); + + return true; + } + + /** + * Process TOXID language by URL + */ + protected function processToxidLangByUrl(int $languageId, string $sSeoUrl): int + { + return $languageId; + } +} diff --git a/core/SmartyParser.php b/core/SmartyParser.php new file mode 100644 index 0000000..53b2883 --- /dev/null +++ b/core/SmartyParser.php @@ -0,0 +1,20 @@ +parseThroughSmarty($content, md5($content), null, true); + } +} diff --git a/core/UtilsView.php b/core/UtilsView.php new file mode 100644 index 0000000..094dc9b --- /dev/null +++ b/core/UtilsView.php @@ -0,0 +1,21 @@ +plugins_dir; + $aPluginsDir[] = Registry::getConfig()->getModulesDir() . "toxid_curl/smarty/plugins/"; + + $oSmarty->plugins_dir = $aPluginsDir; + } +} diff --git a/core/ViewConfig.php b/core/ViewConfig.php new file mode 100644 index 0000000..8d89e5f --- /dev/null +++ b/core/ViewConfig.php @@ -0,0 +1,25 @@ +getInitialized()) { + $smartyParser = new SmartyParser(); + $toxidCurl->init($smartyParser); + } + + return $toxidCurl; + } +} diff --git a/core/facades/toxid_curl_smarty_parser.php b/core/facades/toxid_curl_smarty_parser.php deleted file mode 100644 index a05e872..0000000 --- a/core/facades/toxid_curl_smarty_parser.php +++ /dev/null @@ -1,11 +0,0 @@ -parseThroughSmarty($content, md5($content), null, true); - } -} - - diff --git a/core/toxid_curl_events.php b/core/toxid_curl_events.php deleted file mode 100644 index d4a637f..0000000 --- a/core/toxid_curl_events.php +++ /dev/null @@ -1,54 +0,0 @@ -getConfigParam("sCompileDir")."*"; - foreach (glob($dir) as $item) { - if (!is_dir($item)) { - @unlink($item); - } - } - - // reloading smarty object after activation - oxRegistry::get("oxUtilsView")->getSmarty(true); - } - - public static function onDeactivate() { - // reloading smarty object after deactivationg - // but blocks are still in tempaltes -> exception - // needs some optimization / workaround here, cause custom plugins dir is still in smarty object - - //oxRegistry::get("oxUtilsView")->getSmarty(true); - - - //clearing cache to force re-init smarty object (i hope) - $cfg = oxRegistry::getConfig(); - $dir = $cfg->getConfigParam("sCompileDir")."*"; - foreach (glob($dir) as $item) { - if (!is_dir($item)) { - @unlink($item); - } - } - } - -} - diff --git a/core/toxid_curl_oxseodecoder.php b/core/toxid_curl_oxseodecoder.php deleted file mode 100644 index 7d79bbf..0000000 --- a/core/toxid_curl_oxseodecoder.php +++ /dev/null @@ -1,150 +0,0 @@ -isToxidUrl($sSeoUrl)) { - $aRet['cl'] = 'toxid_curl'; - $aRet['lang'] = $this->decodedUrl['toxidLang']; - $toxidUrl = $this->decodedUrl['toxidUrl']; - - oxRegistry::getLang()->setBaseLanguage($aRet['lang']); - $this->getConfig()->setConfigParam('sToxidCurlPage', $toxidUrl); - - return $aRet; - } - if (isset($this->decodedUrl['params'])) { - return $this->decodedUrl['params']; - } - oxRegistry::getUtils()->redirect($this->getConfig()->getShopURL() . $this->decodedUrl['url'], false); - } - - /** - * Decode seo snippet url for toxid - * - * @param $sSeoUrl - * - * @return array|bool - */ - protected function detectToxidAndLang($sSeoUrl) - { - $seoSnippets = $this->getConfig()->getConfigParam('aToxidCurlSeoSnippets'); - foreach ($seoSnippets as $langId => $snippet) { - if ('' === $snippet) { - continue; - } - if (strpos($sSeoUrl, $snippet . '/') !== false) { - $aUrlSplit = explode($snippet . '/', $sSeoUrl); - $toxidInfo = array( - 'lang' => $langId, - 'url' => $aUrlSplit[1], - ); - - return $toxidInfo; - } - } - - // if nothing was found, return false - return false; - } - - /** - * Check for toxid url - * - * Detects toxid url using the seo snippet or if OXID cannot decode the url. - * - * @param $sSeoUrl - * - * @return bool - */ - private function isToxidUrl($sSeoUrl) - { - $decodedToxidUrl = $this->detectToxidAndLang($sSeoUrl); - if (false !== $decodedToxidUrl) { - $this->decodedUrl['toxidUrl'] = $decodedToxidUrl['url']; - $languageId = oxRegistry::getLang()->getBaseLanguage(); - $this->decodedUrl['toxidLang'] = $this->processToxidLangByUrl($languageId, $this->decodedUrl['toxidUrl']); - - return true; - } - $aParams = parent::decodeUrl($sSeoUrl); - if (false !== $aParams) { - $this->decodedUrl['params'] = $aParams; - - return false; - } - $sUrl = $this->_decodeOldUrl($sSeoUrl); - if (false !== $sUrl) { - $this->decodedUrl['url'] = $sUrl; - - return false; - } - $sUrl = $this->_decodeSimpleUrl($sSeoUrl); - if (null !== $sUrl) { - $this->decodedUrl['url'] = $sUrl; - - return false; - } - - $this->decodedUrl['toxidUrl'] = $this->postProcessToxidUrl($sSeoUrl); - $languageId = oxRegistry::getLang()->getBaseLanguage(); - $this->decodedUrl['toxidLang'] = $this->processToxidLangByUrl($languageId, $this->decodedUrl['toxidUrl']); - - return true; - } - - /** - * @param string $sSeoUrl - * - * @return string - */ - protected function postProcessToxidUrl($sSeoUrl) - { - /* Waving chicken... */ - if (method_exists(get_parent_class(), 'postProcessToxidUrl')) { - $sSeoUrl = parent::postProcessToxidUrl($sSeoUrl); - } - - return $sSeoUrl; - } - - /** - * @param int $languageId - * @param string $sSeoUrl - * - * @return int - */ - protected function processToxidLangByUrl($languageId, $sSeoUrl) - { - if (method_exists(get_parent_class(), 'processToxidLangByUrl')) { - $languageId = parent::processToxidLangByUrl($languageId, $sSeoUrl); - } - - return (int) $languageId; - } -} diff --git a/core/toxid_curl_oxutilsview.php b/core/toxid_curl_oxutilsview.php deleted file mode 100644 index 6bc5d95..0000000 --- a/core/toxid_curl_oxutilsview.php +++ /dev/null @@ -1,30 +0,0 @@ -plugins_dir; - $aPluginsDir[] = $cfg->getModulesDir()."/toxid_curl/smarty/plugins/"; - - $oSmarty->plugins_dir = $aPluginsDir; - } -} diff --git a/core/toxid_curl_oxviewconfig.php b/core/toxid_curl_oxviewconfig.php deleted file mode 100644 index 2773eee..0000000 --- a/core/toxid_curl_oxviewconfig.php +++ /dev/null @@ -1,55 +0,0 @@ -_injectTplVariable(); - return parent::__construct(); - } - - /** - * if config variable sTplVariable is set, - * sets template variable with getToxid() result - * @return void - */ - protected function _injectTplVariable() - { - $oConfig = oxRegistry::getConfig(); - $sTplVariableName = $oConfig->getConfigParam('sTplVariable'); - if ($sTplVariableName) { - $oConfig->getActiveView()->addTplParam($sTplVariableName, $this->getToxid()); - } - } - - /** - * returns instance of toxidCurl - * @return toxidCurl - */ - public function getToxid() - { - $toxidCurl = oxRegistry::get('toxidcurl'); - if (!$toxidCurl->getInitialized()) { - $smartyParser = oxNew('toxid_curl_smarty_parser'); - $toxidCurl->init( - $smartyParser - ); - } - return $toxidCurl; - } -} diff --git a/core/toxidcurl.php b/core/toxidcurl.php index 15f2a42..1b20dfb 100644 --- a/core/toxidcurl.php +++ b/core/toxidcurl.php @@ -1,172 +1,113 @@ smartyParser = $smartyParser; $this->_initialized = true; } - public function getInitialized() + public function getInitialized(): bool { return $this->_initialized; } /** - * returns the called snippet - * - * @param string $snippet - * @param bool $blMultiLang - * @param string $customPage - * @param int $iCacheTtl - * @param bool $blGlobalSnippet - * - * @return string + * Returns the called CMS snippet */ - public function getCmsSnippet($snippet = null, $blMultiLang = false, $customPage = null, $iCacheTtl = null, $blGlobalSnippet = false) + public function getCmsSnippet($snippet = null, $blMultiLang = false, $customPage = null, $iCacheTtl = null, $blGlobalSnippet = false): string { if (!$this->cmsAvailable) { return ''; } - if ($snippet == null) { + if ($snippet === null) { return 'TOXID: Please add part, you want to display!'; } - $oConf = $this->getConfig(); - $sShopId = $oConf->getActiveShop()->getId(); - $sLangId = oxRegistry::getLang()->getBaseLanguage(); - $oUtils = oxRegistry::getUtils(); - $oUtilsServer = oxRegistry::get('oxUtilsServer'); + $oConf = $this->getConfig(); + $sShopId = $oConf->getActiveShop()->getId(); + $sLangId = Registry::getLang()->getBaseLanguage(); + $oUtils = Registry::getUtils(); + $oUtilsServer = Registry::get(\OxidEsales\Eshop\Core\UtilsServer::class); - $sCacheIdent = $this->getCacheIdent($snippet,$sShopId,$sLangId,$blGlobalSnippet); + $sCacheIdent = $this->getCacheIdent($snippet, $sShopId, $sLangId, $blGlobalSnippet); // check if snippet text has a ttl and is in cache - $iCacheTtl = $this->getCacheLifetime($iCacheTtl); + $iCacheTtl = $this->getCacheLifetime($iCacheTtl); if ($iCacheTtl !== null && $this->_oSxToxid === null && ($sCacheContent = $oUtils->fromFileCache($sCacheIdent)) && $oUtilsServer->getServerVar('HTTP_CACHE_CONTROL') !== 'no-cache' @@ -174,7 +115,7 @@ public function getCmsSnippet($snippet = null, $blMultiLang = false, $customPage return $sCacheContent; } - if ($customPage != '') { + if ($customPage !== null && $customPage !== '') { $this->_sCustomPage = $customPage; } @@ -182,35 +123,22 @@ public function getCmsSnippet($snippet = null, $blMultiLang = false, $customPage $sText = $this->_rewriteUrls($sText, null, $blMultiLang); $sPageTitle = $this->_rewriteUrls($this->_getSnippetFromXml('//metadata//title', null, $blMultiLang)); - $sPageDescription = $this->_rewriteUrls($this->_getSnippetFromXml('//metadata//description', null, $blMultiLang)); - $sPageKeywords = $this->_rewriteUrls($this->_getSnippetFromXml('//metadata//keywords', null, $blMultiLang)); - $oConf = $this->getConfig(); - $sShopId = $oConf->getActiveShop()->getId(); - $sLangId = oxRegistry::getLang()->getBaseLanguage(); - $sText = $this->smartyParser->parse($sText); - + $sText = $this->smartyParser->parse($sText); $this->_sPageTitle = $this->smartyParser->parse($sPageTitle); - $this->_sPageDescription = $this->smartyParser->parse($sPageDescription); - $this->_sPageKeywords = $this->smartyParser->parse($sPageKeywords); - /* if actual site is ssl-site, replace all image-sources with ssl-urls */ + // SSL URL replacement for images if ($oConf->isSsl()) { - $aSslUrl = $oConf->getShopConfVar('aToxidCurlSourceSsl', $sShopId); - $sSslUrl = $aSslUrl[$sLangId]; - $oldSrc = $this->_getToxidLangSource($sLangId); - - $sText = $this->replaceNonSslUrls($sText, $sSslUrl, $oldSrc); - } - - if ($oConf->getConfigParam('iUtfMode') === 0) { - $sText = htmlentities($sText, ENT_NOQUOTES, "UTF-8"); - $sText = html_entity_decode($sText); + if (is_array($aSslUrl) && isset($aSslUrl[$sLangId])) { + $sSslUrl = $aSslUrl[$sLangId]; + $oldSrc = $this->_getToxidLangSource($sLangId); + $sText = $this->replaceNonSslUrls($sText, $sSslUrl, $oldSrc); + } } // save in cache if ttl is set @@ -222,74 +150,49 @@ public function getCmsSnippet($snippet = null, $blMultiLang = false, $customPage } /** - * @param null $iLangId - * - * @return string with toxidStartUrl + * Returns the TOXID start URL */ - public function getToxidStartUrl($iLangId = null) + public function getToxidStartUrl($iLangId = null): string { return preg_replace('#index.php\??$#', '', $this->getConfig()->getShopHomeURL()) . $this->_getToxidLangSeoSnippet($iLangId); } /** - * runs search by given keywords in typo3, and returns results as html - * - * @param $sKeywords - * - * @return string + * Runs search by given keywords in CMS, returns results as HTML */ - public function getSearchResult($sKeywords) + public function getSearchResult($sKeywords): string { if (isset($this->_aSearchCache[$sKeywords])) { return $this->_aSearchCache[$sKeywords]; } $this->_aSearchCache[$sKeywords] = ''; - $sSearchStartUrl = $this->_getToxidSearchUrl(); + $sSearchStartUrl = $this->_getToxidSearchUrl(); + + if (!$sSearchStartUrl) { + return ''; + } $aSearchResults = $this->_getRemoteContent($sSearchStartUrl . $sKeywords); - if ($aSearchResults['info']['http_code'] == 200) { - $sSearchResult = $aSearchResults['content']; - $sSearchResult = $this->_rewriteUrls($sSearchResult); + if (isset($aSearchResults['info']['http_code']) && $aSearchResults['info']['http_code'] == 200) { + $sSearchResult = $aSearchResults['content']; + $sSearchResult = $this->_rewriteUrls($sSearchResult); $this->_aSearchCache[$sKeywords] = $sSearchResult; } - if ($this->getConfig()->getConfigParam('iUtfMode') !== 1) { - return utf8_decode($this->_aSearchCache[$sKeywords]); - } else { - return $this->_aSearchCache[$sKeywords]; - } + return $this->_aSearchCache[$sKeywords]; } /** - * @param string $key - * @param string $value + * Add additional URL parameter to CMS request */ - public function setAdditionalUrlParam($key, $value) + public function setAdditionalUrlParam(string $key, string $value): void { $this->additionalUrlParams[$key] = $value; } /** - * @param string $page - * - * @return string - */ - protected function postProcessPageString($page) - { - if (method_exists(get_parent_class(), 'postProcessPageString')) { - $page = parent::postProcessPageString($page); - } - - return $page; - } - - /** - * returns SimpleXMLElement object from Typo3 xml - * - * @param bool $blReset - * - * @return SimpleXMLElement + * Returns SimpleXMLElement object from CMS XML */ protected function _getXmlObject($blReset = false) { @@ -297,124 +200,89 @@ protected function _getXmlObject($blReset = false) if ( isset($this->_oSxToxid[$customPage]) && - ($this->_oSxToxid[$customPage] instanceof SimpleXMLElement) && + ($this->_oSxToxid[$customPage] instanceof \SimpleXMLElement) && !$blReset ) { return $this->_oSxToxid[$customPage]; } - $xml = $this->_getXmlFromTypo3($blReset); + $xml = $this->_getXmlFromCms($blReset); if (!$this->isXml($xml)) { - return new SimpleXMLElement("\n"); + return new \SimpleXMLElement("\n"); } - $this->_oSxToxid[$customPage] = new SimpleXMLElement($xml); + $this->_oSxToxid[$customPage] = new \SimpleXMLElement($xml); return $this->_oSxToxid[$customPage]; - } /** - * Determines if we got XML from Typo3 or not. - * - * @param string $response - * - * @return bool + * Determines if we got XML from CMS or not */ - protected function isXml($response) + protected function isXml($response): bool { - return (0 === strpos($response, '_getXmlObject(); - $aXpathSnippets = $oTypo3Xml->xpath('//' . $sSnippet . '[1]'); - $sText = $aXpathSnippets[0]; + $oXml = $this->_getXmlObject(); + $aXpathSnippets = $oXml->xpath('//' . $sSnippet . '[1]'); - return (string) $sText; + if (!is_array($aXpathSnippets) || empty($aXpathSnippets)) { + return ''; + } + return (string) $aXpathSnippets[0]; } /** - * returns raw string from typo3 CMS-page - * - * @param bool $blReset set to true if you want to fetch content again - * - * @return string + * Returns raw string from CMS page */ - protected function _getXmlFromTypo3($blReset = false) + protected function _getXmlFromCms($blReset = false): string { if ($this->_sPageContent !== null && !$blReset) { return $this->_sPageContent; } $sUrl = $this->buildBaseUrl(); + $aPage = $this->getRemoteContentAndHandleStatusCodes($sUrl); - $aPage = $this->getRemoteContentAndHandleStatusCodes($sUrl); - - // Especially for Wordpress-Frickel-Heinze // Kill everything before the _sPageContent = preg_replace('/.*<\?xml/ms', '_sPageContent = preg_replace('/.*<\?xml/ms', '_sPageContent = preg_replace($regex, '$1', $this->_sPageContent); return $this->_sPageContent; } /** - * returns array with result of http get. array structure: - * array ( - * [content] => '', - * [info] => array ( - * [http_code] => 200, - * ... - * ) - * ) - * - * @param $sUrl - * - * @return array + * Fetches remote content via cURL */ - protected function _getRemoteContent($sUrl) + protected function _getRemoteContent($sUrl): array { - $aResult = []; + $aResult = []; $curl_handle = curl_init(); $sUrl = $this->buildRequestUrl($sUrl); curl_setopt($curl_handle, CURLOPT_URL, $sUrl); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1); - if (!$this->isToxidCurlPage()) { - curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true); - } + curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($curl_handle, CURLOPT_MAXREDIRS, 5); if ($this->getConfig()->getConfigParam('toxidDontVerifySSLCert')) { curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, false); } - /* Forward POST requests like a boss */ + // Forward POST requests if (!empty($_POST) && !$this->getConfig()->getConfigParam('bToxidDontPassPostVarsToCms')) { $postRequest = http_build_query($_POST, '', '&'); curl_setopt($curl_handle, CURLOPT_POST, 1); @@ -422,34 +290,35 @@ protected function _getRemoteContent($sUrl) } $aResult['content'] = curl_exec($curl_handle); - $aResult['info'] = curl_getinfo($curl_handle); + $aResult['info'] = curl_getinfo($curl_handle); curl_close($curl_handle); return $aResult; } /** - * rewrites given string URL's, which belongs to typo3 and configured in aToxidCurlSource - * - * @param string $sContent - * @param int $iLangId - * @param bool $blMultiLang - * - * @return string with changed URL's + * Rewrites CMS URLs to OXID SEO URLs */ - protected function _rewriteUrls($sContent, $iLangId = null, $blMultiLang = false) + protected function _rewriteUrls($sContent, $iLangId = null, $blMultiLang = false): string { - if ($this->getConfig()->getConfigParam('toxidDontRewriteUrls') == true) { + if (!is_string($sContent) || $sContent === '') { + return ''; + } + + if ($this->getConfig()->getConfigParam('toxidDontRewriteUrls')) { return $sContent; } if ($blMultiLang == false) { if ($iLangId === null) { - $iLangId = oxRegistry::getLang()->getBaseLanguage(); + $iLangId = Registry::getLang()->getBaseLanguage(); } - $aLanguages = array($iLangId); + $aLanguages = [$iLangId]; } else { $aLangs = $this->getConfig()->getConfigParam('aToxidCurlSource'); + if (!is_array($aLangs)) { + return $sContent; + } arsort($aLangs); $aLanguages = array_keys($aLangs); } @@ -458,62 +327,72 @@ protected function _rewriteUrls($sContent, $iLangId = null, $blMultiLang = false $sShopUrl = $this->getConfig()->getShopUrl(); if (substr($sShopUrl, -1) !== '/') { - $sShopUrl = $sShopUrl . '/'; + $sShopUrl .= '/'; } - $target = rtrim($sShopUrl . $this->_getToxidLangSeoSnippet($iLangId), '/') . '/'; - $source = $this->_getToxidLangSource($iLangId); - $pattern = '%(action|href)=[\'"]' . $source . '[^"\']*?(?:/|\.html|\.php|\.asp)?(?:\?[^"\']*)?[\'"]%'; + $target = rtrim($sShopUrl . $this->_getToxidLangSeoSnippet($iLangId), '/') . '/'; + $source = $this->_getToxidLangSource($iLangId); - preg_match_all($pattern, $sContent, $matches, PREG_SET_ORDER); - foreach ($matches as $match) { + if (!$source) { + continue; + } - // skip rewrite for defined file extensions - if ($this->_getFileExtensionValuesForNoRewrite()) { - if (preg_match('%\.(' . $this->_getFileExtensionValuesForNoRewrite() . ')[\'"]*%i', $match[0])) { - continue; - } + // Collect all source URLs to rewrite (main + SSL as alternative) + $aSources = [$source]; + $aSslUrls = $this->getConfig()->getConfigParam('aToxidCurlSourceSsl'); + if (is_array($aSslUrls) && !empty($aSslUrls[$iLangId])) { + $sSslSource = rtrim($aSslUrls[$iLangId], '/') . '/'; + if ($sSslSource !== $source) { + $aSources[] = $sSslSource; } + } - if ('src' == $match[1] && $this->getConfig()->getConfigParam('toxidRewriteUrlEncoded') == true) { - $sContent = str_replace($match[0], str_replace(urlencode($source), urlencode($target), $match[0]), $sContent); - continue; - } + foreach ($aSources as $currentSource) { + $pattern = '%(action|href|src|srcset)=[\'"]' . preg_quote($currentSource, '%') . '[^"\']*?(?:/|\.html|\.php|\.asp)?(?:\?[^"\']*)?[\'"]%'; - // skip rewrite for defined rel values - if ($this->_getRelValuesForNoRewrite()) { - if (preg_match('%rel=["\'](' . $this->_getRelValuesForNoRewrite() . ')["\']%', $match[0])) { - continue; + preg_match_all($pattern, $sContent, $matches, PREG_SET_ORDER); + foreach ($matches as $match) { + + // skip rewrite for defined file extensions + $fileExtExclude = $this->_getFileExtensionValuesForNoRewrite(); + if ($fileExtExclude) { + if (preg_match('%\.(' . $fileExtExclude . ')[\'"]*%i', $match[0])) { + continue; + } } - } - $sContent = str_replace($match[0], str_replace($source, $target, $match[0]), $sContent); - } - unset($match); + // skip rewrite for defined rel values + $relExclude = $this->_getRelValuesForNoRewrite(); + if ($relExclude) { + if (preg_match('%rel=["\'](' . $relExclude . ')["\']%', $match[0])) { + continue; + } + } + $sContent = str_replace($match[0], str_replace($currentSource, $target, $match[0]), $sContent); + } + } } return $sContent; } /** - * returns string with language specific sourceUrl - * - * @param int $iLangId - * @param bool $blReset reset object value, and get url again - * - * @return string + * Returns language-specific source URL */ - protected function _getToxidLangSource($iLangId = null, $blReset = false) + protected function _getToxidLangSource($iLangId = null, $blReset = false): string { if ($this->_aSourceUrlByLang === null || $blReset) { $this->_aSourceUrlByLang = $this->getConfig()->getConfigParam('aToxidCurlSource'); } if ($iLangId === null) { - $iLangId = oxRegistry::getLang()->getBaseLanguage(); + $iLangId = Registry::getLang()->getBaseLanguage(); } - $source = $this->_aSourceUrlByLang[$iLangId]; - if (substr($source, -1) !== '/') { + $source = is_array($this->_aSourceUrlByLang) && isset($this->_aSourceUrlByLang[$iLangId]) + ? $this->_aSourceUrlByLang[$iLangId] + : ''; + + if ($source !== '' && substr($source, -1) !== '/') { return $source . '/'; } @@ -521,38 +400,33 @@ protected function _getToxidLangSource($iLangId = null, $blReset = false) } /** - * returns string with language specific toxidUrlParam - * - * @param int $iLangId - * @param bool $blReset reset object value, and get url again - * - * @return string + * Returns language-specific URL parameters */ - protected function _getToxidLangUrlParam($iLangId = null, $blReset = false) + protected function _getToxidLangUrlParam($iLangId = null, $blReset = false): string { if ($this->_aToxidLangUrlParam === null || $blReset) { $this->_aToxidLangUrlParam = $this->getConfig()->getConfigParam('aToxidCurlUrlParams'); } if ($iLangId === null) { - $iLangId = oxRegistry::getLang()->getBaseLanguage(); + $iLangId = Registry::getLang()->getBaseLanguage(); } - return '?' . ltrim($this->_aToxidLangUrlParam[$iLangId], '?'); + $param = is_array($this->_aToxidLangUrlParam) && isset($this->_aToxidLangUrlParam[$iLangId]) + ? $this->_aToxidLangUrlParam[$iLangId] + : ''; + + return '?' . ltrim($param, '?'); } /** - * returns string with toxid specific url params - * - * @return string + * Returns all TOXID URL parameters */ - protected function _getToxidUrlParams() + protected function _getToxidUrlParams(): string { - $langParam = $this->_getToxidLangUrlParam(); - + $langParam = $this->_getToxidLangUrlParam(); $params = $langParam; - if ($this->isAdminLoggedIn()) - { + if ($this->isAdminLoggedIn()) { $params .= $this->_getToxidAdminUrlParam(); $params .= $this->_getToxidCmsUrlParams(); } @@ -561,31 +435,37 @@ protected function _getToxidUrlParams() } /** - * returns string with admin specific toxidUrlParam - * @return mixed|string - * @internal param bool $param + * Returns admin-specific URL parameters */ - protected function _getToxidAdminUrlParam() + protected function _getToxidAdminUrlParam(): string { $this->_aToxidAdminUrlParam = $this->getConfig()->getConfigParam('aToxidCurlUrlAdminParams'); - return '&' . ltrim($this->_aToxidAdminUrlParam[0], '?'); + if (!is_array($this->_aToxidAdminUrlParam) || empty($this->_aToxidAdminUrlParam)) { + return ''; + } + + return '&' . ltrim($this->_aToxidAdminUrlParam[0] ?? '', '?'); } /** - * returns string with cms specific url params - * @return string + * Returns CMS-specific URL parameters from request */ - protected function _getToxidCmsUrlParams() + protected function _getToxidCmsUrlParams(): string { - $params = explode(",", $this->getConfig()->getConfigParam('toxidAllowedCmsRequestParams')); + $allowedParams = $this->getConfig()->getConfigParam('toxidAllowedCmsRequestParams'); + if (!$allowedParams) { + return ''; + } + + $params = explode(",", $allowedParams); $cmsParams = ''; foreach ($params as $param) { + $param = trim($param); + $paramValue = Registry::getConfig()->getRequestParameter($param); - $paramValue = oxRegistry::getConfig()->getRequestParameter($param); - - if (isset($paramValue) && $paramValue !== '') { + if ($paramValue !== null && $paramValue !== '') { $cmsParams .= '&' . $param . '=' . $paramValue; } } @@ -594,144 +474,133 @@ protected function _getToxidCmsUrlParams() } /** - * returns string with language specific toxidSeoSnippet - * - * @param int $iLangId - * @param bool $blReset reset object value, and get url again - * - * @return string + * Returns language-specific SEO snippet */ - protected function _getToxidLangSeoSnippet($iLangId = null, $blReset = false) + protected function _getToxidLangSeoSnippet($iLangId = null, $blReset = false): string { if ($this->_aRewriteStartUrl === null || $blReset) { $this->_aRewriteStartUrl = $this->getConfig()->getConfigParam('aToxidCurlSeoSnippets'); } if ($iLangId === null) { - $iLangId = oxRegistry::getLang()->getBaseLanguage(); + $iLangId = Registry::getLang()->getBaseLanguage(); } - return $this->_aRewriteStartUrl[$iLangId]; + return is_array($this->_aRewriteStartUrl) && isset($this->_aRewriteStartUrl[$iLangId]) + ? $this->_aRewriteStartUrl[$iLangId] + : ''; } /** - * returns string with the currently defined custom url + * Returns the currently defined custom URL */ - protected function _getToxidCustomPage() + protected function _getToxidCustomPage(): string { return ($this->_sCustomPage !== null) ? $this->_sCustomPage : ''; } /** - * returns typo3 search URL - * - * @param int $iLangId - * @param bool $blReset reset object value, and get url again - * - * @return string + * Returns CMS search URL */ - protected function _getToxidSearchUrl($iLangId = null, $blReset = false) + protected function _getToxidSearchUrl($iLangId = null, $blReset = false): string { if ($this->_aSearchUrl === null || $blReset) { $this->_aSearchUrl = $this->getConfig()->getConfigParam('aToxidSearchUrl'); } if ($iLangId === null) { - $iLangId = oxRegistry::getLang()->getBaseLanguage(); + $iLangId = Registry::getLang()->getBaseLanguage(); } - return $this->_aSearchUrl[$iLangId]; + return is_array($this->_aSearchUrl) && isset($this->_aSearchUrl[$iLangId]) + ? $this->_aSearchUrl[$iLangId] + : ''; } /** - * returns string with rel values separated by '|' - * - * @return string + * Returns rel values for which URLs should not be rewritten */ - protected function _getRelValuesForNoRewrite() + protected function _getRelValuesForNoRewrite(): string { if ($this->_sRelValuesForNoRewrite === null) { - $this->_sRelValuesForNoRewrite = implode('|', explode(',', str_replace(' ', '', $this->getConfig()->getConfigParam('toxidDontRewriteRelUrls')))); + $val = $this->getConfig()->getConfigParam('toxidDontRewriteRelUrls'); + $this->_sRelValuesForNoRewrite = $val ? implode('|', explode(',', str_replace(' ', '', $val))) : ''; } return $this->_sRelValuesForNoRewrite; } /** - * returns string with rel values separated by '|' - * - * @return string + * Returns file extensions for which URLs should not be rewritten */ - protected function _getFileExtensionValuesForNoRewrite() + protected function _getFileExtensionValuesForNoRewrite(): string { if ($this->_sFileExtensionValuesForNoRewrite === null) { - $this->_sFileExtensionValuesForNoRewrite = implode('|', explode(',', str_replace(' ', '', $this->getConfig()->getConfigParam('toxidDontRewriteFileExtension')))); + $val = $this->getConfig()->getConfigParam('toxidDontRewriteFileExtension'); + $this->_sFileExtensionValuesForNoRewrite = $val ? implode('|', explode(',', str_replace(' ', '', $val))) : ''; } return $this->_sFileExtensionValuesForNoRewrite; } /** - * returns typo3 URL for not found page - * - * @param int $iLangId - * @param bool $blReset reset object value, and get url again - * - * @return null|string + * Returns not-found URL for the CMS */ - protected function _getToxidNotFoundUrl($iLangId = null, $blReset = false) + protected function _getToxidNotFoundUrl($iLangId = null, $blReset = false): ?string { if ($this->_aNotFoundUrl === null || $blReset) { $this->_aNotFoundUrl = $this->getConfig()->getConfigParam('aToxidNotFoundUrl'); } if ($iLangId === null) { - $iLangId = oxRegistry::getLang()->getBaseLanguage(); + $iLangId = Registry::getLang()->getBaseLanguage(); } - return array_key_exists($iLangId, (array)$this->_aNotFoundUrl) ? $this->_aNotFoundUrl[$iLangId] : null; + return is_array($this->_aNotFoundUrl) && array_key_exists($iLangId, $this->_aNotFoundUrl) + ? $this->_aNotFoundUrl[$iLangId] + : null; } /** - * Handles HTTP status codes for toxid response - * - * @param $sUrl - * @param $notFound404 - * @return array + * Handles HTTP status codes for TOXID response */ - protected function getRemoteContentAndHandleStatusCodes($sUrl, $notFound404 = false) + protected function getRemoteContentAndHandleStatusCodes(string $sUrl, bool $notFound404 = false): array { $aPage = $this->_getRemoteContent($sUrl); - switch ($aPage['info']['http_code']) { + $httpCode = $aPage['info']['http_code'] ?? 0; + + switch ($httpCode) { case 500: header("HTTP/1.1 500 Internal Server Error"); header('Location: ' . $this->getConfig()->getShopHomeURL()); - oxRegistry::getUtils()->showMessageAndExit(''); + Registry::getUtils()->showMessageAndExit(''); break; case 404: - if($this->_getToxidNotFoundUrl() && !$notFound404) { + if ($this->_getToxidNotFoundUrl() && !$notFound404) { header("HTTP/1.0 404 Not Found"); $aPage = $this->getRemoteContentAndHandleStatusCodes($this->_getToxidNotFoundUrl(), true); break; } - $this->handleError(404, $aPage['info']['url']); + $this->handleError(404, $aPage['info']['url'] ?? ''); break; case 301: if ($this->getConfig()->getConfigParam('bToxidRedirect301ToStartpage')) { header("HTTP/1.1 301 Moved Permanently"); header('Location: ' . $this->getToxidStartUrl()); - oxRegistry::getUtils()->showMessageAndExit(''); + Registry::getUtils()->showMessageAndExit(''); } else { - $redirectUrl = $this->prepareRedirectUrl($aPage['info']['redirect_url']); - oxRegistry::getUtils()->redirect($redirectUrl, false, 301); + $redirectUrl = $this->prepareRedirectUrl($aPage['info']['redirect_url'] ?? ''); + Registry::getUtils()->redirect($redirectUrl, false, 301); } break; case 302: case 303: case 307: - $redirectUrl = $aPage['info']['redirect_url']; - $aPage = $this->getRemoteContentAndHandleStatusCodes($redirectUrl); + $redirectUrl = $aPage['info']['redirect_url'] ?? ''; + if ($redirectUrl) { + $aPage = $this->getRemoteContentAndHandleStatusCodes($redirectUrl); + } break; case 0: header('Location: ' . $this->getConfig()->getShopHomeURL()); - oxRegistry::getUtils()->showMessageAndExit(''); + Registry::getUtils()->showMessageAndExit(''); break; } @@ -739,66 +608,54 @@ protected function getRemoteContentAndHandleStatusCodes($sUrl, $notFound404 = fa } /** - * Prepares Url for redirect in shop - * - * @param $sUrl - * - * @return string + * Prepares URL for redirect in shop */ - private function prepareRedirectUrl($sUrl) + private function prepareRedirectUrl(string $sUrl): string { - $aLangSource = $this->getConfig()->getConfigParam('aToxidCurlSource'); - $iLangId = $this->getBaseLanguage(); - $source = $aLangSource[$iLangId]; - $target = $this->_getToxidLangSeoSnippet($iLangId); - // replace domain - $sUrl = str_replace($source, $target, $sUrl); + $iLangId = $this->getBaseLanguage(); + $sShopUrl = $this->getConfig()->getShopUrl(); + if (substr($sShopUrl, -1) !== '/') { + $sShopUrl .= '/'; + } + $target = rtrim($sShopUrl . $this->_getToxidLangSeoSnippet($iLangId), '/') . '/'; - return $sUrl; - } + // Try main source URL + $source = $this->_getToxidLangSource($iLangId); + if ($source && strpos($sUrl, $source) !== false) { + return str_replace($source, $target, $sUrl); + } - /** - * Check if current page is a toxid page or if toxid is used for snippets (i.e. navigation) on the current page - * - * @return bool - */ - private function isToxidCurlPage() - { - return 'toxid_curl' == $this->getConfig()->getActiveView()->getClassName(); + // Try SSL/alternative source URL + $aSslUrls = $this->getConfig()->getConfigParam('aToxidCurlSourceSsl'); + if (is_array($aSslUrls) && !empty($aSslUrls[$iLangId])) { + $sSslSource = rtrim($aSslUrls[$iLangId], '/') . '/'; + if (strpos($sUrl, $sSslSource) !== false) { + return str_replace($sSslSource, $target, $sUrl); + } + } + + return $sUrl; } /** * Getter for base language - * - * @return integer */ - private function getBaseLanguage() + private function getBaseLanguage(): int { if ($this->iLangId === null) { - $this->iLangId = oxRegistry::getLang()->getBaseLanguage(); + $this->iLangId = Registry::getLang()->getBaseLanguage(); } return $this->iLangId; } /** - * Replaces Links to SSL-Links if configured. - * - * @param string $sText - * @param string $sSslUrl - * @param string $oldSrc - * - * @return string + * Replaces non-SSL URLs with SSL URLs for images */ - private function replaceNonSslUrls($sText, $sSslUrl, $oldSrc) + private function replaceNonSslUrls(string $sText, string $sSslUrl, string $oldSrc): string { - if (!empty($sSslUrl)) { - - $newSrc = $sSslUrl; - - if ($oldSrc != "" && $newSrc != "") { - $sText = str_replace('src="' . $oldSrc, 'src="' . $newSrc, $sText); - } + if (!empty($sSslUrl) && $oldSrc !== '' && $sSslUrl !== '') { + $sText = str_replace('src="' . $oldSrc, 'src="' . $sSslUrl, $sText); } return $sText; @@ -806,49 +663,43 @@ private function replaceNonSslUrls($sText, $sSslUrl, $oldSrc) /** * Getter for oxConfig - * - * @return oxConfig */ private function getConfig() { - return oxRegistry::getConfig(); + return Registry::getConfig(); } /** - * Handle toxid request errors - * - * @param integer $statusCode - * @param string $sUrl + * Handle TOXID request errors */ - protected function handleError($statusCode, $sUrl = '') + protected function handleError(int $statusCode, string $sUrl = ''): void { $this->cmsAvailable = false; switch ($statusCode) { case 404: $sRedirectLinkError404 = $this->getConfig()->getConfigParam('toxidError404Link'); - if ('' !== trim($sRedirectLinkError404)) { - oxRegistry::getUtils()->redirect($sRedirectLinkError404); + if ($sRedirectLinkError404 && trim($sRedirectLinkError404) !== '') { + Registry::getUtils()->redirect($sRedirectLinkError404); } - oxRegistry::getUtils()->handlePageNotFoundError($sUrl); + Registry::getUtils()->handlePageNotFoundError($sUrl); break; } - } private function getCacheLifetime($iCacheTtl) { if (null === $iCacheTtl) { $defaultCacheTtl = $this->getConfig()->getConfigParam('toxidCacheTtl'); - if ('' !== trim($defaultCacheTtl)) { - $iCacheTtl = $defaultCacheTtl; + if ($defaultCacheTtl !== null && trim($defaultCacheTtl) !== '') { + $iCacheTtl = (int) $defaultCacheTtl; } } return $iCacheTtl; } - private function getCacheIdent($snippet, $sShopId, $sLangId, $blGlobalSnippet) + private function getCacheIdent(string $snippet, string $sShopId, $sLangId, bool $blGlobalSnippet): string { $identString = $snippet . $this->buildRequestUrl($this->buildBaseUrl()); @@ -862,24 +713,22 @@ private function getCacheIdent($snippet, $sShopId, $sLangId, $blGlobalSnippet) } /** - * @return bool + * Check if admin user is logged in */ - private function isAdminLoggedIn() + private function isAdminLoggedIn(): bool { - $user = oxRegistry::getConfig()->getUser(); + $user = Registry::getConfig()->getUser(); - return ($user && $user->oxuser__oxrights->value != 'user'); + return ($user && isset($user->oxuser__oxrights) && $user->oxuser__oxrights->value !== 'user'); } /** - * @param $baseUrl - * - * @return string + * Builds the full request URL with additional parameters */ - protected function buildRequestUrl($baseUrl) + protected function buildRequestUrl(string $baseUrl): string { $params = http_build_query($this->additionalUrlParams); - if (false === strpos($baseUrl, '?')) { + if (strpos($baseUrl, '?') === false) { $baseUrl .= "?{$params}"; } else { $baseUrl = rtrim($baseUrl, '&') . "&{$params}"; @@ -891,18 +740,15 @@ protected function buildRequestUrl($baseUrl) } /** - * @return string + * Builds the base CMS URL */ - protected function buildBaseUrl() + protected function buildBaseUrl(): string { $source = $this->_getToxidLangSource(); - $page = $this->getConfig()->getConfigParam('sToxidCurlPage'); - $page = $this->postProcessPageString($page); + $page = $this->getConfig()->getConfigParam('sToxidCurlPage') ?? ''; $custom = $this->_getToxidCustomPage(); $params = $this->_getToxidUrlParams(); - $sUrl = $source . $custom . $page . $params; - - return $sUrl; + return $source . $custom . $page . $params; } } diff --git a/metadata.php b/metadata.php index afbb78f..4ce2325 100644 --- a/metadata.php +++ b/metadata.php @@ -1,71 +1,48 @@ - * @license MIT License http://www.opensource.org/licenses/mit-license.html - * @version 2.0 - * @link http://toxid.org - * @link https://github.com/jkrug/TOXID-cURL + * @license MIT License http://www.opensource.org/licenses/mit-license.html + * @link https://github.com/jkrug/TOXID-cURL */ -/** - * Metadata version - */ -$sMetadataVersion = '1.1'; +$sMetadataVersion = '2.1'; -$aModule = array( +$aModule = [ 'id' => 'toxid_curl', - 'title' => 'marmalade :: TOXID cURL', - 'description' => array( - 'de' => 'Integriert CMS-Inhalte in OXID eShop', - 'en' => 'Renders pages form CMS and navigation in OXID.', - ), - 'email' => 'support@marmalade.de', - 'url' => 'http://www.marmalade.de', - 'thumbnail' => 'toxid.jpg', - 'version' => '2.3.3', - 'author' => 'marmalade GmbH :: Joscha Krug', - 'extend' => array( - 'oxseodecoder' => 'toxid_curl/core/toxid_curl_oxseodecoder', - 'oxviewconfig' => 'toxid_curl/core/toxid_curl_oxviewconfig', - 'oxutilsview' => 'toxid_curl/core/toxid_curl_oxutilsview' - ), - 'templates' => array( - 'toxid_curl.tpl' => 'toxid_curl/views/azure/toxid_curl.tpl', - 'product.tpl' => 'toxid_curl/views/azure/product.tpl', - 'toxid_setup_main.tpl' => 'toxid_curl/views/admin/tpl/toxid_setup_main.tpl', - 'toxid_content_widget.tpl' => 'toxid_curl/views/widgets/toxid_content_widget.tpl', - ), - 'blocks' => array( - array( - 'template' => '_formparams.tpl', - 'block'=>'admin_formparams', - 'file'=>'/views/admin/blocks/_formparams_admin_formparams.tpl' - ), - ), - 'files' => array( - 'toxid_curl' => 'toxid_curl/controller/toxid_curl.php', - 'toxidcurl' => 'toxid_curl/core/toxidcurl.php', - 'toxid_setup' => 'toxid_curl/controller/admin/toxid_setup.php', - 'toxid_setup_main' => 'toxid_curl/controller/admin/toxid_setup_main.php', - 'toxid_setup_list' => 'toxid_curl/controller/admin/toxid_setup_list.php', - 'toxid_curl_events' => 'toxid_curl/core/toxid_curl_events.php', - 'toxid_curl_smarty_parser' => 'toxid_curl/core/facades/toxid_curl_smarty_parser.php', - 'toxid_curl_content_widget' => 'toxid_curl/widgets/toxid_curl_content_widget.php', - ), - 'settings' => array( - array( - 'group' => 'toxid_config_not_here', - 'name' => 'noConfigHere', - ), - ), - 'events' => array( - 'onActivate' => 'toxid_curl_events::onActivate', - 'onDeactivate' => 'toxid_curl_events::onDeactivate' - ) -); + 'title' => 'TOXID cURL', + 'description' => [ + 'de' => 'Integriert CMS-Inhalte (WordPress, TYPO3 etc.) per cURL/XML in OXID eShop.', + 'en' => 'Renders CMS pages and navigation in OXID eShop via cURL/XML.', + ], + 'thumbnail' => 'toxid.jpg', + 'version' => '3.0.0', + 'author' => 'marmalade GmbH / Community', + 'url' => 'https://github.com/jkrug/TOXID-cURL', + 'email' => 'support@marmalade.de', + + 'extend' => [ + \OxidEsales\Eshop\Core\ViewConfig::class => \Toxid\Core\ViewConfig::class, + \OxidEsales\Eshop\Core\SeoDecoder::class => \Toxid\Core\SeoDecoder::class, + \OxidEsales\Eshop\Core\UtilsView::class => \Toxid\Core\UtilsView::class, + ], + + 'controllers' => [ + 'toxid' => \Toxid\Application\Controller\ToxidController::class, + 'toxid_setup' => \Toxid\Application\Controller\Admin\ToxidSetup::class, + 'toxid_setup_main' => \Toxid\Application\Controller\Admin\ToxidSetupMain::class, + 'toxid_setup_list' => \Toxid\Application\Controller\Admin\ToxidSetupList::class, + ], + + 'templates' => [ + 'page/toxid/toxid.tpl' => 'toxid_curl/Application/views/tpl/page/toxid/toxid.tpl', + 'admin/toxid_setup_main.tpl' => 'toxid_curl/Application/views/admin/tpl/toxid_setup_main.tpl', + ], + + 'smartyPluginDirectories' => [ + 'smarty/plugins', + ], +]; diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index 215dc50..0000000 --- a/phpunit.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - integration - - - - - - tests/ - - - - - - controller/ - core/ - - - diff --git a/smarty/plugins/function.toxid_load.php b/smarty/plugins/function.toxid_load.php index 914247b..66320fd 100644 --- a/smarty/plugins/function.toxid_load.php +++ b/smarty/plugins/function.toxid_load.php @@ -1,66 +1,52 @@ -getOne( - 'SELECT OXID FROM oxarticles WHERE OXARTNUM = ?', - array($sIdent) - ); - break; - } - } - - if ($sOxid) { - $oObject->load($sOxid); - } - else { - return; - } - - $smarty->assign($params['assign'], $oObject); - - -} +getOne( + 'SELECT OXID FROM oxarticles WHERE OXARTNUM = ?', + [$sIdent] + ); + break; + } + } + + if ($sOxid) { + $oObject->load($sOxid); + } else { + return; + } + + $smarty->assign($params['assign'], $oObject); +} diff --git a/tests/core/toxidcurlTest.php b/tests/core/toxidcurlTest.php deleted file mode 100644 index d5bc0a5..0000000 --- a/tests/core/toxidcurlTest.php +++ /dev/null @@ -1,21 +0,0 @@ -markTestIncomplete("@TODO: Implement Test."); - } - - public function test_getXmlObject() - { - $fakeCurl = $this->getMock('toxidCurl'); - $fakeCurl - ->expects($this->any()) - ->method('_getXmlObject') - ->will($this->returnValue('
    MAIN
    ')); - - - $this->assertEquals('MAIN', $fakeCurl->test_getXmlObject('main')); - } -} diff --git a/tests/data/de/index.html b/tests/data/de/index.html deleted file mode 100644 index cd5b1ca..0000000 --- a/tests/data/de/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - Sidebar -

    Content aus TOXID in der Sidebar

    - - ]]>
    - Hauptcontent

    Content aus TOXID im Content-Bereich.

    ]]>
    -
    diff --git a/tests/data/de/subpage.html b/tests/data/de/subpage.html deleted file mode 100644 index aea285c..0000000 --- a/tests/data/de/subpage.html +++ /dev/null @@ -1,16 +0,0 @@ - - - Sidebar -

    Content aus TOXID in der Sidebar

    - - ]]>
    - Hauptcontent

    Content für eine Unterseite.

    ]]>
    -
    diff --git a/tests/data/en/index.html b/tests/data/en/index.html deleted file mode 100644 index 4e6acc7..0000000 --- a/tests/data/en/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - Sidebar -

    Content from TOXID for the sidebar.

    - - ]]>
    - Main content

    Content from TOXID in the main content section.

    ]]>
    -
    diff --git a/tests/data/en/subpage.html b/tests/data/en/subpage.html deleted file mode 100644 index 44eabd2..0000000 --- a/tests/data/en/subpage.html +++ /dev/null @@ -1,16 +0,0 @@ - - - Sidebar -

    Content from TOXID for the sidebar.

    - - ]]>
    - Hauptcontent

    Content für eine Unterseite.

    ]]>
    -
    diff --git a/views/admin/blocks/_formparams_admin_formparams.tpl b/views/admin/blocks/_formparams_admin_formparams.tpl deleted file mode 100644 index 72e62b2..0000000 --- a/views/admin/blocks/_formparams_admin_formparams.tpl +++ /dev/null @@ -1,5 +0,0 @@ -[{if $cl == "shop_list" && $oViewConf->getActiveClassName() == "toxid_setup_list"}] - [{assign var="cl" value=$oViewConf->getActiveClassName()}] -[{/if}] - -[{$smarty.block.parent}] diff --git a/views/admin/de/module_options.php b/views/admin/de/module_options.php deleted file mode 100644 index a995344..0000000 --- a/views/admin/de/module_options.php +++ /dev/null @@ -1,16 +0,0 @@ - - * Author URI: http://oxid-kochbuch.de - */ - -$sLangName = "Deutsch"; -$aLang = array( - 'charset' => 'utf-8', - 'SHOP_MODULE_GROUP_toxid_config_not_here' => 'Konfiguration unter Erweiterungen > TOXID Einstellungen', - 'SHOP_MODULE_noConfigHere' => 'Die Konfiguration ist nicht hier zu finden!', -); \ No newline at end of file diff --git a/views/admin/de/toxid_admin_lang.php b/views/admin/de/toxid_admin_lang.php deleted file mode 100644 index 24f9e48..0000000 --- a/views/admin/de/toxid_admin_lang.php +++ /dev/null @@ -1,43 +0,0 @@ - 'UTF-8', - 'toxid_setup' => 'TOXID Einstellungen', - 'toxid_setup_main' => 'TOXID Grundeinstellungen', - 'TOXID_SUPPORT_HEADLINE' => 'TOXID unterstützen', - 'TOXID_SUPPORT_DESC' => 'TOXID cURL ist ein OpenSource Projekt, ursprünglich entwickelt von Joscha Krug. - Die Entwicklung wird von seiner Agentur, der marmalade GmbH, fortgesetzt. - Wir freuen uns über Unterstützung, am liebsten in Form von Code, - aber natürlich trägt auch ein finanzielle Unterstützung zur Wartung, - Pflege und Entwicklung neuer Features bei.', - 'TOXID_SOURCE' => 'CMS URL', - 'TOXID_SOURCE_SSL' => 'CMS SSL-URL', - 'TOXID_SEO_SNIPPET' => 'URL Identifier / SEO-Snippet', - 'TOXID_SEARCH_URL' => 'URL zum Aufruf der Suche (optional)', - 'TOXID_NOT_FOUND_URL' => '404 Not found URL (optional)', - 'TOXID_PARAM' => 'TOXID URL-Parameter', - 'TOXID_PREVIEW_PARAM' => 'Admin URL-Parameter (z.B. Blog Preview)', - 'TOXID_CMS_PARAMS' => 'Erlaubte, CMS spezifische Parameter (kommaseparierte Liste)', - 'TOXID_DONT_REWRITE' => 'URLs nicht umschreiben - Aufrufe führen auf externe CMS-Seite', - 'TOXID_DONT_PASSTHROUGH' => 'POST-Parameter nicht an CMS durchreichen', - 'TOXID_DONT_REWRITE_REL_URLS' => 'URLs für bestimmte "rel" Attributwerte nicht umschreiben (kommaseparierte Liste)', - 'TOXID_DONT_REWRITE_URLS_WITH_FILE_EXTENSIONS' => 'URLs für bestimmte Dateiendungen nicht umschreiben (kommaseparierte Liste)', - 'TOXID_ERROR_404_LINK' => 'User will be redirected to this URL on 404 error, when no other 404 url is specified for specific language (optional)', - 'TOXID_REWRITE_URLENCODED' => 'URLs die "url encoded" sind umschreiben (URL muss sich im "src" attribut befindet)', - 'TOXID_REDIRECT_301_TO_STARTPAGE' => 'Auf Startseite weiterleiten wenn das CMS den HTTP-Statuscode 301 liefert', - 'TOXID_GENERAL' => 'Allgemein', - 'TOXID_BECOME_PARTNER' => 'Partner werden', - 'TOXID_INTEGRATIONPARTNER' => 'Integrationspartner', - 'TOXID_CACHE' => 'Cache', - 'TOXID_CACHE_TTL' => 'Cache-Lebenszeit (TTL) in Sekunden', - 'HELP_TOXID_CACHE_TTL' => '0 => unendlich
    kein Wert => default Cache deaktiviert', - 'TOXID_DONT_VERIFY_SSL_CERTIFICATE' => 'SSL-Zertifikat nicht überprüfen', -]; - -if (oxRegistry::getConfig()->getConfigParam('iUtfMode') === 0) { - foreach ($aLang as $k => $v) { - $aLang[$k] = utf8_decode($v); - } -} diff --git a/views/admin/en/module_options.php b/views/admin/en/module_options.php deleted file mode 100644 index 0c20888..0000000 --- a/views/admin/en/module_options.php +++ /dev/null @@ -1,16 +0,0 @@ - - * Author URI: http://oxid-kochbuch.de - */ - -$sLangName = "Deutsch"; -$aLang = array( - 'charset' => 'utf-8', - 'SHOP_MODULE_GROUP_toxid_config_not_here' => 'Configuration in Extensions > TOXID Configuration', - 'SHOP_MODULE_noConfigHere' => 'You won\'t find the configuration here!', -); \ No newline at end of file diff --git a/views/admin/en/toxid_admin_lang.php b/views/admin/en/toxid_admin_lang.php deleted file mode 100644 index 56078fd..0000000 --- a/views/admin/en/toxid_admin_lang.php +++ /dev/null @@ -1,43 +0,0 @@ - 'UTF-8', - 'toxid_setup' => 'TOXID Configuration', - 'toxid_setup_main' => 'TOXID Basic settings', - 'TOXID_SUPPORT_HEADLINE' => 'Support the TOXID project', - 'TOXID_SUPPORT_DESC' => 'TOXID cURL ist ein OpenSource Projekt, ursprünglich entwickelt von Joscha Krug. - Die Entwicklung wird von seiner Agentur, der marmalade GmbH, fortgesetzt. - Wir freuen uns über Unterstützung, am liebsten in Form von Code, - aber natürlich trägt auch ein finanzielle Unterstützung zur Wartung, - Pflege und Entwicklung neuer Features bei.', - 'TOXID_SOURCE' => 'CMS URL', - 'TOXID_SOURCE_SSL' => 'CMS SSL-URL', - 'TOXID_SEO_SNIPPET' => 'URL Identifier / SEO-Snippet', - 'TOXID_SEARCH_URL' => 'URL to call the searchpage (optional)', - 'TOXID_NOT_FOUND_URL' => 'Not found URL (optional)', - 'TOXID_PARAM' => 'TOXID URL parameter', - 'TOXID_PREVIEW_PARAM' => 'Admin URL-Parameter (i.e. Blog Preview)', - 'TOXID_CMS_PARAMS' => 'Allowed, CMS specific parameters (comma-separated list)', - 'TOXID_DONT_REWRITE' => 'Don\'t rewrite the URLs - Users will linked to the external site.', - 'TOXID_DONT_PASSTHROUGH' => 'Don\'t pass POST parameters to CMS', - 'TOXID_DONT_REWRITE_REL_URLS' => 'Don\'t rewrite the URLs for particular "rel" attribute values (comma-separated list)', - 'TOXID_DONT_REWRITE_URLS_WITH_FILE_EXTENSIONS' => 'Don\'t rewrite the URLs for particular file extensions (comma-separated list)', - 'TOXID_ERROR_404_LINK' => 'User will be redirected to this URL on 404 error, when no other 404 url is specified for specific language (optional)', - 'TOXID_REWRITE_URLENCODED' => 'Rewrite URLs that are "url encoded" (URL must be contained in the "src" attribute)', - 'TOXID_REDIRECT_301_TO_STARTPAGE' => 'Redirect to home page if the CMS returns the HTTP status code 301', - 'TOXID_GENERAL' => 'General', - 'TOXID_BECOME_PARTNER' => 'Become a partner', - 'TOXID_INTEGRATIONPARTNER' => 'Integration partners', - 'TOXID_CACHE' => 'Cache', - 'TOXID_CACHE_TTL' => 'Cache lifetime (TTL) in seconds', - 'HELP_TOXID_CACHE_TTL' => '0 => forever
    no value => default cache deactivated', - 'TOXID_DONT_VERIFY_SSL_CERTIFICATE' => 'Don\'t verify SSL certificate (e.g. if it is self-signed).', -]; - -if (oxRegistry::getConfig()->getConfigParam('iUtfMode') === 0) { - foreach ($aLang as $k => $v) { - $aLang[$k] = utf8_decode($v); - } -} diff --git a/views/admin/tpl/toxid_setup_main.tpl b/views/admin/tpl/toxid_setup_main.tpl deleted file mode 100644 index d71dd27..0000000 --- a/views/admin/tpl/toxid_setup_main.tpl +++ /dev/null @@ -1,249 +0,0 @@ -[{include file="headitem.tpl" title="GENERAL_ADMIN_TITLE"|oxmultilangassign}] - - -[{ if $readonly }] -[{assign var="readonly" value="readonly disabled"}] -[{else}] -[{assign var="readonly" value=""}] -[{/if}] -
    - [{ $oViewConf->getHiddenSid() }] - - - - - - -
    -
    - [{ $oViewConf->getHiddenSid() }] - - - -
    -
    - [{oxmultilang ident='TOXID_SUPPORT_HEADLINE'}] -
    -
    - - - - - - - -
    - - - - [{oxmultilang ident='TOXID_SUPPORT_DESC'}] - - [{oxmultilang ident='TOXID_INTEGRATIONPARTNER'}] - - - Contributors - - -   - -
    -
    -
    -
    -
    -
    -
    - [{oxmultilang ident='toxid_setup'}] -
    -
    - [{foreach from=$languages key=lang item=olang}] -
    - [{ $olang->name }] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - [{oxmultilang ident="TOXID_SOURCE"}]: - - -
    - [{oxmultilang ident="TOXID_SOURCE_SSL"}]: - - -
    - [{oxmultilang ident="TOXID_SEARCH_URL"}]: - - -
    - [{oxmultilang ident="TOXID_PARAM"}]: - - -
    - [{oxmultilang ident="TOXID_SEO_SNIPPET"}]: - - -
    - [{oxmultilang ident="TOXID_PREVIEW_PARAM"}]: - - -
    - [{oxmultilang ident="TOXID_NOT_FOUND_URL"}]: - - -
    -
    - [{/foreach}] -
    - [{oxmultilang ident="TOXID_GENERAL"}] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    - [{ oxmultilang ident="TOXID_CMS_PARAMS" }] - - -
    - [{oxmultilang ident="TOXID_DONT_REWRITE_REL_URLS"}]: - - -
    - [{oxmultilang ident="TOXID_DONT_REWRITE_URLS_WITH_FILE_EXTENSIONS"}]: - - -
    - [{ oxmultilang ident="TOXID_ERROR_404_LINK" }]: - - -
    - - - [{oxmultilang ident="TOXID_REWRITE_URLENCODED"}] -
    - - - [{oxmultilang ident="TOXID_DONT_REWRITE"}] -
    - - - [{oxmultilang ident="TOXID_DONT_PASSTHROUGH"}] -
    - - - [{oxmultilang ident="TOXID_REDIRECT_301_TO_STARTPAGE"}] -
    - - - [{oxmultilang ident="TOXID_DONT_VERIFY_SSL_CERTIFICATE"}] -
    -
    -
    - [{oxmultilang ident="TOXID_CACHE"}] - - - - - -
    - [{oxmultilang ident="TOXID_CACHE_TTL"}]: - - [{oxinputhelp ident="HELP_TOXID_CACHE_TTL"}] -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    - -
    - -[{include file="bottomnaviitem.tpl"}] -[{include file="bottomitem.tpl"}] diff --git a/views/azure/product.tpl b/views/azure/product.tpl deleted file mode 100644 index c80339e..0000000 --- a/views/azure/product.tpl +++ /dev/null @@ -1,6 +0,0 @@ -[{ toxid_load type="oxarticle" ident=$ident oxid=$oxid assign="oProduct"}] -[{if $oProduct}] -
      -
    • [{include file="widget/product/listitem_line.tpl" product=$oProduct blDisableToCart=$blDisableToCart}]
    • -
    -[{/if}] diff --git a/views/azure/toxid_curl.tpl b/views/azure/toxid_curl.tpl deleted file mode 100644 index 084137a..0000000 --- a/views/azure/toxid_curl.tpl +++ /dev/null @@ -1,19 +0,0 @@ -[{assign var="tpl" value=$oViewConf->getActTplName()}] -[{assign var='toxid' value=$oViewConf->getToxid()}] - -[{assign var="toxidBlockContent" value=$toxid->getCmsSnippet('content')}] -[{capture append="oxidBlock_content"}] -
    - [{$toxidBlockContent}] -
    -[{/capture}] - -[{assign var="toxidBlockSidebar" value=$toxid->getCmsSnippet('sidebar')}] -[{capture append="oxidBlock_sidebar"}] -
    - [{$toxidBlockSidebar}] -
    -[{/capture}] - -[{include file="layout/page.tpl" sidebar="Left"}] - diff --git a/views/widgets/toxid_content_widget.tpl b/views/widgets/toxid_content_widget.tpl deleted file mode 100644 index 8db0d1b..0000000 --- a/views/widgets/toxid_content_widget.tpl +++ /dev/null @@ -1 +0,0 @@ -[{$content}] \ No newline at end of file diff --git a/widgets/toxid_curl_content_widget.php b/widgets/toxid_curl_content_widget.php deleted file mode 100644 index 6fed612..0000000 --- a/widgets/toxid_curl_content_widget.php +++ /dev/null @@ -1,48 +0,0 @@ -_sThisTemplate current template file name - */ - public function render() - { - /** @var toxidCurl $toxid */ - $toxid = oxRegistry::get('toxidCurl'); - - if (!$toxid->getInitialized()) { - $toxid->init(oxNew('Toxid_Curl_Smarty_Parser')); - } - - $cmsSnippet = $toxid->getCmsSnippet('content', true, 'toxid-content-widget'); - - parent::render(); - - $this->_aViewData['content'] = $cmsSnippet; - - return $this->_sThisTemplate; - - } - -} From 6b2b4b5fb281bf8011098426ac5c930863d77500 Mon Sep 17 00:00:00 2001 From: Alex Hupe Date: Sat, 7 Feb 2026 17:38:16 +0100 Subject: [PATCH 2/2] Fix trailing slash in rewritten URLs and preserve metadata in cache - Ensure trailing slash for href/action URLs after rewriting CMS URLs to OXID SEO URLs (skip for src/srcset and file extensions) - Cache page title, description and keywords alongside snippet content so metadata is restored on cache hits instead of being lost Co-Authored-By: Claude Opus 4.6 --- core/toxidcurl.php | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/core/toxidcurl.php b/core/toxidcurl.php index 1b20dfb..72651cd 100644 --- a/core/toxidcurl.php +++ b/core/toxidcurl.php @@ -112,6 +112,13 @@ public function getCmsSnippet($snippet = null, $blMultiLang = false, $customPage && ($sCacheContent = $oUtils->fromFileCache($sCacheIdent)) && $oUtilsServer->getServerVar('HTTP_CACHE_CONTROL') !== 'no-cache' ) { + // Restore metadata from cache + if (is_array($sCacheContent)) { + $this->_sPageTitle = $sCacheContent['title'] ?? null; + $this->_sPageDescription = $sCacheContent['description'] ?? null; + $this->_sPageKeywords = $sCacheContent['keywords'] ?? null; + return $sCacheContent['content'] ?? ''; + } return $sCacheContent; } @@ -141,9 +148,14 @@ public function getCmsSnippet($snippet = null, $blMultiLang = false, $customPage } } - // save in cache if ttl is set + // save in cache if ttl is set (including metadata for title/description/keywords) if ($iCacheTtl !== null) { - $oUtils->toFileCache($sCacheIdent, $sText, $iCacheTtl); + $oUtils->toFileCache($sCacheIdent, [ + 'content' => $sText, + 'title' => $this->_sPageTitle, + 'description' => $this->_sPageDescription, + 'keywords' => $this->_sPageKeywords, + ], $iCacheTtl); } return $sText; @@ -368,7 +380,21 @@ protected function _rewriteUrls($sContent, $iLangId = null, $blMultiLang = false } } - $sContent = str_replace($match[0], str_replace($currentSource, $target, $match[0]), $sContent); + $rewritten = str_replace($currentSource, $target, $match[0]); + + // Ensure trailing slash for href/action URLs (not for src/srcset) + if ($match[1] === 'href' || $match[1] === 'action') { + if (preg_match('#[\'"]([^\'"]+)[\'"]#', $rewritten, $urlMatch)) { + $url = $urlMatch[1]; + $pathEnd = strcspn($url, '?#'); + $path = substr($url, 0, $pathEnd); + if ($path !== '' && substr($path, -1) !== '/' && !preg_match('#\.\w{2,5}$#', $path)) { + $rewritten = str_replace($url, $path . '/' . substr($url, $pathEnd), $rewritten); + } + } + } + + $sContent = str_replace($match[0], $rewritten, $sContent); } } }