承接 in2code/ipandlanguageredirect 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

in2code/ipandlanguageredirect

Composer 安装命令:

composer require in2code/ipandlanguageredirect

包简介

Redirects TYPO3 visitors automatic or with a suggestlink to another language and/or root page.

README 文档

README

TYPO3 FE visitor automatic or manual redirect to another language or another root page.

Introduction

This extension allows multi-language and multi-domain handling with redirects to best fitting pages with best fitting language based on the visitors browser language and region (IP-Address).

An AJAX-request (VanillaJS only - no JavaScript framework is needed) will handle the serverside-domain-logic to redirect or suggest a new webpage or a new language.

Define in your PHP-configuration which countries belongs to which pagetree and which browserlanguage belongs to which frontend language

In short words

Automaticly redirect or show a note for the visitor to give him the best fitting website version for his/her needs.

Screens

Example suggest message in frontend: Suggest a language

Which way is used to get the country code of the user?

This is completely your choice now. You can choose between different ip2country service classes. There is a local table with ip-ranges and countries on the one hand and on the other hand, you can also use external services to convert the visitors ip to a countryCode. While the first methods respects all privacy the second method is more current of course.

Or: You can combine different methods: Because the service of IpApi is for free for 1000 requests a month, you can use this and in addition the offline-table variant.

Available classes per default:

  • In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\IpApi - This uses the external service of ipapi.co to convert IP-addresses to a country code. Note: You can set the api key via TypoScript if you want to use more then 1000 requests a month
  • In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\LocalDatabase - This uses the local database table tx_ipandlanguageredirect_domain_model_iptocountry to convert the ip address to a country - no external service, most privacy
  • In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\IpApiCom - This uses the external service of ip-api.com to convert IP-addresses to a country code. Attention: Because https is not possible by this service all request are handled over port 80

Go to the extension manager settings and choose the classes that you want to use or simply add your own service. Example string in the extension manager settings for ipToCountryService could be In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\IpApi,In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\LocalDatabase to use the service of IpApi as long as it is free and then fall back to the local database.

What's the difference to other extensions like rmpl_language_detect?

There is a basic difference in the concept. While most of the language-redirect extensions hook into the page rendering process via USER_INT, we choose an ansynchronical way with JavaScript and PHP (AJAX). This solution needs JavaScript on the one hand but is much faster for high availability and more complex websites on the other hand. This means: You can use e.g. staticfilecache or another static solution to improve web performance. While it's not possible to use staticfilecache with a USER_INT, which is included on every single page.

Testing!

This extension allows you to test how your website will react if a visitor from a different country checks out your website. See below for a lot of testings possibilities.

Installation

  • Install this extension
  • Add a static template (page.5 will be used for the suggest container, page.1555 for the script)
  • Copy the original configuration from ipandlanguageredirect/Configuration/Redirect/Redirect.php to any other location
  • Modify the configuration for your needs
  • Set the new path in the extension manager to your configuration file
  • Have fun!

Example configuration

