Issues (24)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/class-rdn.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Remote Dashboard Notifications.
4
 *
5
 * @package   Remote Dashobard Notifications
6
 * @author    ThemeAvenue <[email protected]>
7
 * @license   GPL-2.0+
8
 * @link      http://themeavenue.net
9
 * @copyright 2013 ThemeAvenue
10
 */
11
12
class Remote_Notifications {
13
14
	/**
15
	 * Plugin version, used for cache-busting of style and script file references.
16
	 *""
17
	 * @since   1.0.0
18
	 *
19
	 * @var     string
20
	 */
21
	const VERSION = '1.3.0';
22
23
	/**
24
	 * Unique identifier for your plugin.
25
	 *
26
	 *
27
	 * The variable name is used as the text domain when internationalizing strings
28
	 * of text. Its value should match the Text Domain file header in the main
29
	 * plugin file.
30
	 *
31
	 * @since    1.0.0
32
	 *
33
	 * @var      string
34
	 */
35
	protected $plugin_slug = 'remote-notifications';
36
37
	/**
38
	 * Instance of this class.
39
	 *
40
	 * @since    1.0.0
41
	 *
42
	 * @var      object
43
	 */
44
	protected static $instance = null;
45
46
	/**
47
	 * Initialize the plugin by setting localization and loading public scripts
48
	 * and styles.
49
	 *
50
	 * @since     1.0.0
51
	 */
52
	public function __construct() {
53
54
		// Load plugin text domain
55
		add_action( 'init', array( $this, 'load_plugin_textdomain' ), 1 );
56
57
		// Register post type
58
		add_action( 'init', array( $this, 'register_notification_post_type' ) );
59
		add_filter( 'post_updated_messages', array( $this, 'updated_messages' ) );
60
61
		// Register taxonomies
62
		add_action( 'init', array( $this, 'register_channel' ), 10 );
63
		add_action( 'init', array( $this, 'register_post_type' ), 10 );
64
65
		// Add endpoint
66
		add_action( 'template_redirect', array( $this, 'endpoint' ) );
67
68
	}
69
70
	/**
71
	 * Return the plugin slug.
72
	 *
73
	 * @since    1.0.0
74
	 *
75
	 * @return    string Plugin slug variable.
76
	 */
77
	public function get_plugin_slug() {
78
		return $this->plugin_slug;
79
	}
80
81
	/**
82
	 * Return an instance of this class.
83
	 *
84
	 * @since     1.0.0
85
	 *
86
	 * @return    object    A single instance of this class.
87
	 */
88
	public static function get_instance() {
89
90
		// If the single instance hasn't been set, set it now.
91
		if ( null == self::$instance ) {
92
			self::$instance = new self;
93
		}
94
95
		return self::$instance;
96
	}
97
98
	/**
99
	 * Fired when the plugin is activated.
100
	 *
101
	 * @since    1.0.0
102
	 *
103
	 * @param    boolean    $network_wide    True if WPMU superadmin uses
104
	 *                                       "Network Activate" action, false if
105
	 *                                       WPMU is disabled or plugin is
106
	 *                                       activated on an individual blog.
107
	 */
108 View Code Duplication
	public static function activate( $network_wide ) {
109
110
		if ( function_exists( 'is_multisite' ) && is_multisite() ) {
111
112
			if ( $network_wide  ) {
113
114
				// Get all blog ids
115
				$blog_ids = self::get_blog_ids();
116
117
				foreach ( $blog_ids as $blog_id ) {
0 ignored issues
show
The expression $blog_ids of type array|false is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
118
119
					switch_to_blog( $blog_id );
120
					self::single_activate();
121
				}
122
123
				restore_current_blog();
124
125
			} else {
126
				self::single_activate();
127
			}
128
129
		} else {
130
			self::single_activate();
131
		}
132
133
	}
134
135
	/**
136
	 * Fired when the plugin is deactivated.
137
	 *
138
	 * @since    1.0.0
139
	 *
140
	 * @param    boolean    $network_wide    True if WPMU superadmin uses
141
	 *                                       "Network Deactivate" action, false if
142
	 *                                       WPMU is disabled or plugin is
143
	 *                                       deactivated on an individual blog.
144
	 */
145 View Code Duplication
	public static function deactivate( $network_wide ) {
146
147
		if ( function_exists( 'is_multisite' ) && is_multisite() ) {
148
149
			if ( $network_wide ) {
150
151
				// Get all blog ids
152
				$blog_ids = self::get_blog_ids();
153
154
				foreach ( $blog_ids as $blog_id ) {
0 ignored issues
show
The expression $blog_ids of type array|false is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
155
156
					switch_to_blog( $blog_id );
157
					self::single_deactivate();
158
159
				}
160
161
				restore_current_blog();
162
163
			} else {
164
				self::single_deactivate();
165
			}
166
167
		} else {
168
			self::single_deactivate();
169
		}
170
171
	}
172
173
	/**
174
	 * Fired when a new site is activated with a WPMU environment.
175
	 *
176
	 * @since    1.0.0
177
	 *
178
	 * @param    int    $blog_id    ID of the new blog.
179
	 */
180
	public function activate_new_site( $blog_id ) {
181
182
		if ( 1 !== did_action( 'wpmu_new_blog' ) ) {
183
			return;
184
		}
185
186
		switch_to_blog( $blog_id );
187
		self::single_activate();
188
		restore_current_blog();
189
190
	}
191
192
	/**
193
	 * Get all blog ids of blogs in the current network that are:
194
	 * - not archived
195
	 * - not spam
196
	 * - not deleted
197
	 *
198
	 * @since    1.0.0
199
	 *
200
	 * @return   array|false    The blog ids, false if no matches.
201
	 */
202
	private static function get_blog_ids() {
203
204
		global $wpdb;
205
206
		// get an array of blog ids
207
		$sql = "SELECT blog_id FROM $wpdb->blogs
208
			WHERE archived = '0' AND spam = '0'
209
			AND deleted = '0'";
210
211
		return $wpdb->get_col( $sql );
212
213
	}
214
215
	/**
216
	 * Fired for each blog when the plugin is activated.
217
	 *
218
	 * @since    1.0.0
219
	 */
220
	private static function single_activate() {
221
		flush_rewrite_rules();
222
	}
223
224
	/**
225
	 * Fired for each blog when the plugin is deactivated.
226
	 *
227
	 * @since    1.0.0
228
	 */
229
	private static function single_deactivate() {
230
		flush_rewrite_rules();
231
	}
232
233
	/**
234
	 * Load the plugin text domain for translation.
235
	 *
236
	 * @since    1.0.0
237
	 */
238
	public function load_plugin_textdomain() {
239
240
		$domain = $this->plugin_slug;
241
		$locale = apply_filters( 'plugin_locale', get_locale(), $domain );
242
243
		load_textdomain( $domain, RDN_PATH . 'languages/' . $domain . '-' . $locale . '.mo' );
244
		
245
	}
246
247
	/**
248
	 * Register and enqueue public-facing style sheet.
249
	 *
250
	 * @since    1.0.0
251
	 */
252
	public function enqueue_styles() {
253
		wp_enqueue_style( $this->plugin_slug . '-plugin-styles', plugins_url( 'assets/css/public.css', __FILE__ ), array(), self::VERSION );
254
	}
255
256
	/**
257
	 * Register and enqueues public-facing JavaScript files.
258
	 *
259
	 * @since    1.0.0
260
	 */
261
	public function enqueue_scripts() {
262
		wp_enqueue_script( $this->plugin_slug . '-plugin-script', plugins_url( 'assets/js/public.js', __FILE__ ), array( 'jquery' ), self::VERSION );
263
	}
264
265
	/**
266
	 * Create API endpoint inside the custom post type template
267
	 *
268
	 * @since 1.0.0
269
	 */
270
	public function endpoint() {
271
272
		global $wp_query;
273
274
		if( is_archive() && isset( $wp_query->query_vars['post_type'] ) && 'notification' == $wp_query->query_vars['post_type'] ) {
275
276
			$single = RDN_PATH . '/includes/archive-notification.php';
277
278
			if( file_exists( $single ) ) {
279
280
				include( $single );
281
				exit;
282
283
			}
284
285
		}
286
287
	}
288
289
	/**
290
	 * Register notification post type
291
	 *
292
	 * @since 1.0.0
293
	 */
294
	public function register_notification_post_type() {
295
296
		/* Set the default labels */
297
		$labels = array(
298
			'name'                  => _x( 'Notification', 'post type general name', 'remote-notifications' ),  
299
			'singular_name'         => _x( 'Notification', 'post type singular name', 'remote-notifications' ),  
300
			'add_new'               => __( 'Add New', 'remote-notifications' ),  
301
			'add_new_item'          => __( 'Add New Notification', 'remote-notifications' ),  
302
			'edit_item'             => __( 'Edit Notification', 'remote-notifications' ),  
303
			'new_item'              => __( 'New Notification', 'remote-notifications' ),  
304
			'all_items'             => __( 'All Notifications', 'remote-notifications' ),  
305
			'view_item'             => __( 'View Notification', 'remote-notifications' ),  
306
			'search_items'          => __( 'Search Notifications', 'remote-notifications' ),  
307
			'not_found'             => __( 'No Notification found', 'remote-notifications' ),  
308
			'not_found_in_trash'    => __( 'No Notification found in Trash', 'remote-notifications' ),   
309
			'parent_item_colon'     => '',
310
			'menu_icon' 			=> 'dashicons-format-chat',
311
			'menu_name'             => __( 'Notifications', 'remote-notifications' )
312
		);
313
314
		/* Post type settings */
315
		$args = array(
316
			'labels'             => $labels,
317
			'public'             => true,
318
			'publicly_queryable' => true,
319
			'show_ui'            => true,
320
			'show_in_menu'       => true,
321
			'query_var'          => true,
322
			'capability_type'    => 'post',
323
			'has_archive'        => true,
324
			'hierarchical'       => false,
325
			'menu_position'      => null,
326
			'supports'           => array( 'title', 'editor' )
327
		);
328
329
		register_post_type( 'notification', $args );
330
331
	}
332
333
	/**
334
	 * Custom updated messages
335
	 *
336
	 * @param array $messages Post types messages array
337
	 *
338
	 * @return array Messages array with our post type messages added
339
	 */
340
	function updated_messages( $messages ) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
341
342
		global $post;
343
344
		$post_type_object = get_post_type_object( 'notification' );
345
346
		$messages['notification'] = array(
347
			0  => '', // Unused. Messages start at index 1.
348
			1  => __( 'Notification updated.', 'remote-notifications' ),
349
			2  => __( 'Custom field updated.', 'remote-notifications' ),
350
			3  => __( 'Custom field deleted.', 'remote-notifications' ),
351
			4  => __( 'Notification updated.', 'remote-notifications' ),
352
			/* translators: %s: date and time of the revision */
353
			5  => isset( $_GET['revision'] ) ? sprintf( __( 'Notification restored to revision from %s', 'remote-notifications' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
354
			6  => __( 'Notification published.', 'remote-notifications' ),
355
			7  => __( 'Notification saved.', 'remote-notifications' ),
356
			8  => __( 'Notification submitted.', 'remote-notifications' ),
357
			9  => sprintf(
358
				__( 'Notification scheduled for: <strong>%1$s</strong>.', 'remote-notifications' ),
359
				// translators: Publish box date format, see http://php.net/date
360
				date_i18n( __( 'M j, Y @ G:i', 'remote-notifications' ), strtotime( $post->post_date ) )
361
			),
362
			10 => __( 'Notification draft updated.', 'remote-notifications' )
363
		);
364
365
		return $messages;
366
		
367
	}
368
369
	/**
370
	 * Register the "Channels" taxonomy
371
	 *
372
	 * @since 1.0.0
373
	 */
374 View Code Duplication
	public function register_channel() {
375
376
		$labels = array(
377
			'name'              => _x( 'Channels', 'taxonomy general name', 'remote-notifications' ),
378
			'singular_name'     => _x( 'Channel', 'taxonomy singular name', 'remote-notifications' ),
379
			'search_items'      => __( 'Search Channels', 'remote-notifications' ),
380
			'all_items'         => __( 'All Channels', 'remote-notifications' ),
381
			'parent_item'       => __( 'Parent Channel', 'remote-notifications' ),
382
			'parent_item_colon' => __( 'Parent Channel:', 'remote-notifications' ),
383
			'edit_item'         => __( 'Edit Channel', 'remote-notifications' ),
384
			'update_item'       => __( 'Update Channel', 'remote-notifications' ),
385
			'add_new_item'      => __( 'Add New Channel', 'remote-notifications' ),
386
			'new_item_name'     => __( 'New Channel Name', 'remote-notifications' ),
387
			'menu_name'         => __( 'Channels', 'remote-notifications' ),
388
		);
389
390
		$args = array(
391
			'hierarchical'      => true,
392
			'labels'            => $labels,
393
			'show_ui'           => true,
394
			'show_admin_column' => true,
395
			'query_var'         => true,
396
			'rewrite'           => array( 'slug' => 'channel' ),
397
		);
398
399
		register_taxonomy( 'rn-channel', array( 'notification' ), $args );
400
401
	}
402
403
	/**
404
	 * Register the post type taxonomy
405
	 *
406
	 * This taxonomy will be used to limit notices
407
	 * display on specific post types only.
408
	 *
409
	 * @since 1.0.0
410
	 */
411 View Code Duplication
	public function register_post_type() {
412
413
		$labels = array(
414
			'name'              => _x( 'Post Types Limitation', 'taxonomy general name', 'remote-notifications' ),
415
			'singular_name'     => _x( 'Post Type', 'taxonomy singular name', 'remote-notifications' ),
416
			'search_items'      => __( 'Search Post Types', 'remote-notifications' ),
417
			'all_items'         => __( 'All Post Types', 'remote-notifications' ),
418
			'parent_item'       => __( 'Parent Post Type', 'remote-notifications' ),
419
			'parent_item_colon' => __( 'Parent Post Type:', 'remote-notifications' ),
420
			'edit_item'         => __( 'Edit Post Type', 'remote-notifications' ),
421
			'update_item'       => __( 'Update Post Type', 'remote-notifications' ),
422
			'add_new_item'      => __( 'Add New Post Type', 'remote-notifications' ),
423
			'new_item_name'     => __( 'New Post Type Name', 'remote-notifications' ),
424
			'menu_name'         => __( 'Post Types', 'remote-notifications' ),
425
		);
426
427
		$args = array(
428
			'hierarchical'      => false,
429
			'labels'            => $labels,
430
			'show_ui'           => true,
431
			'show_admin_column' => true,
432
			'query_var'         => true,
433
			'rewrite'           => array( 'slug' => 'post-type' ),
434
		);
435
436
		register_taxonomy( 'rn-pt', array( 'notification' ), $args );
437
438
	}
439
440
}