Index: trunk/extensions/ZeroRatedMobileAccess/ZeroRatedMobileAccess.body.php |
— | — | @@ -1,13 +1,22 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | class ExtZeroRatedMobileAccess { |
5 | | - const VERSION = '0.0.5'; |
| 5 | + const VERSION = '0.0.6'; |
6 | 6 | |
7 | 7 | public static $renderZeroRatedLandingPage; |
| 8 | + public static $renderZeroRatedBanner; |
8 | 9 | private static $debugOutput = array(); |
9 | 10 | private static $displayDebugOutput = false; |
| 11 | + private static $formatMobileUrl = '//%s.m.wikipedia.org/'; |
| 12 | + private static $title; |
| 13 | + private static $isFilePage; |
| 14 | + private static $acceptBilling; |
| 15 | + private static $carrier; |
| 16 | + private static $renderZeroRatedRedirect; |
10 | 17 | |
11 | 18 | /** |
| 19 | + * Handler for the BeforePageDisplay hook |
| 20 | + * |
12 | 21 | * @param $out OutputPage |
13 | 22 | * @param $text String |
14 | 23 | * @return bool |
— | — | @@ -15,9 +24,95 @@ |
16 | 25 | public function beforePageDisplayHTML( &$out, &$text ) { |
17 | 26 | global $wgRequest; |
18 | 27 | wfProfileIn( __METHOD__ ); |
| 28 | + |
| 29 | + $output = Html::openElement( 'div', |
| 30 | + array( 'id' => 'zero-landing-page' ) ); |
| 31 | + |
19 | 32 | self::$renderZeroRatedLandingPage = $wgRequest->getFuzzyBool( 'renderZeroRatedLandingPage' ); |
| 33 | + self::$renderZeroRatedBanner = $wgRequest->getFuzzyBool( 'renderZeroRatedBanner' ); |
| 34 | + self::$renderZeroRatedRedirect = $wgRequest->getFuzzyBool( 'renderZeroRatedRedirect' ); |
| 35 | + self::$acceptBilling = $wgRequest->getVal( 'acceptbilling' ); |
| 36 | + self::$title = $out->getTitle(); |
| 37 | + |
| 38 | + if ( self::$title->getNamespace() == NS_FILE ) { |
| 39 | + self::$isFilePage = true; |
| 40 | + } |
| 41 | + |
| 42 | + if ( self::$acceptBilling === 'no' ) { |
| 43 | + $targetUrl = $wgRequest->getVal( 'returnto' ); |
| 44 | + $out->redirect( $targetUrl, '301' ); |
| 45 | + $out->output(); |
| 46 | + } |
| 47 | + |
| 48 | + if ( self::$acceptBilling === 'yes' ) { |
| 49 | + $targetUrl = $wgRequest->getVal( 'returnto' ); |
| 50 | + if ( $targetUrl ) { |
| 51 | + $out->redirect( $targetUrl, '301' ); |
| 52 | + $out->output(); |
| 53 | + } |
| 54 | + } |
| 55 | + |
| 56 | + if ( self::$isFilePage && self::$acceptBilling !== 'yes' ) { |
| 57 | + $acceptBillingYes = Html::rawElement( 'a', |
| 58 | + array('href' => $wgRequest->appendQuery( 'renderZeroRatedBanner=true&acceptbilling=yes' ) ), |
| 59 | + wfMsg( 'zero-rated-mobile-access-banner-text-data-charges-yes' ) ); |
| 60 | + $referrer = $wgRequest->getHeader( 'referer' ); |
| 61 | + $acceptBillingNo = Html::rawElement( 'a', |
| 62 | + array('href' => $wgRequest->appendQuery( 'acceptbilling=no&returnto=' . urlencode( $referrer ) ) ), |
| 63 | + wfMsg( 'zero-rated-mobile-access-banner-text-data-charges-no' ) ); |
| 64 | + $bannerText = Html::rawElement( 'h3', |
| 65 | + array( 'id' => 'zero-rated-banner-text' ), |
| 66 | + wfMsg( 'zero-rated-mobile-access-banner-text-data-charges', $acceptBillingYes, $acceptBillingNo ) ); |
| 67 | + $banner = Html::rawElement( 'div', |
| 68 | + array( 'style' => 'display:none;', |
| 69 | + 'id' => 'zero-rated-banner-red' ), |
| 70 | + $bannerText |
| 71 | + ); |
| 72 | + $output .= $banner; |
| 73 | + $out->clearHTML(); |
| 74 | + $out->setPageTitle( null ); |
| 75 | + } elseif ( self::$renderZeroRatedRedirect === true ) { |
| 76 | + $returnto = $wgRequest->getVal( 'returnto' ); |
| 77 | + $acceptBillingYes = Html::rawElement( 'a', |
| 78 | + array('href' => $wgRequest->appendQuery( 'renderZeroRatedBanner=true&acceptbilling=yes&returnto=' . urlencode( $returnto ) ) ), |
| 79 | + wfMsg( 'zero-rated-mobile-access-banner-text-data-charges-yes' ) ); |
| 80 | + $referrer = $wgRequest->getHeader( 'referer' ); |
| 81 | + $acceptBillingNo = Html::rawElement( 'a', |
| 82 | + array('href' => $wgRequest->appendQuery( 'acceptbilling=no&returnto=' . urlencode( $referrer ) ) ), |
| 83 | + wfMsg( 'zero-rated-mobile-access-banner-text-data-charges-no' ) ); |
| 84 | + $bannerText = Html::rawElement( 'h3', |
| 85 | + array( 'id' => 'zero-rated-banner-text' ), |
| 86 | + wfMsg( 'zero-rated-mobile-access-banner-text-data-charges', $acceptBillingYes, $acceptBillingNo ) ); |
| 87 | + $banner = Html::rawElement( 'div', |
| 88 | + array( 'style' => 'display:none;', |
| 89 | + 'id' => 'zero-rated-banner-red' ), |
| 90 | + $bannerText |
| 91 | + ); |
| 92 | + $output .= $banner; |
| 93 | + $out->clearHTML(); |
| 94 | + $out->setPageTitle( null ); |
| 95 | + } elseif ( self::$renderZeroRatedBanner === true ) { |
| 96 | + // a2enmod headers >>> .htaccess >>> RequestHeader set HTTP_CARRIER Verizon |
| 97 | + $carrier = $wgRequest->getHeader( 'HTTP_CARRIER' ); |
| 98 | + self::$carrier = $this->lookupCarrier( $carrier ); |
| 99 | + $html = $out->getHTML(); |
| 100 | + $parsedHtml = $this->parseLinksForZeroQueryString( $html ); |
| 101 | + $out->clearHTML(); |
| 102 | + $out->addHTML( $parsedHtml ); |
| 103 | + $bannerText = Html::rawElement( 'h3', |
| 104 | + array( 'id' => 'zero-rated-banner-text' ), |
| 105 | + wfMsg( 'zero-rated-mobile-access-banner-text', self::$carrier['link'] ) ); |
| 106 | + $banner = Html::rawElement( 'div', |
| 107 | + array( 'style' => 'display:none;', |
| 108 | + 'id' => 'zero-rated-banner' ), |
| 109 | + $bannerText |
| 110 | + ); |
| 111 | + $output .= $banner; |
| 112 | + } |
20 | 113 | if ( self::$renderZeroRatedLandingPage === true ) { |
21 | | - echo wfMsg( 'zero-rated-mobile-access-desc' ); |
| 114 | + $out->clearHTML(); |
| 115 | + $out->setPageTitle( null ); |
| 116 | + $output .= wfMsg( 'zero-rated-mobile-access-desc' ); |
22 | 117 | $languageNames = Language::getLanguageNames(); |
23 | 118 | $country = $wgRequest->getVal( 'country' ); |
24 | 119 | $ip = $wgRequest->getVal( 'ip', wfGetIP() ); |
— | — | @@ -47,16 +142,32 @@ |
48 | 143 | self::writeDebugOutput(); |
49 | 144 | |
50 | 145 | if ( is_array( $languagesForCountry ) ) { |
51 | | - foreach( $languagesForCountry as $language ) { |
52 | | - echo Html::element( 'h3', |
53 | | - array( 'id' => 'lang_' . $language['language'] ), |
54 | | - $languageNames[$language['language']] |
| 146 | + $sizeOfLanguagesForCountry = sizeof( $languagesForCountry ); |
| 147 | + for ( $i = 0; $i < $sizeOfLanguagesForCountry; $i++ ) { |
| 148 | + $languageName = $languageNames[$languagesForCountry[$i]['language']]; |
| 149 | + $languageCode = $languagesForCountry[$i]['language']; |
| 150 | + $output .= Html::element( 'hr' ); |
| 151 | + $output .= Html::element( 'h3', |
| 152 | + array( 'id' => 'lang_' . $languageCode ), |
| 153 | + $languageName |
55 | 154 | ); |
56 | | - echo Html::element( 'hr' ); |
57 | | - echo self::getSearchFormHtml( $language['language'] ); |
| 155 | + if ( $i == 0 ) { |
| 156 | + $output .= self::getSearchFormHtml( $languageCode ); |
| 157 | + } else { |
| 158 | + $languageUrl = sprintf( self::$formatMobileUrl, $languageCode ); |
| 159 | + $output .= Html::element( 'a', |
| 160 | + array( 'id' => 'lang_' . $languageCode, |
| 161 | + 'href' => $languageUrl ), |
| 162 | + wfMessage( 'zero-rated-mobile-access-home-page-selection', |
| 163 | + $languageName )->inLanguage( $languageCode ) |
| 164 | + ); |
| 165 | + $output .= Html::element( 'br' ); |
| 166 | + } |
58 | 167 | } |
59 | 168 | } |
60 | | - $output = Html::openElement( 'select', |
| 169 | + $output .= Html::element( 'hr' ); |
| 170 | + $output .= wfMsg( 'zero-rated-mobile-access-home-page-selection-text' ); |
| 171 | + $output .= Html::openElement( 'select', |
61 | 172 | array( 'id' => 'languageselection', |
62 | 173 | 'onchange' => 'javascript:window.location = this.options[this.selectedIndex].value;', |
63 | 174 | ) |
— | — | @@ -67,19 +178,162 @@ |
68 | 179 | ); |
69 | 180 | foreach ( $languageNames as $languageCode => $languageName ) { |
70 | 181 | $output .= Html::element( 'option', |
71 | | - array( 'value' => '//' . $languageCode . '.m.wikipedia.org/' ), |
72 | | - $languageName |
| 182 | + array( 'value' => sprintf( self::$formatMobileUrl, $languageCode ) ), |
| 183 | + $languageName |
73 | 184 | ); |
74 | 185 | } |
75 | 186 | $output .= Html::closeElement( 'select' ); |
76 | | - echo $output; |
77 | | - exit(); |
78 | 187 | } |
79 | 188 | |
| 189 | + $output .= Html::closeElement( 'div' ); |
| 190 | + $out->addHTML( $output ); |
80 | 191 | wfProfileOut( __METHOD__ ); |
81 | 192 | return true; |
82 | 193 | } |
| 194 | + |
| 195 | + /** |
| 196 | + * Returns information about carrier |
| 197 | + * |
| 198 | + * @param String $carrier: Name of carrier e.g., "Verizon Wireless" |
| 199 | + * @return Array |
| 200 | + */ |
| 201 | + private function lookupCarrier( $carrier ) { |
| 202 | + wfProfileIn( __METHOD__ ); |
| 203 | + $carrierLink = ''; |
| 204 | + $carrierLinkData = ''; |
| 205 | + switch ( $carrier ) { |
| 206 | + case 'Verizon': |
| 207 | + $carrierLinkData = array( 'name' => 'Verizon Wireless', |
| 208 | + 'url' => 'http://www.verizonwireless.com/b2c/index.html', |
| 209 | + 'partnerId' => '1006' ); |
| 210 | + break; |
| 211 | + case 'Orange': |
| 212 | + $carrierLinkData = array( 'name' => 'Orange Tunisia', |
| 213 | + 'url' => 'http://www.orange.tn/', |
| 214 | + 'partnerId' => '1007' ); |
| 215 | + break; |
| 216 | + } |
83 | 217 | |
| 218 | + if ( is_array( $carrierLinkData ) ) { |
| 219 | + $carrierLink = Html::rawElement( 'a', |
| 220 | + array('href' => $carrierLinkData['url'] ), |
| 221 | + $carrierLinkData['name'] ); |
| 222 | + } |
| 223 | + $carrierLinkData['link'] = $carrierLink; |
| 224 | + wfProfileOut( __METHOD__ ); |
| 225 | + return $carrierLinkData; |
| 226 | + } |
| 227 | + |
| 228 | + /** |
| 229 | + * Returns the Html of a page with the various links appended with zeropartner parameter |
| 230 | + * |
| 231 | + * @param String $html: Html of current page |
| 232 | + * @return String |
| 233 | + */ |
| 234 | + private function parseLinksForZeroQueryString( $html ) { |
| 235 | + wfProfileIn( __METHOD__ ); |
| 236 | + $html = mb_convert_encoding( $html, 'HTML-ENTITIES', "UTF-8" ); |
| 237 | + libxml_use_internal_errors( true ); |
| 238 | + $doc = new DOMDocument(); |
| 239 | + $doc->loadHTML( '<?xml encoding="UTF-8">' . $html ); |
| 240 | + libxml_use_internal_errors( false ); |
| 241 | + $doc->preserveWhiteSpace = false; |
| 242 | + $doc->strictErrorChecking = false; |
| 243 | + $doc->encoding = 'UTF-8'; |
| 244 | + |
| 245 | + $xpath = new DOMXpath( $doc ); |
| 246 | + |
| 247 | + $zeroRatedLinks = $xpath->query( "//a[not(contains(@class,'external'))]" ); |
| 248 | + foreach ( $zeroRatedLinks as $zeroRatedLink ) { |
| 249 | + $zeroRatedLinkHref = $zeroRatedLink->getAttribute( 'href' ); |
| 250 | + if ( $zeroRatedLinkHref && substr( $zeroRatedLinkHref, 0, 1 ) !== '#' ) { |
| 251 | + $zeroPartnerUrl = $this->appendQueryString( $zeroRatedLinkHref, |
| 252 | + array( array( 'name' => 'zeropartner', |
| 253 | + 'value' => self::$carrier['partnerId'] ), |
| 254 | + array('name' => 'renderZeroRatedBanner', |
| 255 | + 'value' => 'true') ) ); |
| 256 | + if ( $zeroPartnerUrl ) { |
| 257 | + $zeroRatedLink->setAttribute( 'href', $zeroPartnerUrl ); |
| 258 | + } |
| 259 | + } |
| 260 | + } |
| 261 | + |
| 262 | + $zeroRatedExternalLinks = $xpath->query( "//a[contains(@class,'external')]" ); |
| 263 | + foreach ( $zeroRatedExternalLinks as $zeroRatedExternalLink ) { |
| 264 | + $zeroRatedExternalLinkHref = $zeroRatedExternalLink->getAttribute( 'href' ); |
| 265 | + if ( $zeroRatedExternalLinkHref && substr( $zeroRatedExternalLinkHref, 0, 1 ) !== '#' ) { |
| 266 | + $zeroPartnerUrl = $this->appendQueryString( $zeroRatedLinkHref, |
| 267 | + array( array( 'name' => 'zeropartner', |
| 268 | + 'value' => self::$carrier['partnerId'] ), |
| 269 | + array('name' => 'renderZeroRatedBanner', |
| 270 | + 'value' => 'true') ) ); |
| 271 | + if ( $zeroPartnerUrl ) { |
| 272 | + $zeroRatedExternalLink->setAttribute( 'href', '?renderZeroRatedRedirect=true&returnto=' . urlencode($zeroRatedExternalLinkHref) ); |
| 273 | + } |
| 274 | + } |
| 275 | + } |
| 276 | + |
| 277 | + $output = $doc->saveXML( null, LIBXML_NOEMPTYTAG ); |
| 278 | + wfProfileOut( __METHOD__ ); |
| 279 | + return $output; |
| 280 | + } |
| 281 | + |
| 282 | + /** |
| 283 | + * Returns the url with querystring parameters appended |
| 284 | + * |
| 285 | + * @param String $url: valid url to append querystring |
| 286 | + * @param Array $queryStringParameters: array of parameters to add to querystring |
| 287 | + * @return String |
| 288 | + */ |
| 289 | + private function appendQueryString( $url, $queryStringParameters ) { |
| 290 | + wfProfileIn( __METHOD__ ); |
| 291 | + $parsedUrl = parse_url( $url ); |
| 292 | + if ( isset( $parsedUrl['query'] ) ) { |
| 293 | + parse_str( $parsedUrl['query'], $queryString ); |
| 294 | + foreach ( $queryStringParameters as $queryStringParameter ) { |
| 295 | + $queryString[$queryStringParameter['name']] = $queryStringParameter['value']; |
| 296 | + } |
| 297 | + $parsedUrl['query'] = http_build_query( $queryString ); |
| 298 | + } else { |
| 299 | + $parsedUrl['query'] = ''; |
| 300 | + foreach ( $queryStringParameters as $queryStringParameter ) { |
| 301 | + $parsedUrl['query'] .= "{$queryStringParameter['name']}={$queryStringParameter['value']}&"; |
| 302 | + } |
| 303 | + if ( substr( $parsedUrl['query'], -1, 1 ) === '&' ) { |
| 304 | + $parsedUrl['query'] = substr( $parsedUrl['query'], 0, -1 ); |
| 305 | + } |
| 306 | + } |
| 307 | + wfProfileOut( __METHOD__ ); |
| 308 | + return $this->unParseUrl( $parsedUrl ); |
| 309 | + } |
| 310 | + |
| 311 | + /** |
| 312 | + * Returns the full url |
| 313 | + * |
| 314 | + * @param Array $parsedUrl: the array returned from parse_url |
| 315 | + * @return String |
| 316 | + */ |
| 317 | + private function unParseUrl( $parsedUrl ) { |
| 318 | + wfProfileIn( __METHOD__ ); |
| 319 | + $scheme = isset( $parsedUrl['scheme'] ) ? $parsedUrl['scheme'] . '://' : ''; |
| 320 | + $host = isset( $parsedUrl['host'] ) ? $parsedUrl['host'] : ''; |
| 321 | + $port = isset( $parsedUrl['port'] ) ? ':' . $parsedUrl['port'] : ''; |
| 322 | + $user = isset( $parsedUrl['user'] ) ? $parsedUrl['user'] : ''; |
| 323 | + $pass = isset( $parsedUrl['pass'] ) ? ':' . $parsedUrl['pass'] : ''; |
| 324 | + $pass = ( $user || $pass ) ? "$pass@" : ''; |
| 325 | + $path = isset( $parsedUrl['path'] ) ? $parsedUrl['path'] : ''; |
| 326 | + $query = isset( $parsedUrl['query'] ) ? '?' . $parsedUrl['query'] : ''; |
| 327 | + $fragment = isset( $parsedUrl['fragment'] ) ? '#' . $parsedUrl['fragment'] : ''; |
| 328 | + wfProfileOut( __METHOD__ ); |
| 329 | + return "$scheme$user$pass$host$port$path$query$fragment"; |
| 330 | + } |
| 331 | + |
| 332 | + /** |
| 333 | + * Adds object to debugOutput Array |
| 334 | + * |
| 335 | + * @param Object $object: any valid PHP object |
| 336 | + * @return bool |
| 337 | + */ |
84 | 338 | private static function addDebugOutput( $object ) { |
85 | 339 | wfProfileIn( __METHOD__ ); |
86 | 340 | if ( is_array( self::$debugOutput ) ) { |
— | — | @@ -89,6 +343,11 @@ |
90 | 344 | return true; |
91 | 345 | } |
92 | 346 | |
| 347 | + /** |
| 348 | + * Writes objects from the debugOutput Array to buffer |
| 349 | + * |
| 350 | + * @return bool |
| 351 | + */ |
93 | 352 | private static function writeDebugOutput() { |
94 | 353 | wfProfileIn( __METHOD__ ); |
95 | 354 | if ( self::$debugOutput && self::$displayDebugOutput === true ) { |
— | — | @@ -102,42 +361,97 @@ |
103 | 362 | return true; |
104 | 363 | } |
105 | 364 | |
| 365 | + /** |
| 366 | + * Returns the language options array parsed from a valid Wiki page |
| 367 | + * |
| 368 | + * @return Array |
| 369 | + */ |
106 | 370 | private static function createLanguageOptionsFromWikiText() { |
| 371 | + global $wgMemc; |
107 | 372 | wfProfileIn( __METHOD__ ); |
108 | | - $languageOptions = array(); |
109 | 373 | $languageOptionsWikiPage = wfMsg( 'zero-rated-mobile-access-language-options-wiki-page' ); |
110 | 374 | $title = Title::newFromText( $languageOptionsWikiPage, NS_MEDIAWIKI ); |
111 | 375 | // Use the revision directly to prevent other hooks to be called |
112 | 376 | $rev = Revision::newFromTitle( $title ); |
113 | | - $lines = array(); |
114 | | - if ( $rev ) { |
115 | | - $lines = explode( "\n", $rev->getRawText() ); |
116 | | - } |
117 | | - if ( $lines && count( $lines ) > 0 ) { |
118 | | - $sizeOfLines = sizeof( $lines ); |
119 | | - for ( $i = 0; $i < $sizeOfLines; $i++ ) { |
120 | | - $line = $lines[$i]; |
121 | | - if ( strpos( $line, '*' ) === 0 && strpos( $line, '**' ) !== 0 && $i >= 0 ) { |
122 | | - $countryName = strtoupper( str_replace( '* ', '', $line ) ); |
123 | | - $languageOptions[$countryName] = ''; |
124 | | - } elseif ( strpos( $line, '**' ) === 0 && $i > 0 ) { |
125 | | - $lineParts = explode('#', $line); |
126 | | - $language = ( isset( $lineParts[0] ) ) ? |
127 | | - trim( str_replace( '** ', '', $lineParts[0] ) ) : |
128 | | - trim( str_replace( '** ', '', $line ) ) ; |
| 377 | + $sha1OfRev = $rev->getSha1(); |
| 378 | + $key = wfMemcKey( 'zero-rated-mobile-access-language-options', $sha1OfRev ); |
| 379 | + $languageOptions = $wgMemc->get( $key ); |
| 380 | + |
| 381 | + if ( !$languageOptions ) { |
| 382 | + $languageOptions = array(); |
| 383 | + $lines = array(); |
| 384 | + if ( $rev ) { |
| 385 | + $lines = explode( "\n", $rev->getRawText() ); |
| 386 | + } |
| 387 | + if ( $lines && count( $lines ) > 0 ) { |
| 388 | + $sizeOfLines = sizeof( $lines ); |
| 389 | + for ( $i = 0; $i < $sizeOfLines; $i++ ) { |
| 390 | + $line = $lines[$i]; |
| 391 | + if ( strpos( $line, '*' ) === 0 && strpos( $line, '**' ) !== 0 && $i >= 0 ) { |
| 392 | + $countryName = strtoupper( str_replace( '* ', '', $line ) ); |
| 393 | + $languageOptions[$countryName] = ''; |
| 394 | + } elseif ( strpos( $line, '**' ) === 0 && $i > 0 ) { |
| 395 | + $lineParts = explode('#', $line); |
| 396 | + $language = ( isset( $lineParts[0] ) ) ? |
| 397 | + trim( str_replace( '** ', '', $lineParts[0] ) ) : |
| 398 | + trim( str_replace( '** ', '', $line ) ) ; |
129 | 399 | if ( $language !== 'portal' && $language !== 'other' ) { |
130 | 400 | $languageOptions[$countryName][] = ( isset( $lineParts[1] ) ) ? |
131 | | - array( 'language' => $language, |
132 | | - 'percentage' => intval( str_replace( '%', '', trim( $lineParts[1] ) ) ) ) : |
| 401 | + array( 'language' => $language, |
| 402 | + 'percentage' => intval( str_replace( '%', '', trim( $lineParts[1] ) ) ) ) : |
133 | 403 | $language; |
134 | 404 | } |
| 405 | + } |
135 | 406 | } |
136 | 407 | } |
| 408 | + $wgMemc->set( $key, $languageOptions, self::getMaxAge() ); |
137 | 409 | } |
138 | 410 | wfProfileOut( __METHOD__ ); |
139 | 411 | return $languageOptions; |
140 | 412 | } |
141 | 413 | |
| 414 | + /** |
| 415 | + * Returns the number of seconds an item should stay in cache |
| 416 | + * |
| 417 | + * @return int: Time in seconds |
| 418 | + */ |
| 419 | + private static function getMaxAge() { |
| 420 | + wfProfileIn( __METHOD__ ); |
| 421 | + // add 10 seconds to cater for the time deviation between servers |
| 422 | + $expiry = self::todaysStart() + 24 * 3600 - wfTimestamp() + 10; |
| 423 | + wfProfileOut( __METHOD__ ); |
| 424 | + return min( $expiry, 3600 ); |
| 425 | + } |
| 426 | + |
| 427 | + /** |
| 428 | + * Returns the Unix timestamp of current day's first second |
| 429 | + * |
| 430 | + * @return int: Timestamp |
| 431 | + */ |
| 432 | + private static function todaysStart() { |
| 433 | + wfProfileIn( __METHOD__ ); |
| 434 | + static $time = false; |
| 435 | + if ( !$time ) { |
| 436 | + global $wgLocaltimezone; |
| 437 | + if ( isset( $wgLocaltimezone ) ) { |
| 438 | + $tz = new DateTimeZone( $wgLocaltimezone ); |
| 439 | + } else { |
| 440 | + $tz = new DateTimeZone( date_default_timezone_get() ); |
| 441 | + } |
| 442 | + $dt = new DateTime( 'now', $tz ); |
| 443 | + $dt->setTime( 0, 0, 0 ); |
| 444 | + $time = $dt->getTimestamp(); |
| 445 | + } |
| 446 | + wfProfileOut( __METHOD__ ); |
| 447 | + return $time; |
| 448 | + } |
| 449 | + |
| 450 | + /** |
| 451 | + * Get full country name from code |
| 452 | + * |
| 453 | + * @param string $code: alpha-2 code ISO 3166 country code |
| 454 | + * @return String |
| 455 | + */ |
142 | 456 | private static function getFullCountryNameFromCode( $code ) { |
143 | 457 | wfProfileIn( __METHOD__ ); |
144 | 458 | $countries = array( |
— | — | @@ -386,10 +700,17 @@ |
387 | 701 | return ( $code && isset( $countries[$code] ) ) ? $countries[$code] : null; |
388 | 702 | } |
389 | 703 | |
| 704 | + /** |
| 705 | + * Search form for various languages |
| 706 | + * |
| 707 | + * @param string $langCode: alpha-2 code for language |
| 708 | + * @return String |
| 709 | + */ |
390 | 710 | private static function getSearchFormHtml( $langCode ) { |
| 711 | + wfProfileIn( __METHOD__ ); |
391 | 712 | $searchValue = wfMessage( 'zero-rated-mobile-access-search' )->inLanguage( $langCode ); |
392 | 713 | $formHtml = <<<HTML |
393 | | - <form action="//{$langCode}.wikipedia.org/w/index.php" class="search_bar" method="get"> |
| 714 | + <form id="zero-language-search" action="//{$langCode}.wikipedia.org/w/index.php" class="search_bar" method="get"> |
394 | 715 | <input type="hidden" value="Special:Search" name="title"> |
395 | 716 | <div id="sq" class="divclearable"> |
396 | 717 | <input type="text" name="search" id="search" size="22" value="" autocorrect="off" autocomplete="off" autocapitalize="off" maxlength="1024"> |
— | — | @@ -398,6 +719,11 @@ |
399 | 720 | <button id="goButton" type="submit">{$searchValue}</button> |
400 | 721 | </form> |
401 | 722 | HTML; |
| 723 | + wfProfileOut( __METHOD__ ); |
402 | 724 | return $formHtml; |
403 | 725 | } |
| 726 | + |
| 727 | + public function getVersion() { |
| 728 | + return __CLASS__ . ': $Id$'; |
| 729 | + } |
404 | 730 | } |
\ No newline at end of file |
Property changes on: trunk/extensions/ZeroRatedMobileAccess/ZeroRatedMobileAccess.body.php |
___________________________________________________________________ |
Added: svn:keywords |
405 | 731 | + Id |
Index: trunk/extensions/ZeroRatedMobileAccess/ZeroRatedMobileAccess.i18n.php |
— | — | @@ -17,16 +17,27 @@ |
18 | 18 | 'zero-rated-mobile-access-search' => 'Search', |
19 | 19 | 'zero-rated-mobile-access-language-options-wiki-page' => 'Language_options', |
20 | 20 | 'zero-rated-mobile-access-language-selection' => 'All languages', |
| 21 | + 'zero-rated-mobile-access-home-page-selection' => '$1 home page', |
| 22 | + 'zero-rated-mobile-access-home-page-selection-text' => 'Or go to the home page in the following language:', |
| 23 | + 'zero-rated-mobile-access-banner-text' => 'Free Wikipedia from $1', |
| 24 | + 'zero-rated-mobile-access-banner-text-data-charges' => 'Data charges may apply continue: $1 or $2', |
| 25 | + 'zero-rated-mobile-access-banner-text-data-charges-yes' => 'Yes', |
| 26 | + 'zero-rated-mobile-access-banner-text-data-charges-no' => 'No', |
21 | 27 | ); |
22 | | - |
23 | 28 | $messages['ja'] = array ( |
24 | 29 | 'zero-rated-mobile-access-desc' => 'ゼロ格モバイルアクセス', |
25 | 30 | 'zero-rated-mobile-access-search' => '検索する', |
26 | 31 | 'zero-rated-mobile-access-language-options-wiki-page' => 'Language_options', |
27 | 32 | ); |
28 | | - |
29 | 33 | $messages['qqq'] = array( |
30 | 34 | 'zero-rated-mobile-access-desc' => '{{desc}}', |
31 | 35 | 'zero-rated-mobile-access-search' => 'Text for search action on the search button', |
32 | 36 | 'zero-rated-mobile-access-language-options-wiki-page' => 'The name of the wiki page to store the country language data', |
| 37 | + 'zero-rated-mobile-access-language-selection' => 'Text to show the user when they select a language option', |
| 38 | + 'zero-rated-mobile-access-home-page-selection' => 'name of language followed by text to show user in local link to Wikipedia', |
| 39 | + 'zero-rated-mobile-access-home-page-selection-text' => 'Text to show user prior to selection of language option', |
| 40 | + 'zero-rated-mobile-access-banner-text' => 'Text shown to users of various carriers with carrier name', |
| 41 | + 'zero-rated-mobile-access-banner-text-data-charges' => 'Data charges notice to user before images are displayed', |
| 42 | + 'zero-rated-mobile-access-banner-text-data-charges-yes' => 'Text for accepting charges', |
| 43 | + 'zero-rated-mobile-access-banner-text-data-charges-no' => 'Text for rejecting charges', |
33 | 44 | ); |
\ No newline at end of file |