Options   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Test Coverage

Coverage 77.91%

Importance

Changes 0
Metric Value
eloc 84
dl 0
loc 229
ccs 67
cts 86
cp 0.7791
rs 10
c 0
b 0
f 0
wmc 25

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
A get() 0 36 4
A get_all_options() 0 38 6
A add() 0 35 5
A delete() 0 19 3
B update() 0 38 6
1
<?php
2
3
/**
4
 * YOURLS Options
5
 *
6
 * Note to plugin authors: you most likely SHOULD NOT use directly methods and properties of this class. Use instead
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 116 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
7
 * function wrappers (eg don't use $ydb->option, or $ydb->get(), use yourls_*_options() functions instead).
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 107 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
8
 *
9
 * Note to devs: this class internally uses function wrappers eg yourls_*_options() instead of direct methods, to
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 113 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
10
 * comply to any filter set in the function wrappers (eg $this->update() uses yourls_get_option()).
11
 * Maybe in the future this will look as a dumb idea?
12
 * The alternative would be to move return filters from function wrappers to here, but I think this will make things
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 116 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
13
 * less readable for users.
14
 *
15
 * @since 1.7.3
16
 */
17
18
namespace YOURLS\Database;
19
20
use YOURLS\Database\YDB;
21
use PDOException;
22
23
class Options {
24
25
    /**
26
     * Hold a copy of the all mighty $ydb global
27
     *
28
     * @var \YOURLS\Database\YDB
29
     */
30
    protected $ydb;
31
32 30
    public function __construct(YDB $ydb) {
33 30
        $this->ydb = $ydb;
34 30
    }
35
36
    /**
37
     * Read all options from DB at once, return bool
38
     *
39
     * @since  1.7.3
40
     * @see yourls_get_all_options()
41
     * @return bool    True on success, false on failure (eg table missing or empty)
42
     */
43
    public function get_all_options() {
44
        // Get option values from DB
45
        $table = YOURLS_DB_TABLE_OPTIONS;
46
        $sql = "SELECT option_name, option_value FROM $table WHERE 1=1";
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $table instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
47
48
        try {
49
            $options = (array) $this->ydb->fetchPairs($sql);
50
51
        } catch ( PDOException $e ) {
52
53
            // We could not fetch value from the table. Let's check if the option table exists
54
            try {
55
                $check = $this->ydb->fetchAffected(sprintf("SHOW TABLES LIKE '%s'", $table));
56
                // Table doesn't exist
57
                if ($check ==0) {
0 ignored issues
show
Coding Style introduced by
Operator == prohibited; use === instead
Loading history...
58
                    return false;
59
                }
60
61
            // Error at this point means the database isn't readable
62
            } catch ( PDOException $e ) {
63
                $this->ydb->dead_or_error($e);
64
            }
65
66
        }
67
68
69
        // Unlikely scenario, but who knows: table exists, but is empty
70
        if (empty($options)) {
71
            return false;
72
        }
73
74
        foreach ($options as $name => $value) {
75
            $this->ydb->set_option($name, yourls_maybe_unserialize($value));
76
        }
77
78
        yourls_apply_filter('get_all_options', 'deprecated');
79
80
        return true;
81
    }
82
83
    /**
84
     * Get option value from DB (or from cache if available). Return value or $default if not found
85
     *
86
     * @since  1.7.3
87
     * @see yourls_get_option()
88
     * @param  string $name     Option name
89
     * @param  string $default  Value to return if option doesn't exist
90
     * @return mixed            Value set for the option
91
     */
92 30
    public function get($name, $default) {
93 30
        $name = trim((string)$name);
94 30
        if (empty($name)) {
95 6
            return $default;
96
        }
97
98
        // Check if option value is cached already
99 24
        if($this->ydb->has_option($name)) {
100 24
            return $this->ydb->get_option($name);
101
        }
102
103
        // Get option value from DB
104 2
        $table = YOURLS_DB_TABLE_OPTIONS;
105 2
        $sql = "SELECT option_value FROM $table WHERE option_name = :option_name LIMIT 1";
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $table instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
106 2
        $bind = array('option_name' => $name);
107
108
        // Use fechOne() to get array('option_value'=>$value), or false if not found.
109
        // This way, we can effectively store false as an option value, and not confuse with false as the default return value
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
110 2
        $value = $this->ydb->fetchOne($sql, $bind);
111 2
        if($value !== false) {
112
            $value = yourls_maybe_unserialize( $value['option_value'] );
113
            // Cache option value to save a DB query if needed later
114
            $this->ydb->set_option($name, $value);
115
        } else {
116 2
            $value = $default;
117
        }
118
119
        /**
0 ignored issues
show
Coding Style introduced by
Block comments must be started with /*
Loading history...
120
         * We don't cache value if option is not set, to make a difference between "not found: returning false"
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 111 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
121
         * and "found, and value is false".
122
         * This way, we can:
123
         * $check = yourls_get_option('doesnt_exist'); // false
124
         * yourls_add_option('doesnt_exist', 'value'); // will work, because check on has_option() will return false
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 116 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
125
         */
126
127 2
        return $value;
128
    }
129
130
    /**
131
     * Update (add if doesn't exist) an option to DB
132
     *
133
     * @since  1.7.3
134
     * @see yourls_update_option()
135
     * @param  string $name      Option name. Expected to not be SQL-escaped.
136
     * @param  mixed  $newvalue  Option value.
137
     * @return bool              False if value was not updated, true otherwise.
138
     */
139 28
    public function update($name, $newvalue) {
140 28
        $name = trim((string)$name);
141 28
        if (empty($name)) {
142 6
            return false;
143
        }
144
145
        // Use clone to break object refs -- see commit 09b989d375bac65e692277f61a84fede2fb04ae3
146 22
        if (is_object($newvalue)) {
147 13
            $newvalue = clone $newvalue;
148
        }
149
150 22
        $oldvalue = yourls_get_option($name);
151
152
        // If the new and old values are the same, no need to update.
153 22
        if ($newvalue === $oldvalue) {
154 3
            return false;
155
        }
156
157
        // If this is a new option, just add it
158 22
        if (false === $oldvalue) {
159 2
            return $this->add($name, $newvalue);
160
        }
161
162 21
        $_newvalue = yourls_maybe_serialize($newvalue);
163 21
        $table = YOURLS_DB_TABLE_OPTIONS;
164 21
        $sql  = "UPDATE $table SET option_value = :value WHERE option_name = :name";
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $table instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
165 21
        $bind = array('name' => $name, 'value' => $_newvalue);
0 ignored issues
show
Coding Style introduced by
Arrays with multiple values should not be declared on a single line.
Loading history...
166 21
        $do   = $this->ydb->fetchAffected($sql, $bind);
167
168 21
        if($do !== 1) {
169
            // Something went wrong :(
170 2
            return false;
171
        }
172
173
        // Cache option value to save a DB query if needed later
174 19
        $this->ydb->set_option($name, $newvalue);
175 19
    	yourls_do_action( 'update_option', $name, $oldvalue, $newvalue );
176 19
        return true;
177
    }
178
179
    /**
180
     * Add an option to the DB
181
     *
182
     * @since  1.7.3
183
     * @see yourls_add_option()
184
     * @param  string $name   Name of option to add. Expected to not be SQL-escaped.
185
     * @param  mixed  $value  Option value. Must be serializable if non-scalar. Expected to not be SQL-escaped.
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 100 characters; contains 111 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
186
     * @return bool           False if option was not added (eg already exists), true otherwise.
187
     */
188 11
    public function add($name, $value) {
189 11
        $name = trim((string)$name);
190 11
        if (empty($name)) {
191 6
            return false;
192
        }
193
194
        // Use clone to break object refs -- see commit 09b989d375bac65e692277f61a84fede2fb04ae3
195 5
        if (is_object($value)) {
196 1
            $value = clone $value;
197
        }
198
199
        // Make sure the option doesn't already exist
200 5
        if ($this->ydb->has_option($name)) {
201 1
            return false;
202
        }
203
        // if (false !== yourls_get_option($name)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
204
            // return false;
205
        // }
206
207 5
        $table = YOURLS_DB_TABLE_OPTIONS;
208 5
        $_value = yourls_maybe_serialize($value);
209 5
        $sql  = "INSERT INTO $table (option_name, option_value) VALUES (:name, :value)";
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $table instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
210 5
        $bind = array('name' => $name, 'value' => $_value);
0 ignored issues
show
Coding Style introduced by
Arrays with multiple values should not be declared on a single line.
Loading history...
211 5
        $do   = $this->ydb->fetchAffected($sql, $bind);
212
213 5
        if($do !== 1) {
214
            // Something went wrong :(
215
            return false;
216
        }
217
218
        // Cache option value to save a DB query if needed later
219 5
        $this->ydb->set_option($name, $value);
220 5
        yourls_do_action('add_option', $name, $_value);
221
222 5
        return true;
223
    }
224
225
    /**
226
     * Delete option from DB
227
     *
228
     * @since  1.7.3
229
     * @see yourls_delete_option()
230
     * @param  string $name  Option name to delete. Expected to not be SQL-escaped.
231
     * @return bool          False if option was not deleted (eg not found), true otherwise.
232
     */
233 8
    public function delete($name) {
234 8
        $name = trim((string)$name);
235 8
        if (empty($name)) {
236 6
            return false;
237
        }
238
239 2
        $table = YOURLS_DB_TABLE_OPTIONS;
240 2
        $sql = "DELETE FROM $table WHERE option_name = :name";
0 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $table instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
241 2
        $bind = array('name' => $name);
242 2
        $do   = $this->ydb->fetchAffected($sql, $bind);
243
244 2
        if($do !== 1) {
245
            // Something went wrong :(
246 1
            return false;
247
        }
248
249 2
        yourls_do_action('delete_option', $name);
250 2
        $this->ydb->delete_option($name);
251 2
        return true;
252
    }
253
254
}
255