Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 54 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
SpecialHideBanners | |
0.00% |
0 / 54 |
|
0.00% |
0 / 4 |
132 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
42 | |||
setHideCookie | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
6 | |||
setP3P | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | |
3 | use MediaWiki\Extension\CentralAuth\User\CentralAuthUser; |
4 | |
5 | /** |
6 | * Unlisted Special Page which sets a cookie for hiding banners across all languages of a project. |
7 | * This is typically used on donation thank-you pages so that users who have donated will no longer |
8 | * see fundrasing banners. |
9 | */ |
10 | class SpecialHideBanners extends UnlistedSpecialPage { |
11 | // Cache this blank response for a day or so (60 * 60 * 24 s.) |
12 | private const CACHE_EXPIRY = 86400; |
13 | private const P3P_SUBPAGE = 'P3P'; |
14 | |
15 | public function __construct() { |
16 | parent::__construct( 'HideBanners' ); |
17 | } |
18 | |
19 | public function execute( $par ) { |
20 | global $wgNoticeCookieDurations, $wgCentralNoticeHideBannersP3P, |
21 | $wgCentralNoticeFallbackHideCookieDuration; |
22 | |
23 | // Handle /P3P subpage with explanation of invalid P3P header |
24 | if ( ( strval( $par ) === self::P3P_SUBPAGE ) && |
25 | !$wgCentralNoticeHideBannersP3P |
26 | ) { |
27 | $this->setHeaders(); |
28 | $this->getOutput()->addWikiMsg( 'centralnotice-specialhidebanners-p3p' ); |
29 | return; |
30 | } |
31 | |
32 | $reason = $this->getRequest()->getText( 'reason', 'donate' ); |
33 | |
34 | // No duration parameter for a custom reason is not expected; we have a |
35 | // fallback value, but we log that this happened. |
36 | $duration = $this->getRequest()->getInt( 'duration', 0 ); |
37 | if ( !$duration ) { |
38 | if ( isset( $wgNoticeCookieDurations[$reason] ) ) { |
39 | $duration = $wgNoticeCookieDurations[$reason]; |
40 | } else { |
41 | $duration = $wgCentralNoticeFallbackHideCookieDuration; |
42 | wfLogWarning( 'Missing or 0 duration for hide cookie reason ' |
43 | . $reason . '.' ); |
44 | } |
45 | } |
46 | |
47 | $category = $this->getRequest()->getText( 'category', 'fundraising' ); |
48 | $category = Banner::sanitizeRenderedCategory( $category ); |
49 | $this->setHideCookie( $category, $duration, $reason ); |
50 | $this->setP3P(); |
51 | |
52 | $this->getOutput()->disable(); |
53 | wfResetOutputBuffers(); |
54 | |
55 | header( 'Content-Type: image/png' ); |
56 | if ( !$this->getUser()->isRegistered() ) { |
57 | $expiry = self::CACHE_EXPIRY; |
58 | header( "Cache-Control: public, s-maxage={$expiry}, max-age=0" ); |
59 | } |
60 | } |
61 | |
62 | /** |
63 | * Set the cookie for hiding fundraising banners. |
64 | * @param string $category |
65 | * @param int $duration |
66 | * @param string $reason |
67 | */ |
68 | private function setHideCookie( $category, $duration, $reason ) { |
69 | global $wgNoticeCookieDomain; |
70 | |
71 | $created = time(); |
72 | $exp = $created + $duration; |
73 | $value = [ |
74 | 'v' => 1, |
75 | 'created' => $created, |
76 | 'reason' => $reason |
77 | ]; |
78 | |
79 | if ( ExtensionRegistry::getInstance()->isLoaded( 'CentralAuth' ) ) { |
80 | $cookieDomain = CentralAuthUser::getCookieDomain(); |
81 | } else { |
82 | $cookieDomain = $wgNoticeCookieDomain; |
83 | } |
84 | setcookie( |
85 | "centralnotice_hide_{$category}", |
86 | json_encode( $value ), |
87 | $exp, |
88 | '/', |
89 | $cookieDomain, |
90 | false, |
91 | false |
92 | ); |
93 | } |
94 | |
95 | /** |
96 | * Set an invalid P3P policy header to make IE accept third-party hide cookies. |
97 | */ |
98 | private function setP3P() { |
99 | global $wgCentralNoticeHideBannersP3P; |
100 | |
101 | if ( !$wgCentralNoticeHideBannersP3P ) { |
102 | $url = SpecialPage::getTitleFor( |
103 | 'HideBanners', self::P3P_SUBPAGE ) |
104 | ->getCanonicalURL(); |
105 | |
106 | $p3p = "CP=\"This is not a P3P policy! See $url for more info.\""; |
107 | |
108 | } else { |
109 | $p3p = $wgCentralNoticeHideBannersP3P; |
110 | } |
111 | |
112 | header( "P3P: $p3p", true ); |
113 | } |
114 | } |