Issues (4)

Security Analysis    no request data  

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.

class-gamajo-dashboard-glancer.php (1 issue)

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
 * Gamajo Dashboard Glancer
4
 *
5
 * @package   Gamajo\DashboardGlancer
6
 * @author    Gary Jones
7
 * @link      https://github.com/gamajo/dashboard-glancer
8
 * @copyright 2013 Gary Jones, Gamajo
9
 * @license   GPL-2.0-or-later
10
 * @version   1.0.5
11
 */
12
13
/**
14
 * Easily add items to the At a Glance Dashboard widget in WordPress 3.8+.
15
 *
16
 * @package Gamajo\DashboardGlancer
17
 * @author  Gary Jones
18
 */
19
class Gamajo_Dashboard_Glancer {
20
	/**
21
	 * Hold all of the items to show.
22
	 *
23
	 * @since 1.0.0
24
	 *
25
	 * @var array
26
	 */
27
	protected $items;
28
29
	/**
30
	 * Automatically show any registered items.
31
	 *
32
	 * With this, there's no need to explicitly call show() during the
33
	 * `dashboard_glance_items` hook, and items can be registered at any time
34
	 * before `dashboard_glance_items` priority 20 (including on earlier hooks).
35
	 *
36
	 * @since 1.0.0
37
	 */
38
	public function __construct() {
39
		add_action( 'dashboard_glance_items', array( $this, 'show' ), 20 );
40
		add_action( 'admin_enqueue_scripts', array( $this, 'dashboard_css' ) );
41
	}
42
43
	/**
44
	 * Register one or more post type items to be shown on the dashboard widget.
45
	 *
46
	 * @since 1.0.0
47
	 *
48
	 * @param array|string $post_types Post type name, or array of post type names.
49
	 * @param array|string $statuses   Optional. Post status or array of
50
	 *                                 different post type statuses. Default is
51
	 *                                 `publish`.
52
	 * @return null Return early if action hook has already passed, or no valid
53
	 *              post types were given.
54
	 */
55
	public function add( $post_types, $statuses = null ) {
56
		if ( null === $statuses ) {
57
			$statuses = 'publish';
58
		}
59
60
		// If relevant output action hook has already passed, then no point in proceeding.
61
		if ( did_action( 'dashboard_glance_items' ) ) {
62
			_doing_it_wrong( __CLASS__, 'Trying to add At a Glance items to dashboard widget afterhook already fired', '1.0.0' );
63
64
			return;
65
		}
66
67
		$post_types = $this->unset_invalid_post_types( (array) $post_types );
68
69
		// If all given post types were invalid, bail now.
70
		if ( ! $post_types ) {
71
			return;
72
		}
73
74
		// Register each combination of given post type and status.
75
		foreach ( $post_types as $post_type ) {
76
			foreach ( (array) $statuses as $status ) {
77
				$this->items[] = array(
78
					'type'   => $post_type,
79
					'status' => $status, // No checks yet to see if status is valid.
80
				);
81
			}
82
		}
83
	}
84
85
	/**
86
	 * Show the items on the dashboard widget.
87
	 *
88
	 * @since 1.0.0
89
	 */
90
	public function show() {
91
		foreach ( $this->items as $item ) {
92
			echo wp_kses_post( $this->get_single_item( $item ) );
93
		}
94
		// Reset items, so items aren't shown again if show() is re-called.
95
		unset( $this->items );
96
	}
97
98
	/**
99
	 * Check one or more post types to see if they are valid.
100
	 *
101
	 * @since 1.0.0
102
	 *
103
	 * @param array $post_types Each of the post types to check.
104
	 * @return array List of the given post types that are valid.
105
	 */
106
	protected function unset_invalid_post_types( array $post_types ) {
107
		foreach ( $post_types as $index => $post_type ) {
108
			$post_type_object = get_post_type_object( $post_type );
109
			if ( null === $post_type_object ) {
110
				unset( $post_types[ $index ] );
111
			}
112
		}
113
114
		return $post_types;
115
	}
116
117
	/**
118
	 * Build and return the data and markup for a single item.
119
	 *
120
	 * If the item count is zero, return an empty string, to avoid visual clutter.
121
	 *
122
	 * @since 1.0.0
123
	 *
124
	 * @param array $item Registered item.
125
	 * @return string Markup, or empty string if item count is zero.
126
	 */
127 View Code Duplication
	protected function get_single_item( array $item ) {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
128
		$num_posts = wp_count_posts( $item['type'] );
129
		$count     = (int) $num_posts->{$item['status']};
130
131
		if ( ! $count ) {
132
			return '';
133
		}
134
135
		$href = $this->get_link_url( $item );
136
		$text = number_format_i18n( $count ) . ' ' . $this->get_label( $item, $count );
137
		$text = $this->maybe_link( $text, $href );
138
139
		return $this->get_markup( $text, $item['type'] );
140
	}
141
142
	/**
143
	 * Get the singular or plural label for an item.
144
	 *
145
	 * @since 1.0.0
146
	 *
147
	 * @param array $item  Registered item.
148
	 * @param int   $count Number of items present in WP.
149
	 * @return string
150
	 */
151
	protected function get_label( array $item, $count ) {
152
		$post_type_object = get_post_type_object( $item['type'] );
153
		$labels           = $post_type_object->labels;
154
		$label            = 1 === $count ? $labels->singular_name : $labels->name;
155
156
		// Append status for non-publish statuses for disambiguation.
157
		if ( 'publish' !== $item['status'] ) {
158
			$label .= ' (' . $item['status'] . ')';
159
		}
160
161
		return $label;
162
	}
163
164
	/**
165
	 * Build the URL that linked items use.
166
	 *
167
	 * @since 1.0.0
168
	 *
169
	 * @param array $item Registered item.
170
	 * @return string Admin URL to view the entries of the given post type with the given status
171
	 */
172
	public function get_link_url( array $item ) {
173
		return 'edit.php?post_status=' . $item['status'] . '&amp;post_type=' . $item['type'];
174
	}
175
176
	/**
177
	 * Wrap a glance item in a link, if the current user can edit posts.
178
	 *
179
	 * @since 1.0.0
180
	 *
181
	 * @param string $text Text to potentially wrap in a link.
182
	 * @param string $href Link target.
183
	 * @return string Text wrapped in a link if current user can edit posts, or original text otherwise.
184
	 */
185
	protected function maybe_link( $text, $href ) {
186
		if ( current_user_can( 'edit_posts' ) ) {
187
			return '<a href="' . esc_url( $href ) . '">' . esc_html( $text ) . '</a>';
188
		}
189
190
		return '<span>' . esc_html( $text ) . '</span>';
191
	}
192
193
	/**
194
	 * Wrap number and text within list item markup.
195
	 *
196
	 * The extra work for populating classes is to provide dashicons support.
197
	 *
198
	 * @since 1.0.0
199
	 *
200
	 * @param string $text      Text to display. May be wrapped in a link.
201
	 * @param string $post_type Post type.
202
	 * @return string Markup for list item.
203
	 */
204
	protected function get_markup( $text, $post_type ) {
205
		$classes[]        = $post_type . '-count';
206
		$post_type_object = get_post_type_object( $post_type );
207
		$menu_icon        = isset( $post_type_object->menu_icon ) ? $post_type_object->menu_icon : null;
208
209
		if ( 0 === strpos( $menu_icon, 'dashicons-' ) ) {
210
			$classes[] = 'dashicons-before';
211
			$classes[] = $menu_icon;
212
		}
213
214
		$class = implode( ' ', sanitize_html_class( $classes ) );
215
216
		return '<li class="' . esc_attr( $class ) . '">' . wp_kses_post( $text ) . '</li>' . "\n";
217
	}
218
219
	/**
220
	 * Add post types icon styling to Dashboard page.
221
	 *
222
	 * To override the overly-specific core styles, we apply styles to ignore
223
	 * the default circle, and with the classes added to the list item (not
224
	 * anchor), get dashicons showing there instead.
225
	 *
226
	 * @since 1.1.0
227
	 *
228
	 * @return null Return early if style already added, or the Dashboard page.
229
	 */
230
	public function dashboard_css() {
231
		static $added_style;
232
233
		if ( $added_style ) {
234
			return;
235
		}
236
237
		$screen = get_current_screen();
238
239
		if ( 'dashboard' !== $screen->base ) {
240
			return;
241
		}
242
243
		// Remove default circle, and style dashicons we add via classes.
244
		echo '<style type="text/css">#dashboard_right_now li.dashicons-before a:before, #dashboard_right_now li.dashicons span:before {content: none;}#dashboard_right_now li.dashicons-before:before {color: #82878c;margin: 0 5px 0 0;}</style>';
245
246
		$added_style = true;
247
	}
248
}
249