<?php
return [
    // Example action
    'actions' => [
        [
            // Automatic redirect to best fitting uri if visitor comes from a search engine
            'referrers' => [
                'google.',
                'bing.',
                'yahoo.',
                't-online.',
                'yandex.',
                'baidu.'
            ],
            'events' => [
                'redirect'
            ]
        ],
        [
            // For all other cases: Suggest a better fitting page
            'referrers' => [
                '*'
            ],
            'events' => [
                'suggest'
            ]
        ],
        [
            // Disable redirect for pages inside the given pid
            'pidInRootline' => [
                '129',
                '11',
            ],
            'events' => [
                'none',
            ],
        ],
        [
            // Prevent redirect for google pagespeed access
            'userAgent' => [
                'Chrome-Lighthouse'
            ],
            'events' => [
                'none'
            ]
        ],
    ],
    'globalConfiguration' => [
        // don't show suggest or redirect on a subpage
        'actionOnHomeOnly' => false,

        // always redirect to the home-page, don not try to stay on the same page while changing the language
        'stayOnCurrentPage' => false
    ],
    // configuration if nothing matches
    'noMatchingConfiguration' => [
        'identifierUsage' => 'worldwide_english',
        'matchMinQuantifier' => 15
    ],
    // main redirect configuration
    'redirectConfiguration' => [

        // Build URI to page 1 if visitors came from anywhere in the world
        1 => [

            // Build URI to language 0 if browser language is not defined here
            0 => [
                'identifier' => 'worldwide_english',
                'domain' => [
                    'www.domain.com',
                    'test.domain.org'
                ],
                'browserLanguage' => [
                    '*'
                ],
                'countryBasedOnIp' => [
                    '*'
                ]
            ],

            // Build URI to language 1 if browser language is german "de"
            1 => [
                'identifier' => 'worldwide_german',
                'domain' => [
                    'www.domain.com',
                    'test.domain.org'
                ],
                'browserLanguage' => [
                    'de'
                ],
                'countryBasedOnIp' => [
                    '*'
                ]
            ],

            // Build URI to language 2 if browser language is chinese "zh"
            2 => [
                'identifier' => 'worldwide_chinese',
                'domain' => [
                    'www.domain.com',
                    'test.domain.org'
                ],
                'browserLanguage' => [
                    'zh'
                ],
                'countryBasedOnIp' => [
                    '*'
                ]
            ],
        ],

        // Build URI to page 2 if visitors came from USA, Canada or Argentina
        2 => [

            // Build URI to language 0 if browser language is not defined here
            0 => [
                'identifier' => 'america_english',
                'domain' => [
                    'www.seconddomain.org',
                    'test.seconddomain.org'
                ],
                'browserLanguage' => [
                    '*'
                ],
                'countryBasedOnIp' => [
                    'ca',
                    'us',
                    'ar',
                ]
            ],

            // Build URI to language 1 if browser language is german "de"
            1 => [
                'identifier' => 'worldwide_german',
                'domain' => [
                    'www.seconddomain.org',
                    'test.seconddomain.org'
                ],
                'browserLanguage' => [
                    'de'
                ],
                'countryBasedOnIp' => [
                    '*'
                ]
            ],
        ],
    ],
    // Quantifiers for the matches (shouldn't be touched)
    'quantifier' => [
        'browserLanguage' => [
            'totalMatch' => 7,
            'wildCardMatch' => 3
        ],
        'countryBasedOnIp' => [
            'totalMatch' => 13,
            'wildCardMatch' => 5
        ],
        'domain' => [
            'totalMatch' => 10,
            'wildCardMatch' => 4
        ],
        'actions' => [
            'referrers' => [
                'totalMatch' => 7,
                'wildCardMatch' => 3,
            ],
            'userAgents' => [
                'totalMatch' => 7,
                'wildCardMatch' => 3,
            ],
            'pidInRootline' => 9999
        ]
    ]
];

TypoScript

If you add the static TypoScript, this lines have an effect:

plugin.tx_ipandlanguageredirect {
	view {
		templateRootPaths {
			0 = EXT:ipandlanguageredirect/Resources/Private/Templates/
			1 = {$plugin.tx_ipandlanguageredirect.view.templateRootPath}
		}
	}
	features.requireCHashArgumentForActionArguments = 0

	settings {
		# Add configuration to your IpToCountry service classes
		ipToCountry {
			In2code\Ipandlanguageredirect\Domain\Service\IpToCountry\IpApi {
				# IpApi Key: Please enter your key for ipapi.co (optional), otherwise extension will have limited access to the service (less then 1000 visitors a day). See ipapi.co for details.
				ipApiKey =
			}
		}
	}
}

