PluginProbe
Stream – Activity Log & Audit Trail / 4.0.2
Stream – Activity Log & Audit Trail v4.0.2
4.4.0 4.3.0 4.2.2 4.2.1 trunk 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.1 3.1.1 3.10.0 3.2.0 3.2.1 3.2.2 3.2.3 All 50 releases
← All changes | classes/class-plugin.php +154 -52 3.0.04.0.2 View file →
@@ -1,14 +1,25 @@
1 1 <?php
2 +/**
3 + * Initializes plugin
4 + *
5 + * @package WP_Stream;
6 + */
7 +
2 8 namespace WP_Stream;
3 9
10 +/**
11 + * Class Plugin
12 + */
4 13 class Plugin {
5 14 /**
6 - * Plugin version number
15 + * Plugin version number.
7 16 *
17 + * TODO Maybe pass this as a constructor dependency?
18 + *
8 19 * @const string
9 20 */
10 - const VERSION = '3.0.0';
21 + const VERSION = '4.0.2';
11 22
12 23 /**
13 24 * WP-CLI command
14 25 *
@@ -16,33 +27,59 @@
16 27 */
17 28 const WP_CLI_COMMAND = 'stream';
18 29
19 30 /**
31 + * Holds and manages WordPress Admin configurations.
32 + *
20 33 * @var Admin
21 34 */
22 35 public $admin;
23 36
24 37 /**
38 + * Holds and manages alerts.
39 + *
40 + * @var Alerts
41 + */
42 + public $alerts;
43 +
44 + /**
45 + * Holds and manages alerts lists.
46 + *
47 + * @var Alerts_List
48 + */
49 + public $alerts_list;
50 +
51 + /**
52 + * Holds and manages connectors
53 + *
25 54 * @var Connectors
26 55 */
27 56 public $connectors;
28 57
29 58 /**
59 + * Holds and manages DB connections.
60 + *
30 61 * @var DB
31 62 */
32 63 public $db;
33 64
34 65 /**
66 + * Holds and manages records.
67 + *
35 68 * @var Log
36 69 */
37 70 public $log;
38 71
39 72 /**
73 + * Stores and manages WordPress settings.
74 + *
40 75 * @var Settings
41 76 */
42 77 public $settings;
43 78
44 79 /**
80 + * Process DB migrations.
81 + *
45 82 * @var Install
46 83 */
47 84 public $install;
48 85
@@ -53,8 +90,15 @@
53 90 */
54 91 public $locations = array();
55 92
56 93 /**
94 + * IP address for the current request to be associated with the log entry.
95 + *
96 + * @var null|false|string Valid IP address, null if not set, false if invalid.
97 + */
98 + protected $client_ip_address;
99 +
100 + /**
57 101 * Class constructor
58 102 */
59 103 public function __construct() {
60 104 $locate = $this->locate_plugin();
@@ -68,43 +112,61 @@
68 112 );
69 113
70 114 spl_autoload_register( array( $this, 'autoload' ) );
71 115
72 - // Load helper functions
116 + // Load helper functions.
73 117 require_once $this->locations['inc_dir'] . 'functions.php';
74 118
75 - // Load DB helper interface/class
76 - $driver = '\WP_Stream\DB';
77 - if ( class_exists( $driver ) ) {
78 - $this->db = new DB( $this );
119 + // Load DB helper interface/class.
120 + $driver_class = apply_filters( 'wp_stream_db_driver', '\WP_Stream\DB_Driver_WPDB' );
121 + $driver = null;
122 +
123 + if ( class_exists( $driver_class ) ) {
124 + $driver = new $driver_class();
125 + $this->db = new DB( $driver );
79 126 }
80 127
128 + $error = false;
81 129 if ( ! $this->db ) {
130 + $error = esc_html__( 'Stream: Could not load chosen DB driver.', 'stream' );
131 + } elseif ( ! $driver instanceof DB_Driver ) {
132 + $error = esc_html__( 'Stream: DB driver must implement DB Driver interface.', 'stream' );
133 + }
134 +
135 + if ( $error ) {
82 136 wp_die(
83 - esc_html__( 'Stream: Could not load chosen DB driver.', 'stream' ),
137 + esc_html( $error ),
84 138 esc_html__( 'Stream DB Error', 'stream' )
85 139 );
86 140 }
87 141
88 - // Load languages
142 + // Load languages.
89 143 add_action( 'plugins_loaded', array( $this, 'i18n' ) );
90 144
91 - // Load logger class
145 + // Load logger class.
92 146 $this->log = apply_filters( 'wp_stream_log_handler', new Log( $this ) );
93 147
94 - // Load settings and connectors after widgets_init and before the default init priority
148 + // Set the IP address for the current request.
149 + $this->client_ip_address = wp_stream_filter_input( INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP );
150 +
151 + // Load settings and connectors after widgets_init and before the default init priority.
95 152 add_action( 'init', array( $this, 'init' ), 9 );
96 153
97 - // Add frontend indicator
154 + // Add frontend indicator.
98 155 add_action( 'wp_head', array( $this, 'frontend_indicator' ) );
99 156
100 - // Load admin area classes
101 - if ( is_admin() || ( defined( 'WP_STREAM_DEV_DEBUG' ) && WP_STREAM_DEV_DEBUG ) ) {
157 + // Change DB driver after plugin loaded if any add-ons want to replace.
158 + add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ), 20 );
159 +
160 + // Load admin area classes.
161 + if ( is_admin() || ( defined( 'WP_STREAM_DEV_DEBUG' ) && WP_STREAM_DEV_DEBUG ) || ( defined( 'WP_CLI' ) && WP_CLI ) ) {
102 162 $this->admin = new Admin( $this );
103 - $this->install = new Install( $this );
163 + $this->install = $driver->setup_storage( $this );
164 + } elseif ( defined( 'DOING_CRON' ) && DOING_CRON ) {
165 + $this->admin = new Admin( $this, $driver );
104 166 }
105 167
106 - // Load WP-CLI command
168 + // Load WP-CLI command.
107 169 if ( defined( 'WP_CLI' ) && WP_CLI ) {
108 170 \WP_CLI::add_command( self::WP_CLI_COMMAND, 'WP_Stream\CLI' );
109 171 }
110 172 }
@@ -111,12 +173,12 @@
111 173
112 174 /**
113 175 * Autoloader for classes
114 176 *
115 - * @param string $class
177 + * @param string $class_name Fully qualified classname to be loaded.
116 178 */
117 - function autoload( $class ) {
118 - if ( ! preg_match( '/^(?P<namespace>.+)\\\\(?P<autoload>[^\\\\]+)$/', $class, $matches ) ) {
179 + public function autoload( $class_name ) {
180 + if ( ! preg_match( '/^(?P<namespace>.+)\\\\(?P<autoload>[^\\\\]+)$/', $class_name, $matches ) ) {
119 181 return;
120 182 }
121 183
122 184 static $reflection;
@@ -146,16 +208,18 @@
146 208 public function i18n() {
147 209 load_plugin_textdomain( 'stream', false, dirname( $this->locations['plugin'] ) . '/languages/' );
148 210 }
149 211
150 - /*
151 - * Load Settings and Connectors
212 + /**
213 + * Load Settings, Notifications, and Connectors
152 214 *
153 215 * @action init
154 216 */
155 217 public function init() {
156 - $this->settings = new Settings( $this );
157 - $this->connectors = new Connectors( $this );
218 + $this->settings = new Settings( $this );
219 + $this->connectors = new Connectors( $this );
220 + $this->alerts = new Alerts( $this );
221 + $this->alerts_list = new Alerts_List( $this );
158 222 }
159 223
160 224 /**
161 225 * Displays an HTML comment in the frontend head to indicate that Stream is activated,
@@ -165,9 +229,10 @@
165 229 *
166 230 * @return string|void An HTML comment, or nothing if the value is filtered out.
167 231 */
168 232 public function frontend_indicator() {
169 - $comment = sprintf( 'Stream WordPress user activity plugin v%s', esc_html( $this->get_version() ) ); // Localization not needed
233 + /* translators: Localization not needed */
234 + $comment = sprintf( 'Stream WordPress user activity plugin v%s', esc_html( $this->get_version() ) );
170 235
171 236 /**
172 237 * Filter allows the HTML output of the frontend indicator comment
173 238 * to be altered or removed, if desired.
@@ -176,9 +241,9 @@
176 241 */
177 242 $comment = apply_filters( 'wp_stream_frontend_indicator', $comment );
178 243
179 244 if ( ! empty( $comment ) ) {
180 - echo sprintf( "<!-- %s -->\n", esc_html( $comment ) ); // xss ok
245 + printf( "<!-- %s -->\n", esc_html( $comment ) );
181 246 }
182 247 }
183 248
184 249 /**
@@ -184,51 +249,88 @@
184 249 /**
185 250 * Version of plugin_dir_url() which works for plugins installed in the plugins directory,
186 251 * and for plugins bundled with themes.
187 252 *
188 - * @throws \Exception
189 - *
190 253 * @return array
191 254 */
192 255 private function locate_plugin() {
193 - $reflection = new \ReflectionObject( $this );
194 - $file_name = $reflection->getFileName();
256 + $dir_url = trailingslashit( plugins_url( '', __DIR__ ) );
257 + $dir_path = plugin_dir_path( __DIR__ );
258 + $dir_basename = basename( $dir_path );
259 + $plugin_basename = trailingslashit( $dir_basename ) . $dir_basename . '.php';
195 260
196 - if ( '/' !== \DIRECTORY_SEPARATOR ) {
197 - $file_name = str_replace( \DIRECTORY_SEPARATOR, '/', $file_name ); // Windows compat
261 + return compact( 'dir_url', 'dir_path', 'dir_basename', 'plugin_basename' );
262 + }
263 +
264 + /**
265 + * Getter for the version number.
266 + *
267 + * @return string
268 + */
269 + public function get_version() {
270 + return self::VERSION;
271 + }
272 +
273 + /**
274 + * Change plugin database driver in case driver plugin loaded after stream
275 + */
276 + public function plugins_loaded() {
277 + // Load DB helper interface/class.
278 + $driver_class = apply_filters( 'wp_stream_db_driver', '\WP_Stream\DB_Driver_WPDB' );
279 +
280 + if ( class_exists( $driver_class ) ) {
281 + $driver = new $driver_class();
282 + $this->db = new DB( $driver );
198 283 }
284 + }
199 285
200 - $plugin_dir = preg_replace( '#(.*plugins[^/]*/[^/]+)(/.*)?#', '$1', $file_name, 1, $count );
286 + /**
287 + * Returns true if Stream is network activated, otherwise false
288 + *
289 + * @return bool
290 + */
291 + public function is_network_activated() {
201 292
202 - if ( 0 === $count ) {
203 - throw new \Exception( "Class not located within a directory tree containing 'plugins': $file_name" );
293 + $is_network_activated = false;
294 +
295 + if ( $this->is_mustuse() ) {
296 + $is_network_activated = true;
297 + } else {
298 + if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
299 + require_once ABSPATH . '/wp-admin/includes/plugin.php';
300 + }
301 + $is_network_activated = is_plugin_active_for_network( $this->locations['plugin'] );
204 302 }
205 303
206 - // Make sure that we can reliably get the relative path inside of the content directory
207 - $content_dir = trailingslashit( WP_CONTENT_DIR );
304 + /**
305 + * Filter allows the network activated detection to be overridden.
306 + *
307 + * @param string $is_network_activated Whether the plugin is network activated.
308 + * @param WP_Stream\Plugin $plugin The stream plugin object.
309 + */
310 + return apply_filters( 'wp_stream_is_network_activated', $is_network_activated, $this );
311 + }
208 312
209 - if ( '/' !== \DIRECTORY_SEPARATOR ) {
210 - $content_dir = str_replace( \DIRECTORY_SEPARATOR, '/', $content_dir ); // Windows compat
211 - }
313 + /**
314 + * Returns true if Stream is a must-use plugin, otherwise false
315 + *
316 + * @return bool
317 + */
318 + public function is_mustuse() {
319 + $stream_php = trailingslashit( WPMU_PLUGIN_DIR ) . $this->locations['plugin'];
212 320
213 - if ( 0 !== strpos( $plugin_dir, $content_dir ) ) {
214 - throw new \Exception( 'Plugin dir is not inside of WP_CONTENT_DIR' );
321 + if ( file_exists( $stream_php ) && class_exists( 'WP_Stream\Plugin' ) ) {
322 + return true;
215 323 }
216 324
217 - $content_sub_path = substr( $plugin_dir, strlen( $content_dir ) );
218 - $dir_url = content_url( trailingslashit( $content_sub_path ) );
219 - $dir_path = trailingslashit( $plugin_dir );
220 - $dir_basename = basename( $plugin_dir );
221 - $plugin_basename = trailingslashit( $dir_basename ) . $dir_basename. '.php';
222 -
223 - return compact( 'dir_url', 'dir_path', 'dir_basename', 'plugin_basename' );
325 + return false;
224 326 }
225 327
226 328 /**
227 - * Getter for the version number.
329 + * Get the IP address for the current request.
228 330 *
229 - * @return string
331 + * @return false|null|string Valid IP address, null if not set, false if invalid.
230 332 */
231 - public function get_version() {
232 - return self::VERSION;
333 + public function get_client_ip_address() {
334 + return apply_filters( 'wp_stream_client_ip_address', $this->client_ip_address );
233 335 }
234 336 }