Issues (9)

src/RedirectionIOSettingsPage.php (3 issues)

1
<?php
2
3
namespace RedirectionIO\Client\Wordpress;
4
5
use RedirectionIO\Client\Sdk\Client;
6
use RedirectionIO\Client\Sdk\Command\MatchWithResponseCommand;
7
use RedirectionIO\Client\Sdk\Exception\AgentNotFoundException;
8
use RedirectionIO\Client\Sdk\HttpMessage\Request;
9
10
/**
11
 *  RedirectionIOSettingsPage class.
12
 *
13
 * This class is used to create a new page in the admin area
14
 * dedicated to redirection.io. It lets you configuring the plugin as you like.
15
 */
16
class RedirectionIOSettingsPage
17
{
18
    private $overrider;
19
20
    public function __construct()
21
    {
22
        $this->overrider = new WPCoreFunctionsOverrider();
23
24
        add_action('init', [$this, 'setTranslations']);
0 ignored issues
show
The call to RedirectionIO\Client\Wordpress\add_action() has too many arguments starting with 'init'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

24
        /** @scrutinizer ignore-call */ 
25
        add_action('init', [$this, 'setTranslations']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
25
        add_action('admin_menu', [$this, 'setUp']);
26
        add_action('admin_init', [$this, 'registerSettings']);
27
        add_action('admin_enqueue_scripts', [$this, 'registerAssets']);
28
    }
29
30
    public function setUp()
31
    {
32
        add_options_page('redirection.io', 'redirection.io', 'manage_options', 'redirectionio', [$this, 'outputContent']);
33
    }
34
35
    public function setTranslations()
36
    {
37
        load_plugin_textdomain('redirectionio', false, \dirname(plugin_basename(__FILE__)) . '/../languages');
38
    }
39
40
    public function outputContent()
41
    {
42
        if (!current_user_can('manage_options')) {
43
            wp_die(__('You do not have sufficient permissions to access this page.'));
44
        }
45
46
        $title = 'redirection.io';
47
        $intro =
48
            '<p>' .
49
                __('redirection.io let you track HTTP errors and setup useful HTTP redirections.', 'redirectionio') .
50
            '</p><p>' .
51
               sprintf(__('This plugin works in combination with <a href="%s">redirection.io</a>
52
                    and need an installed and configured agent on your server.
53
                    </br>
54
                    Before using it, please make sure that you have :', 'redirectionio'), esc_url('//redirection.io')) .
55
                '<ul>' .
56
                    '<li>' . sprintf(__('created a redirection.io account <a href="">here</a>', 'redirectionio'), esc_url('//redirection.io')) . '</li>' .
57
                    '<li>' . sprintf(__('followed the <a href="">installation guide</a> to setup a redirection.io agent on your server', 'redirectionio'), esc_url('//redirection.io')) . '</li>' .
58
                '</ul>' .
59
            '</p><p>' .
60
                __('Drop us an email to [email protected] if you need help or have any question.', 'redirectionio') .
61
            '</p><p>' .
62
                __('Note: in most cases, you only have one agent, so you only need to configure one connection.', 'redirectionio') .
63
            '</p>'
64
        ;
65
        $confirm = __('Are you sure ?', 'redirectionio');
66
67
        echo '
68
            <div class="wrap" id="redirectionio">
69
                <h1>' . $title . '</h1>
70
                <div>' . $intro . '</div>
71
                <form method="post" action="options.php">
72
        ';
73
74
        settings_fields('redirectionio-group');
75
        $this->overrider->doSettingsSections('redirectionio');
76
77
        submit_button();
78
79
        echo '
80
            </form></div>
81
            <script>
82
                var confirmStr = \'' . $confirm . '\';
83
            </script>
84
        ';
85
    }
86
87
    public function registerSettings()
88
    {
89
        register_setting(
90
            'redirectionio-group',
91
            'redirectionio',
92
            [$this, 'sanitizeInput']
93
        );
94
95
        $options = get_option('redirectionio');
0 ignored issues
show
The call to RedirectionIO\Client\Wordpress\get_option() has too many arguments starting with 'redirectionio'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

95
        $options = /** @scrutinizer ignore-call */ get_option('redirectionio');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
96
97
        // Add projectKey
98
        add_settings_section(
99
            'redirectionio-section-project-key',
100
            __('Project key', 'redirectionio'),
101
            [$this, 'printSection'],
102
            'redirectionio'
103
        );
104
105
        add_settings_field(
106
            'redirectionio-input-project-key',
107
            __('Project key', 'redirectionio'),
108
            [$this, 'printProjectKeyField'],
109
            'redirectionio',
110
            'redirectionio-section-project-key',
111
            $options['projectKey']
112
        );
113
114
        // Add connections
115
        foreach ($options['connections'] as $i => $option) {
116
            add_settings_section(
117
                'redirectionio-section-' . $i,
118
                sprintf(__('Connection #%s', 'redirectionio'), $i + 1),
119
                [$this, 'printSection'],
120
                'redirectionio'
121
            );
122
123
            foreach ($option as $key => $value) {
124
                switch ($key) {
125
                    case 'name':
126
                        $title = __('Name', 'redirectionio');
127
                        $required = false;
128
                        $description = __('[Optional] If you have multiple connections, you may find useful to name them for better readability.', 'redirectionio');
129
                        $placeholder = __('my-connection', 'redirectionio');
130
                        break;
131
                    case 'remote_socket':
132
                        $title = __('Agent address', 'redirectionio');
133
                        $required = true;
134
                        $description = __('[Required] Insert here your agent address. Internet Domain socket (AF_INET) and Unix Domain socket (AF_UNIX) are supported.<br/> Examples: tcp://192.168.1.1:20301, tcp://agent.my-website.com:10301, unix:///var/run/my-agent.sock', 'redirectionio');
135
                        $placeholder = 'tcp://192.168.1.1:20301';
136
                        break;
137
                    default:
138
                        $title = 'unknown';
139
                        $required = false;
140
                        $description = '';
141
                        $placeholder = '';
142
                }
143
144
                add_settings_field(
145
                    $i . '_' . $key,
146
                    $title . ($required ? '*' : ''),
147
                    [$this, 'printConnectionField'],
148
                    'redirectionio',
149
                    'redirectionio-section-' . $i,
150
                    [
151
                        'id' => $i,
152
                        'type' => $key,
153
                        'value' => $value,
154
                        'placeholder' => $placeholder,
155
                        'description' => $description,
156
                    ]
157
                );
158
            }
159
        }
160
161
        // Add doNotRedirectAdmin
162
        add_settings_section(
163
            'redirectionio-section-do-not-redirect-admin',
164
            __('Disable redirections for admin area', 'redirectionio'),
165
            [$this, 'printSection'],
166
            'redirectionio'
167
        );
168
169
        add_settings_field(
170
            'redirectionio-checkbox-do-not-redirect-admin',
171
            __("Yes, I wan't to disable it", 'redirectionio'),
172
            [$this, 'printDoNotRedirectAdminCheckbox'],
173
            'redirectionio',
174
            'redirectionio-section-do-not-redirect-admin',
175
            $options['doNotRedirectAdmin']
176
        );
177
    }
178
179
    public function sanitizeInput(array $input)
180
    {
181
        $newInput = [
182
            'projectKey' => $input['projectKey'],
183
            'doNotRedirectAdmin' => $input['doNotRedirectAdmin'],
184
        ];
185
186
        foreach ($input['connections'] as $i => $option) {
187
            foreach ($option as $key => $value) {
188
                $newInput['connections'][$i][$key] = sanitize_text_field($input['connections'][$i][$key]);
189
            }
190
        }
191
192
        return $newInput;
193
    }
194
195
    public function printSection()
196
    {
197
    }
198
199
    public function printProjectKeyField(string $projectKey)
200
    {
201
        $placeholder = __('my-project-key', 'redirectionio');
202
        echo "<input id='redirectionio_projectKey' name='redirectionio[projectKey]' type='text' size='100' value='$projectKey' placeholder='$placeholder' />";
203
    }
204
205
    public function printConnectionField(array $args)
206
    {
207
        $id = isset($args['id']) ? $args['id'] : '';
208
        $type = isset($args['type']) ? $args['type'] : '';
209
        $value = isset($args['value']) ? $args['value'] : '';
210
        $placeholder = isset($args['placeholder']) ? $args['placeholder'] : '';
211
        $description = isset($args['description']) ? $args['description'] : '';
212
213
        echo "<input id='redirectionio_{$id}_{$type}' name='redirectionio[connections][$id][$type]' size='40' type='text' value='$value' placeholder='$placeholder' />";
214
        echo "<p class='description' id='redirectionio_{$id}_{$type}_description'>$description</p>";
215
    }
216
217
    /**
218
     * @param bool $checked
219
     */
220
    public function printDoNotRedirectAdminCheckbox($checked)
221
    {
222
        echo '<input id="redirectionio_doNotRedirectAdmin" name="redirectionio[doNotRedirectAdmin]" type="checkbox" ' . ($checked ? 'checked' : '') . ' />';
223
    }
224
225
    public function registerAssets()
226
    {
227
        wp_enqueue_style('redirectionio', plugins_url('../assets/css/redirectionio.css', __FILE__));
228
        wp_enqueue_script('redirectionio', plugins_url('../assets/js/redirectionio.js', __FILE__), [], false, true);
229
    }
230
231
    /**
232
     * Return a connection (associative array with (`port` && `host`) || `remote_socket` keys).
233
     *
234
     * @param mixed $page
235
     * @param mixed $section
236
     */
237
    public static function getConnectionFromSection($page, $section)
238
    {
239
        global $wp_settings_fields;
240
241
        if (!isset($wp_settings_fields[$page][$section])) {
242
            return false;
243
        }
244
245
        foreach ((array) $wp_settings_fields[$page][$section] as $field) {
246
            if ($field['args']['type'] === 'remote_socket') {
247
                $remoteSocket = $field['args']['value'];
248
            }
249
        }
250
251
        return ['remote_socket' => $remoteSocket];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $remoteSocket does not seem to be defined for all execution paths leading up to this point.
Loading history...
252
    }
253
254
    /**
255
     * Test if a connection is currently working.
256
     *
257
     * @param mixed $connection array|bool(false)
258
     */
259
    public static function isWorkingConnection($connection)
260
    {
261
        if ($connection === false) {
262
            return false;
263
        }
264
265
        $client = new Client(
266
            'check-status-project-key',
267
            [
268
                'checkStatus' => $connection['remote_socket'],
269
            ],
270
            10000,
271
            true
272
        );
273
274
        try {
275
            $request = new Request('', '', '');
276
            $client->request(new MatchWithResponseCommand($request));
277
        } catch (AgentNotFoundException $e) {
278
            return false;
279
        }
280
281
        return true;
282
    }
283
}
284