page {
	includeJSFooter.ipandlanguageredirect = EXT:ipandlanguageredirect/Resources/Public/JavaScripts/Frontend.min.js
	includeCSS.ipandlanguageredirect = EXT:ipandlanguageredirect/Resources/Public/Css/Frontend.min.css

	# Suggest container that can be slided down
	5 = USER
	5 {
		userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
		extensionName = Ipandlanguageredirect
		pluginName = Pi1
		vendorName = In2code
		controller = Redirect
		action = suggest
		switchableControllerActions.Redirect.1 = suggest
	}

	# Container for informations that will be send to an AJAX service
	1555 = COA
	1555 {
		wrap = <script id="ipandlanguageredirect_container"|></script>

		# Uri to send AJAX request to
		10 = TEXT
		10 {
			noTrimWrap = | data-ipandlanguageredirect-ajaxuri="|"|
			typolink {
				parameter.data = TSFE:id
				additionalParams = &type=1555
				returnLast = url
				forceAbsoluteUrl = 1
			}
		}

		# FE language
		20 = TEXT
		20 {
			noTrimWrap = | data-ipandlanguageredirect-languageuid="|"|
			data = sitelanguage:languageId
			ifEmpty.data = GP:L
			intval = 1
		}

		# Root page uid
		30 = TEXT
		30 {
			noTrimWrap = | data-ipandlanguageredirect-rootpageuid="|"|
			data = leveluid:0
		}

		# Fake browser language for testing - e.g. &tx_ipandlanguageredirect_pi1[browserLanguage]=en
		40 = TEXT
		40 {
			noTrimWrap = | data-ipandlanguageredirect-browserlanguage="|"|
			data = GP:tx_ipandlanguageredirect_pi1|browserLanguage
			htmlSpecialChars = 1
			required = 1
		}

		# Fake ip-address for testing - e.g. &tx_ipandlanguageredirect_pi1[ipAddress]=66.85.131.18 (USA)
		50 = TEXT
		50 {
			noTrimWrap = | data-ipandlanguageredirect-ipaddress="|"|
			data = GP:tx_ipandlanguageredirect_pi1|ipAddress
			htmlSpecialChars = 1
			required = 1
		}

		# Fake country for testing (overlays ip-address) - e.g. &tx_ipandlanguageredirect_pi1[countryCode]=us (USA)
		60 = TEXT
		60 {
			noTrimWrap = | data-ipandlanguageredirect-countrycode="|"|
			data = GP:tx_ipandlanguageredirect_pi1|countryCode
			htmlSpecialChars = 1
			required = 1
		}

		# Fake referrer for testing - e.g. &tx_ipandlanguageredirect_pi1[referrer]=www.google.de
		70 = TEXT
		70 {
			noTrimWrap = | data-ipandlanguageredirect-referrer="|"|
			data = GP:tx_ipandlanguageredirect_pi1|referrer
			htmlSpecialChars = 1
			required = 1
		}

		# Fake domain for testing - e.g. &tx_ipandlanguageredirect_pi1[domain]=www.production.org
		80 = TEXT
		80 {
			noTrimWrap = | data-ipandlanguageredirect-domain="|"|
			data = GP:tx_ipandlanguageredirect_pi1|domain
			htmlSpecialChars = 1
			required = 1
		}
	}
}

# AJAX types
redirectAjax = PAGE
redirectAjax {
	typeNum = 1555
	config {
		additionalHeaders = Content-Type: application/json
		additionalHeaders.10.header = Content-Type: application/json
		no_cache = 1
		disableAllHeaderCode = 1
		disablePrefixComment = 1
		xhtml_cleaning = 0
		admPanel = 0
		debug = 0
	}

	10  = USER
	10 {
		userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
		extensionName = Ipandlanguageredirect
		pluginName = Pi1
		vendorName = In2code
		controller = Redirect
		action = redirect
		switchableControllerActions.Redirect.1 = redirect
	}
}
testAjax < redirectAjax
testAjax {
	typeNum = 1556
	10.action = test
	10.switchableControllerActions.Redirect.1 = test
}

