Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.30% covered (success)
96.30%
52 / 54
83.33% covered (warning)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
Options
96.30% covered (success)
96.30%
52 / 54
83.33% covered (warning)
83.33%
5 / 6
18
0.00% covered (danger)
0.00%
0 / 1
 get_options
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 get_option
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 set_option
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 set_options
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
5
 upgrade_options
77.78% covered (warning)
77.78%
7 / 9
0.00% covered (danger)
0.00%
0 / 1
5.27
 get_defaults
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Stats Options
4 *
5 * @package automattic/jetpack-stats
6 */
7
8namespace Automattic\Jetpack\Stats;
9
10use Jetpack_Options;
11
12/**
13 * Stats Options class.
14 */
15class Options {
16
17    /**
18     * Option name.
19     *
20     * @var string $option_name The 'stats' option name
21     */
22    const OPTION_NAME = 'stats_options';
23
24    /**
25     * Stats Options.
26     *
27     * @var array $options An array of associated Stats options (default empty)
28     */
29    protected static $options = array();
30
31    /**
32     * Stats Get Options.
33     *
34     * @return array
35     */
36    public static function get_options() {
37        // Make sure we only get options from the database once per connection.
38        if ( array() !== self::$options ) {
39            return self::$options;
40        }
41
42        self::$options = get_option( self::OPTION_NAME, array() );
43        self::$options = array_merge( self::get_defaults(), self::$options );
44
45        if ( self::$options['version'] < Main::STATS_VERSION ) {
46            self::upgrade_options( self::$options );
47        }
48
49        return self::$options;
50    }
51
52    /**
53     * Get Stats Option.
54     *
55     * @param string $option Option name.
56     * @return mixed|null
57     */
58    public static function get_option( $option ) {
59        if ( 'blog_id' === $option ) {
60            return Jetpack_Options::get_option( 'id' );
61        }
62
63        $options = self::get_options();
64
65        if ( isset( $options[ $option ] ) ) {
66            return $options[ $option ];
67        }
68
69        return null;
70    }
71
72    /**
73     * Stats Set Option.
74     *
75     * @param string $option The option name.
76     * @param mixed  $value The option Value.
77     * @return bool
78     */
79    public static function set_option( $option, $value ) {
80        $options = self::get_options();
81
82        $options[ $option ] = $value;
83
84        return self::set_options( $options );
85    }
86
87    /**
88     * Stats Set Options.
89     *
90     * @access public
91     * @param array $options Options.
92     * @return bool
93     */
94    public static function set_options( $options ) {
95        if ( ! is_array( $options ) ) {
96            return false;
97        }
98
99        $defaults       = self::get_defaults();
100        $stored_options = get_option( self::OPTION_NAME, array() );
101        $all_options    = array_merge( $defaults, $stored_options );
102        $options        = array_merge( $all_options, $options );
103
104        $allowed_options = array_keys( $defaults );
105        foreach ( $options as $option_name => $option_value ) {
106            if ( ! in_array( $option_name, $allowed_options, true ) ) {
107                unset( $options[ $option_name ] );
108            }
109        }
110
111        $options['blog_id'] = Jetpack_Options::get_option( 'id' );
112        $options['version'] = Main::STATS_VERSION;
113
114        $success = update_option( self::OPTION_NAME, $options );
115
116        if ( true === $success ) {
117            self::$options = $options;
118        }
119
120        return $success;
121    }
122
123    /**
124     * Stats Upgrade Options.
125     *
126     * Ideally this should be a protected method but keeping it public
127     * to maintain backwards compatibility with stats_upgrade_options.
128     *
129     * @access public
130     * @param array $options The stats options.
131     * @return array|bool
132     */
133    public static function upgrade_options( $options ) {
134        if ( isset( $options['reg_users'] ) ) {
135            if ( ! function_exists( 'get_editable_roles' ) ) {
136                require_once ABSPATH . 'wp-admin/includes/user.php';
137            }
138            if ( $options['reg_users'] ) {
139                $options['count_roles'] = array_keys( get_editable_roles() );
140            }
141            unset( $options['reg_users'] );
142        }
143
144        if ( false === self::set_options( $options ) ) {
145            return false;
146        }
147
148        return self::$options;
149    }
150
151    /**
152     * Default Stats related options.
153     *
154     * Exposed so consumers (e.g. the Abilities API surface) can introspect
155     * each option's default value and infer its type without redeclaring
156     * a parallel allow-list of bool/array fields.
157     *
158     * @return array
159     */
160    public static function get_defaults() {
161        return array(
162            'admin_bar'                => true,
163            'roles'                    => array( 'administrator' ),
164            'count_roles'              => array(),
165            'do_not_track'             => true, // @todo
166            'blog_id'                  => Jetpack_Options::get_option( 'id' ),
167            'version'                  => Main::STATS_VERSION,
168            'collapse_nudges'          => false,
169            'enable_odyssey_stats'     => true,
170            'odyssey_stats_changed_at' => 0,
171            'notices'                  => array(),
172            'views'                    => 0,
173        );
174    }
175}