Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
Monitor
0.00% covered (danger)
0.00%
0 / 42
0.00% covered (danger)
0.00%
0 / 8
650
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 initialize
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 ensure_enabled
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 match_request_filter
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
72
 save
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
42
 key
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 is_enabled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 get_filter
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3namespace Automattic\Jetpack_Inspect;
4
5use Automattic\Jetpack\Packages\Async_Option\Async_Option;
6use Automattic\Jetpack_Inspect\Monitor\Observable;
7
8/**
9 * The Monitor class.
10 */
11class Monitor {
12
13    /**
14     * The observable object.
15     *
16     * @var Observable
17     */
18    protected $observer;
19
20    /**
21     * The option name.
22     *
23     * @var String
24     */
25    protected $name;
26
27    /**
28     * Whether to bypass the filter.
29     *
30     * @var Boolean
31     * */
32    protected $bypass_filter = false;
33
34    /**
35     * The async option object.
36     *
37     * @var Async_Option
38     */
39    protected $option;
40
41    /**
42     * Creates a Monitor object.
43     *
44     * @param String     $name the option name.
45     * @param Observable $observable the object to attach hooks to.
46     */
47    public function __construct( $name, $observable ) {
48        $this->name     = $name;
49        $this->observer = $observable;
50        $this->option   = jetpack_inspect_option( $name );
51    }
52
53    /**
54     * Initializes the object.
55     */
56    public function initialize() {
57
58        if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
59            return false;
60        }
61
62        if ( $this->is_enabled() ) {
63            $this->observer->attach_hooks();
64        }
65
66        add_action( 'shutdown', array( $this, 'save' ) );
67    }
68
69    /**
70     * Ensures that the hooks are attached.
71     */
72    public function ensure_enabled() {
73        if ( $this->is_enabled() ) {
74            return;
75        }
76        $this->observer->attach_hooks();
77        add_action( 'shutdown', array( $this, 'log' ) );
78    }
79
80    /**
81     * Returns true whether the request url matches the filter.
82     *
83     * @param String $url the request URL.
84     */
85    protected function match_request_filter( $url ) {
86        if ( $this->bypass_filter ) {
87            return true;
88        }
89
90        $filter = $this->get_filter();
91        if ( ! $filter ) {
92            return true;
93        }
94
95        // https://example.com/?foo=bar will match "*example[s].com*.
96        if ( str_contains( $filter, '*' ) || ( str_contains( $filter, '[' ) && str_contains( $filter, ']' ) ) ) {
97            return fnmatch( $filter, $url );
98        }
99
100        // https://example.com/?foo=bar will match "https://example.com/?foo=bar".
101        if ( $filter[0] === $filter[ strlen( $filter ) - 1 ] && $filter[0] === '"' ) {
102            $filter = substr( $filter, 1, - 1 );
103            return $filter === $url;
104        }
105
106        // https://example.com/?foo=bar will match example.com.
107        return str_contains( $url, $filter );
108    }
109
110    /**
111     * Saves the log data.
112     */
113    public function save() {
114
115        $log_data = $this->observer->get();
116        if ( ! $log_data ) {
117            return;
118        }
119
120        foreach ( $log_data as $data ) {
121
122            if ( empty( $data ) || ! $this->match_request_filter( $data['url'] ) ) {
123                continue;
124            }
125
126            // @TODO: Create a Log object. This will do for now.
127            $url = $data['url'];
128            unset( $data['url'] );
129
130            $log_name = $this->name;
131            if ( isset( $data['error'] ) ) {
132                $log_name = 'wp_error';
133            }
134
135            $log = array(
136                'url'     => $url,
137                $log_name => $data,
138            );
139
140            Log::insert( $url, $log );
141        }
142    }
143
144    /**
145     * Generate keys for wp options dynamically
146     *   Example keys:
147     *      * observer_incoming
148     *      * observer_outgoing
149     *
150     * @param String $name option name.
151     */
152    private function key( $name ) {
153        return "{$this->name}_{$name}";
154    }
155
156    /**
157     * Returns the Monitor status.
158     */
159    public function is_enabled() {
160        return jetpack_inspect_get_option( 'monitor_status' ) && $this->option->get()['enabled'];
161    }
162
163    /**
164     * Returns the currently set filter.
165     */
166    public function get_filter() {
167        return $this->option->get()['filter'];
168    }
169}