Testing

Simulate browserlanguage, country and referrer

http://domain.org/index.php?id=1
&tx_ipandlanguageredirect_pi1[ipAddress]=66.85.131.18
&tx_ipandlanguageredirect_pi1[browserLanguage]=de
&tx_ipandlanguageredirect_pi1[referrer]=www.google.de
&tx_ipandlanguageredirect_pi1[countryCode]=af
&tx_ipandlanguageredirect_pi1[domain]=www.domain.org
&no_cache=1

Note: Be aware that this settings are cached by default. So you have to always add a &no_cache=1

Don't redirect or suggest but show the redirectUri in the browserconsole

http://domain.org/index.php?id=1
&ipandlanguagedebug=1

Example answer from your server:

{
  "redirectUri": "https:\/\/local.domain.org\/de\/",
  "activated": true,
  "events": [
    "redirect"
  ],
  "activatedReasons": {
    "differentLanguages": true,
    "differentRootpages": false
  },
  "country": "jp",
  "givenParameters": {
    "browserLanguage": "de",
    "referrer": "www.google.de",
    "ipAddress": "27.121.255.4",
    "languageUid": 0,
    "rootpageUid": 209,
    "countryCodeOverlay": "",
    "domain": "local.domain.org"
  }
}

FAQ

  • Hide Suggest Message
    • Q1: How to disable the suggest message on click on one of my own links?
    • A1: You could add links or other dom elements with attribute data-ipandlanguageredirect-action="hideMessage" anywhere on your page to disable the suggest message. Use case: If the user changes the region or language manually on your site, the message should be dissapear in future.
    • Q2: How to disable the suggest message with a GET parameter?
    • A2: The message will be hidden and the cookie to hide it will be set if the GET parameter &h=1 or &h=3 is given
  • Disable redirect
    • Q1: How to disable the redirect on click on one of my own links?
    • A1: You could add links or other dom elements with attribute data-ipandlanguageredirect-action="disableRedirect" anywhere on your page to disable redirect.
    • Q2: How to disable the redirect with a GET parameter?
    • A2: The redirect will be disabled by settings a cookie if the GET parameter &h=2 or &h=3 is given
  • Cookie Livetime
    • The default cookie livetime is temporarely - as long as the browser is open. This is not adjustable at the moment.
  • Testing
    • Q1: How can I test another IP-address, region or browserlanguage?
    • A1: See part testing
    • Q2: Where can I see which parameters are send and received via AJAX?
    • A2: Open your browser console and check the post request to ?type=1555 - check the parameters or answers
  • Typenum will not work
    • Q1: In TYPO3 9 or higher my requests won't work - what can I do?
    • Q1: You have to define the used type param in your routing configuration (see following example)

Routing example:

routeEnhancers:
    PageTypeSuffix:
        type: PageType
        map:
            redirect.json: 1555

Your Contribution

Pull requests are welcome in general! Nevertheless please don't forget to add a description to your pull requests. This is very helpful to understand what kind of issue the PR is going to solve.

  • Bugfixes: Please describe what kind of bug your fix solve and give me feedback how to reproduce the issue. I'm going to accept only bugfixes if I can reproduce the issue.
  • Features: Not every feature is relevant for the bulk of extension users. Please discuss a new feature before.

Contribution with ddev

Requirements

  1. Install ddev, see: https://ddev.readthedocs.io/en/stable/#installation
  2. Install git-lfs, see: https://git-lfs.github.com/

Installation

  1. Clone this repository
  2. Run ddev start
  3. Run ddev initialize to setup configurations and test database

Branchinfo

  • Main Branch - Next Major Version
  • typo3-v13: Version V13 for TYPO3 13

What's not (yet?) possible at the moment

  • Make wildcard usage available in browserlanguage (like "en*" for all english browserlanguages)
  • Support all browserlanguages and not only the first one
  • Support also continents

