Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 112
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
WordAds_Params
0.00% covered (danger)
0.00%
0 / 110
0.00% covered (danger)
0.00%
0 / 9
4556
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 1
210
 is_mobile
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 is_cloudflare
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
30
 is_ios
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get_device
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 get_page_type
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
90
 get_page_type_ipw
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
182
 is_static_home
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 should_show
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
342
1<?php
2/**
3 * WordAds Param Class file.
4 *
5 * @package automattic/jetpack
6 */
7
8use Automattic\Jetpack\Status;
9
10if ( ! defined( 'ABSPATH' ) ) {
11    exit( 0 );
12}
13
14/**
15 * Class WordAds_Params
16 *
17 * Sets parameters for WordAds.
18 */
19class WordAds_Params {
20    /**
21     * WordAds options
22     *
23     * @var array
24     */
25    public $options;
26
27    /**
28     * Current URL
29     *
30     * @access public
31     * @var string
32     */
33    public $url;
34
35    /**
36     * Is this site served by CloudFlare?
37     *
38     * @access public
39     * @var bool
40     */
41    public $cloudflare;
42
43    /**
44     * Jetpack Blog ID
45     *
46     * @var mixed
47     */
48    public $blog_id;
49
50    /**
51     * Determine if the current User Agent is a mobile device
52     *
53     * @var bool
54     */
55    public $mobile_device;
56
57    /**
58     * WordAds targeting tags
59     *
60     * @var array
61     */
62    public $targeting_tags;
63
64    /**
65     * Type of page that is being loaded
66     *
67     * @var string
68     */
69    public $page_type;
70
71    /**
72     * Page type code for IPW config
73     *
74     * @var int
75     */
76    public $page_type_ipw;
77
78    /**
79     * Is this an AMP request?
80     *
81     * @var bool
82     */
83    public $is_amp;
84
85    /**
86     * Setup parameters for serving the ads
87     *
88     * @since 4.5.0
89     */
90    public function __construct() {
91        // WordAds setting => default.
92        $settings = array(
93            'wordads_approved'                     => false,
94            'wordads_active'                       => false,
95            'wordads_house'                        => true,
96            'wordads_unsafe'                       => false,
97            'enable_header_ad'                     => true,
98            'wordads_second_belowpost'             => true,
99            'wordads_inline_enabled'               => true,
100            'wordads_bottom_sticky_enabled'        => false,
101            'wordads_sidebar_sticky_right_enabled' => false,
102            'wordads_display_front_page'           => true,
103            'wordads_display_post'                 => true,
104            'wordads_display_page'                 => true,
105            'wordads_display_archive'              => true,
106            'wordads_custom_adstxt'                => '',
107            'wordads_custom_adstxt_enabled'        => false,
108            'wordads_ccpa_enabled'                 => false,
109            'wordads_ccpa_privacy_policy_url'      => get_option( 'wp_page_for_privacy_policy' ) ? get_permalink( (int) get_option( 'wp_page_for_privacy_policy' ) ) : '',
110            'wordads_cmp_enabled'                  => false,
111        );
112
113        // Grab settings, or set as default if it doesn't exist.
114        $this->options = array();
115
116        foreach ( $settings as $setting => $default ) {
117            $option = get_option( $setting, null );
118
119            if ( $option === null ) {
120
121                // Handle retroactively setting wordads_custom_adstxt_enabled to true if custom ads.txt content is already entered.
122                if ( 'wordads_custom_adstxt_enabled' === $setting ) {
123                    $default = get_option( 'wordads_custom_adstxt' ) !== '';
124                }
125
126                // Convert boolean options to string first to work around update_option not setting the option if the value is false.
127                // This sets the option to either '1' if true or '' if false.
128                update_option( $setting, (string) $default, true );
129
130                $option = $default;
131            }
132
133            $this->options[ $setting ] = is_bool( $default ) ? (bool) $option : $option;
134        }
135
136        $this->url = esc_url_raw( ( is_ssl() ? 'https' : 'http' ) . '://' . ( isset( $_SERVER['HTTP_HOST'] ) ? wp_unslash( $_SERVER['HTTP_HOST'] ) : 'localhost' ) . ( isset( $_SERVER['REQUEST_URI'] ) ? wp_unslash( $_SERVER['REQUEST_URI'] ) : '' ) );
137        if ( str_contains( $this->url, '?' ) && ! isset( $_GET['p'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
138            $this->url = substr( $this->url, 0, strpos( $this->url, '?' ) );
139        }
140
141        $this->cloudflare     = self::is_cloudflare();
142        $this->blog_id        = Jetpack::get_option( 'id', 0 );
143        $this->mobile_device  = jetpack_is_mobile( 'any', true );
144        $this->targeting_tags = array(
145            'WordAds' => 1,
146            'BlogId'  => ( new Status() )->is_offline_mode() ? 0 : Jetpack_Options::get_option( 'id' ),
147            'Domain'  => esc_js( wp_parse_url( home_url(), PHP_URL_HOST ) ),
148            'PageURL' => esc_js( $this->url ),
149            'LangId'  => str_contains( get_bloginfo( 'language' ), 'en' ) ? 1 : 0, // TODO something else?
150            'AdSafe'  => 1, // TODO.
151        );
152        $this->is_amp         = function_exists( 'amp_is_request' ) && amp_is_request();
153    }
154
155    /**
156     * Is this a mobile device?
157     *
158     * @return boolean true if the user is browsing on a mobile device (iPad not included)
159     *
160     * @since 4.5.0
161     */
162    public function is_mobile() {
163        return ! empty( $this->mobile_device );
164    }
165
166    /**
167     * Is this site served by CloudFlare?
168     *
169     * @return boolean true if site is being served via CloudFlare
170     *
171     * @since 4.5.0
172     */
173    public static function is_cloudflare() {
174        if (
175            defined( 'WORDADS_CLOUDFLARE' )
176            || isset( $_SERVER['HTTP_CF_CONNECTING_IP'] )
177            || isset( $_SERVER['HTTP_CF_IPCOUNTRY'] )
178            || isset( $_SERVER['HTTP_CF_VISITOR'] )
179        ) {
180            return true;
181        }
182
183        return false;
184    }
185
186    /**
187     * Is this an iOS device?
188     *
189     * @return boolean true if user is browsing in iOS device
190     *
191     * @since 4.5.0
192     */
193    public function is_ios() {
194        return in_array( $this->get_device(), array( 'ipad', 'iphone', 'ipod' ), true );
195    }
196
197    /**
198     * Returns the user's device (see user-agent.php) or 'desktop'
199     *
200     * @return string user device
201     *
202     * @since 4.5.0
203     */
204    public function get_device() {
205        global $agent_info;
206
207        if ( ! empty( $this->mobile_device ) ) {
208            return $this->mobile_device;
209        }
210
211        if ( $agent_info->is_ipad() ) {
212            return 'ipad';
213        }
214
215        return 'desktop';
216    }
217
218    /**
219     * Get page type.
220     *
221     * @return string The type of page that is being loaded
222     *
223     * @since 4.5.0
224     */
225    public function get_page_type() {
226        if ( ! empty( $this->page_type ) ) {
227            return $this->page_type;
228        }
229
230        if ( self::is_static_home() ) {
231            $this->page_type = 'static_home';
232        } elseif ( is_home() ) {
233            $this->page_type = 'home';
234        } elseif ( is_page() ) {
235            $this->page_type = 'page';
236        } elseif ( is_single() ) {
237            $this->page_type = 'post';
238        } elseif ( is_search() ) {
239            $this->page_type = 'search';
240        } elseif ( is_category() ) {
241            $this->page_type = 'category';
242        } elseif ( is_archive() ) {
243            $this->page_type = 'archive';
244        } else {
245            $this->page_type = 'wtf';
246        }
247
248        return $this->page_type;
249    }
250
251    /**
252     * Get IPW code.
253     *
254     * @return int The page type code for ipw config
255     *
256     * @since 5.6.0
257     */
258    public function get_page_type_ipw() {
259        if ( ! empty( $this->page_type_ipw ) ) {
260            return $this->page_type_ipw;
261        }
262
263        $page_type_ipw = 6;
264        if ( self::is_static_home() || is_home() || is_front_page() ) {
265            $page_type_ipw = 0;
266        } elseif ( is_page() ) {
267            $page_type_ipw = 2;
268        } elseif ( is_singular() ) {
269            $page_type_ipw = 1;
270        } elseif ( is_search() ) {
271            $page_type_ipw = 4;
272        } elseif ( is_category() || is_tag() || is_archive() || is_author() ) {
273            $page_type_ipw = 3;
274        } elseif ( is_404() ) {
275            $page_type_ipw = 5;
276        }
277
278        $this->page_type_ipw = $page_type_ipw;
279        return $page_type_ipw;
280    }
281
282    /**
283     * Returns true if page is static home
284     *
285     * @return boolean true if page is static home
286     *
287     * @since 4.5.0
288     */
289    public static function is_static_home() {
290        return is_front_page() &&
291            'page' === get_option( 'show_on_front' ) &&
292            get_option( 'page_on_front' );
293    }
294
295    /**
296     * Logic for if we should show an ad
297     *
298     * @since 4.5.0
299     */
300    public function should_show() {
301        global $wp_query;
302        if ( ( is_front_page() || is_home() ) && ! $this->options['wordads_display_front_page'] ) {
303            return false;
304        }
305
306        if ( is_single() && ! $this->options['wordads_display_post'] ) {
307            return false;
308        }
309
310        if ( is_page() && ! $this->options['wordads_display_page'] ) {
311            return false;
312        }
313
314        if ( ( is_archive() || is_search() ) && ! $this->options['wordads_display_archive'] ) {
315            return false;
316        }
317
318        if ( is_single() || ( is_page() && ! is_home() ) ) {
319            return true;
320        }
321
322        // TODO this would be a good place for allowing the user to specify.
323        if ( ( is_home() || is_archive() || is_search() ) && 0 === $wp_query->current_post ) {
324            return true;
325        }
326
327        return false;
328    }
329}