Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 74 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
FundraiserRedirector | |
0.00% |
0 / 74 |
|
0.00% |
0 / 4 |
380 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 46 |
|
0.00% |
0 / 1 |
272 | |||
reload | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
isValidIsoCountryCode | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /* |
3 | * Provides redirect service for donors coming from external sites (so that they get |
4 | * directed to the proper form for their country). |
5 | * |
6 | * @author Ryan Kaldari <rkaldari@wikimedia.org> |
7 | * @author Peter Gehres <pgehres@wikimedia.org> |
8 | */ |
9 | |
10 | namespace MediaWiki\Extension\FundraiserLandingPage\Specials; |
11 | |
12 | use MediaWiki\MediaWikiServices; |
13 | use SpecialPage; |
14 | use UnlistedSpecialPage; |
15 | |
16 | class FundraiserRedirector extends UnlistedSpecialPage { |
17 | public function __construct() { |
18 | parent::__construct( 'FundraiserRedirector' ); |
19 | } |
20 | |
21 | /** |
22 | * @param string $par |
23 | */ |
24 | public function execute( $par ) { |
25 | global $wgFundraiserLPDefaults, $wgFundraiserLandingPageChapters; |
26 | |
27 | // Country passed in the URL param gets first precedence. |
28 | $country = $this->getRequest()->getVal( 'country' ); |
29 | if ( !self::isValidIsoCountryCode( $country ) ) { |
30 | $country = ''; |
31 | } |
32 | |
33 | // Get country from the GeoIP cookie if present. |
34 | if ( !$country ) { |
35 | $geoip = $this->getRequest()->getCookie( 'GeoIP', '' ); |
36 | if ( $geoip ) { |
37 | $components = explode( ':', $geoip ); |
38 | $country = $components[0]; |
39 | } |
40 | } |
41 | |
42 | if ( !$country ) { |
43 | // If country isn't set, try realoding the page (redirecting to the same page |
44 | // with a 'reloaded' URL param to prevent a loop). This may be necessary if |
45 | // no GeoIP cookie was previously set for this domain. While our front-end |
46 | // cache showuld always set a GeoIP cookie, it won't be visible server-side |
47 | // until it's reflected back by the browser. For details, see T317427. |
48 | if ( !$this->getRequest()->getBool( 'reloaded' ) ) { |
49 | $this->reload(); |
50 | return; |
51 | } |
52 | |
53 | // Still no country? use the default. |
54 | $country = $wgFundraiserLPDefaults[ 'country' ]; |
55 | } |
56 | |
57 | // Set the language parameter |
58 | $language = $this->getRequest()->getVal( 'uselang' ); |
59 | // If not set, try the browser language |
60 | if ( !$language ) { |
61 | $mwLanguages = array_keys( MediaWikiServices::getInstance()->getLanguageNameUtils()->getLanguageNames() ); |
62 | $languages = array_keys( $this->getRequest()->getAcceptLang() ); |
63 | foreach ( $languages as $tryLanguage ) { |
64 | if ( in_array( $tryLanguage, $mwLanguages ) ) { |
65 | // use the language if it is supported in MediaWiki |
66 | $language = $tryLanguage; |
67 | // don't search further |
68 | break; |
69 | } |
70 | } |
71 | } |
72 | |
73 | $params = [ |
74 | 'country' => $country, |
75 | 'uselang' => $language, |
76 | // set default tracking variables that will be overridden |
77 | // by anything passed in the query string |
78 | 'wmf_medium' => "spontaneous", |
79 | 'wmf_source' => "fr-redir", |
80 | 'wmf_campaign' => "spontaneous", |
81 | ]; |
82 | |
83 | // Pass any other params that are set |
84 | // If we arrived here with a 'reloaded' param, don't pass that along when |
85 | // redirecting to Special:FundraiserLandingPage. |
86 | $excludeKeys = [ 'country', 'title', 'reloaded' ]; |
87 | if ( $this->getRequest()->getQueryValuesOnly() ) { |
88 | foreach ( $this->getRequest()->getQueryValuesOnly() as $key => $value ) { |
89 | // Skip the required variables |
90 | if ( !in_array( $key, $excludeKeys ) ) { |
91 | // Change any starting with utm_ to wmf_ - T351325 |
92 | $params[ str_replace( 'utm_', 'wmf_', $key ) ] = $value; |
93 | } |
94 | } |
95 | } |
96 | |
97 | // set the default redirect |
98 | $redirectURL = SpecialPage::getTitleFor( 'FundraiserLandingPage' )->getLocalUrl( $params ); |
99 | |
100 | // if the country is covered by a payment-processing chapter, redirect |
101 | // the donor to the chapter's default landing page |
102 | if ( array_key_exists( $params['country'], $wgFundraiserLandingPageChapters ) ) { |
103 | // Get the message key for the chapter's landing page |
104 | $message_key = $wgFundraiserLandingPageChapters[ $params['country'] ]; |
105 | // Get the url for the chapter's landing page |
106 | $message = $this->msg( $message_key )->plain(); |
107 | // if the message is not equal to the default message that is returned |
108 | // for a missing message, set the redirect URL to the message |
109 | if ( $message != "<$message_key>" ) { |
110 | $redirectURL = $message; |
111 | |
112 | if ( strpos( $redirectURL, "LandingCheck" ) !== false ) { |
113 | // the chapter is using LandingCheck, so go ahead and send |
114 | // all of the params as well |
115 | $querystring = http_build_query( $params ); |
116 | |
117 | if ( strpos( $redirectURL, "?" ) === false ) { |
118 | $redirectURL .= "?" . $querystring; |
119 | } else { |
120 | $redirectURL .= "&" . $querystring; |
121 | } |
122 | } |
123 | } |
124 | } |
125 | // Redirect |
126 | $this->getOutput()->redirect( $redirectURL ); |
127 | } |
128 | |
129 | /** |
130 | * Reload the page by redirecting to the same URL, adding a 'reloaded' URL param, |
131 | * and preserving other params from the current request. |
132 | * |
133 | * @return void |
134 | */ |
135 | private function reload() { |
136 | $params = $this->getRequest()->getQueryValuesOnly(); |
137 | |
138 | // Title may be re-added below by getTitleFor() |
139 | unset( $params[ 'title' ] ); |
140 | |
141 | // 'reloaded' param used to prevent an infinite redirect loop |
142 | $params[ 'reloaded' ] = 'true'; |
143 | |
144 | $redirectURL = SpecialPage::getTitleFor( 'FundraiserRedirector' ) |
145 | ->getLocalUrl( $params ); |
146 | |
147 | $this->getOutput()->redirect( $redirectURL ); |
148 | } |
149 | |
150 | /** |
151 | * Checks to see if $country is a valid iso 3166-1 country code. |
152 | * DOES NOT VERIFY THAT WE FUNDRAISE THERE. Only that the code makes sense. |
153 | * @param string $country the code we want to check |
154 | * @return bool |
155 | */ |
156 | public static function isValidIsoCountryCode( $country ) { |
157 | /** |
158 | * List of valid iso 3166 country codes, regenerated on 1380836686 |
159 | * Code generated by a happy script at |
160 | * https://gerrit.wikimedia.org/r/#/admin/projects/wikimedia/fundraising/tools,branches |
161 | */ |
162 | $iso_3166_codes = [ |
163 | 'AF', 'AX', 'AL', 'DZ', 'AS', 'AD', 'AO', 'AI', 'AQ', 'AG', 'AR', 'AM', 'AW', 'AU', |
164 | 'AT', 'AZ', 'BS', 'BH', 'BD', 'BB', 'BY', 'BE', 'BZ', 'BJ', 'BM', 'BT', 'BO', 'BQ', |
165 | 'BA', 'BW', 'BV', 'BR', 'IO', 'BN', 'BG', 'BF', 'BI', 'KH', 'CM', 'CA', 'CV', 'KY', |
166 | 'CF', 'TD', 'CL', 'CN', 'CX', 'CC', 'CO', 'KM', 'CG', 'CD', 'CK', 'CR', 'CI', 'HR', |
167 | 'CU', 'CW', 'CY', 'CZ', 'DK', 'DJ', 'DM', 'DO', 'EC', 'EG', 'SV', 'GQ', 'ER', 'EE', |
168 | 'ET', 'FK', 'FO', 'FJ', 'FI', 'FR', 'GF', 'PF', 'TF', 'GA', 'GM', 'GE', 'DE', 'GH', |
169 | 'GI', 'GR', 'GL', 'GD', 'GP', 'GU', 'GT', 'GG', 'GN', 'GW', 'GY', 'HT', 'HM', 'VA', |
170 | 'HN', 'HK', 'HU', 'IS', 'IN', 'ID', 'IR', 'IQ', 'IE', 'IM', 'IL', 'IT', 'JM', 'JP', |
171 | 'JE', 'JO', 'KZ', 'KE', 'KI', 'KP', 'KR', 'KW', 'KG', 'LA', 'LV', 'LB', 'LS', 'LR', |
172 | 'LY', 'LI', 'LT', 'LU', 'MO', 'MK', 'MG', 'MW', 'MY', 'MV', 'ML', 'MT', 'MH', 'MQ', |
173 | 'MR', 'MU', 'YT', 'MX', 'FM', 'MD', 'MC', 'MN', 'ME', 'MS', 'MA', 'MZ', 'MM', 'NA', |
174 | 'NR', 'NP', 'NL', 'NC', 'NZ', 'NI', 'NE', 'NG', 'NU', 'NF', 'MP', 'NO', 'OM', 'PK', |
175 | 'PW', 'PS', 'PA', 'PG', 'PY', 'PE', 'PH', 'PN', 'PL', 'PT', 'PR', 'QA', 'RE', 'RO', |
176 | 'RU', 'RW', 'BL', 'SH', 'KN', 'LC', 'MF', 'PM', 'VC', 'WS', 'SM', 'ST', 'SA', 'SN', |
177 | 'RS', 'SC', 'SL', 'SG', 'SX', 'SK', 'SI', 'SB', 'SO', 'ZA', 'GS', 'SS', 'ES', 'LK', |
178 | 'SD', 'SR', 'SJ', 'SZ', 'SE', 'CH', 'SY', 'TW', 'TJ', 'TZ', 'TH', 'TL', 'TG', 'TK', |
179 | 'TO', 'TT', 'TN', 'TR', 'TM', 'TC', 'TV', 'UG', 'UA', 'AE', 'GB', 'US', 'UM', 'UY', |
180 | 'UZ', 'VU', 'VE', 'VN', 'VG', 'VI', 'WF', 'EH', 'YE', 'ZM', 'ZW', |
181 | ]; |
182 | |
183 | return in_array( $country, $iso_3166_codes ); |
184 | } |
185 | |
186 | } |