Early Access Programm for TYPO3 14 support

ℹ️ TYPO3 14 compatibility

See EAP page (DE) or EAP page (EN) for more information how to get access to a TYPO3 14 version

Changelog

Version Date State Description Note
13.0.0 2025-08-07 Feature TYPO3 v13 compatibility
5.2.2 2025-01-10 Task Logging adjustments and small bugfixes
5.2.1 2023-04-23 Bugfix Bugfix for correct constraints
5.2.0 2023-04-20 Feabure Support for TYPO3 12
5.1.2 2023-06-12 Security Fix a possible SQL injection
5.1.1 2023-02-07 Bugfix Fixed undefined array key exception in PHP 8
5.1.0 2022-07-12 Task Css and frontend toolchain update
5.0.0 2022-04-08 Task Update for TYPO3 11 (9 and 10 support is dropped now)
4.0.1 2021-11-22 Task Define extension key in composer.json file
4.0.0 2020-12-31 Task Update for TYPO3 9 and 10
3.1.0 2020-02-07 Task Small update: Move ext icon to Public, clean composer.json, doc update
3.0.1 2019-08-06 Bugfix Don't use a configuration of a wrong rootpage
3.0.0 !!! 2019-07-05 Feature Do actions based on user agent (disable redirect for google page speed) Update your configuration
2.2.0 2019-04-26 Task Support language handling in TYPO3 9, small documentation fixes
2.1.0 2019-01-10 Task Small cleanup, small text changes
2.0.0 !!! 2018-10-18 Feature Multi domain handling, actionOnHomeOnly, offline ip2geo, stayOnCurrentPage Update your configuration
1.8.0 2018-08-23 Task Add extension icon, add some documentation
1.7.2 2018-01-21 Task Allow ipapi key now without &key=
1.7.1 2018-01-16 Bugfix Don't send "null" for an IP-address value if not testvalue is given
1.7.0 2017-09-25 Feature Support paid variant of IpApi.co for more then 1000 visitors a day
1.6.4 2017-08-11 Bugfix Fix header output in TYPO3 8
1.6.3 2017-07-28 Bugfix Disable cHash check for AJAX requests in T3 8
1.6.2 2017-07-12 Bugfix Fix small typo in composer.json
1.6.1 2017-04-12 Bugfix Fix getting browserlanguage from chrome
1.6.0 2017-02-04 Feature Redirection should be only once in a session
1.5.3 2017-02-01 Bugfix Make code readable for PHP 5.5
1.5.2 2017-01-31 Task Remove unused typoscript
1.5.1 2017-01-26 Bugfix Avoid JS exception if state == none
1.5.0 2017-01-25 Feature New option to disable functions for a pagetree
1.4.1 2016-11-15 Task Semantic code cleanup for HTML and CSS
1.4.0 2016-11-15 Feature Semantic code cleanup for HTML and CSS
1.3.0 2016-11-07 Feature Hide suggest message on GET parameter
1.2.0 2016-11-03 Feature Allow hideMessage on multi-links now
1.1.0 2016-11-01 Feature Add testing features
1.0.0 2016-11-01 Initial Initial release

in2code/ipandlanguageredirect 适用场景与选型建议

in2code/ipandlanguageredirect 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 43.44k 次下载、GitHub Stars 达 14, 最近一次更新时间为 2018 年 07 月 26 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「redirect」 「typo3」 「ip address」 「browserlanguage」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 in2code/ipandlanguageredirect 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 in2code/ipandlanguageredirect 我们能提供哪些服务?
定制开发 / 二次开发

基于 in2code/ipandlanguageredirect 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 43.44k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 17
  • 点击次数: 5
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 14
  • Watchers: 6
  • Forks: 16
  • 开发语言: PHP

其他信息

  • 授权协议: GPL-2.0-or-later
  • 更新时间: 2018-07-26