Completed
Push — master ( 37d93b...e0e7fb )
by
unknown
18:13
created

wpshop_dashboard   F

Complexity

Total Complexity 55

Size/Duplication

Total Lines 687
Duplicated Lines 8.73 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 60
loc 687
rs 1.447
c 0
b 0
f 0
wmc 55
lcom 1
cbo 1

6 Methods

Rating   Name   Duplication   Size   Complexity  
B wpshop_rss_feed() 27 27 4
B wpshop_rss_tutorial_videos() 0 27 5
A wpshop_dashboard_get_changelog() 10 10 2
C wpshop_dashboard_orders() 8 50 24
A dashboard.class.php ➔ orders_this_month() 0 17 1
F display_dashboard() 15 565 20

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like wpshop_dashboard often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use wpshop_dashboard, and based on these observations, apply Extract Interface, too.

1
<?php if ( !defined( 'ABSPATH' ) ) exit;
2
3
/*	Check if file is include. No direct access possible with file url	*/
4
if ( !defined( 'WPSHOP_VERSION' ) ) {
5
	die( __('Access is not allowed by this way', 'wpshop') );
6
}
7
8
class wpshop_dashboard {
9
	function display_dashboard() {
0 ignored issues
show
Best Practice introduced by
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...
10
		global $order_status, $wpdb;
11
12
	ob_start();
13
?>
14
	<div id="wpshop_dashboard">
15
16
		<div id="dashboard-widgets" class="metabox-holder">
17
18
			<div class="postbox-container" style="width:49%;">
19
20
				<div id="wpshop_right_now" class="wpshop_right_now postbox">
21
					<h3><?php _e('Right Now', 'wpshop') ?></h3>
22
					<div class="inside">
23
24
						<div class="table table_content">
25
							<p class="sub"><?php _e('Shop Content', 'wpshop'); ?></p>
26
							<table>
27
								<tbody>
28
									<tr class="first">
29
30
										<td class="first b"><a href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT; ?>"><?php
31
											$num_posts = wp_count_posts(WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT);
32
											$number_of_products = number_format_i18n( $num_posts->publish );
33
											echo $number_of_products;
34
										?></a></td>
35
										<td class="t"><a href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT; ?>"><?php _e('Products', 'wpshop'); ?></a></td>
36
									</tr>
37
									<tr>
38
										<td class="first b"><a href="edit-tags.php?taxonomy=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_CATEGORIES; ?>&amp;post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT; ?>"><?php echo wp_count_terms(WPSHOP_NEWTYPE_IDENTIFIER_CATEGORIES); ?></a></td>
39
										<td class="t"><a href="edit-tags.php?taxonomy=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_CATEGORIES; ?>&amp;post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT; ?>"><?php _e('Product Categories', 'wpshop'); ?></a></td>
40
									</tr>
41
									<tr>
42
										<td class="first b"><a href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>">
43
										<?php $num_posts = wp_count_posts(WPSHOP_NEWTYPE_IDENTIFIER_ORDER); echo number_format_i18n($num_posts->publish); ?></a></td>
44
										<td class="t"><a href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>"><?php _e('Orders', 'wpshop'); ?></a></td>
45
									</tr>
46
									<tr>
47
										<td class="first b"><a href="users.php"><?php $result = count_users(); echo $result['total_users']; ?></a></td>
48
										<td class="t"><a href="users.php"><?php _e('Customers', 'wpshop'); ?></a></td>
49
									</tr>
50
								</tbody>
51
							</table>
52
						</div>
53
						<div class="table table_discussion">
54
							<p class="sub"><?php _e('Orders', 'wpshop'); ?></p>
55
							<table>
56
								<tbody>
57
									<?php
58
									$args = array(
59
										'numberposts'     => -1,
60
										'orderby'         => 'post_date',
61
										'order'           => 'DESC',
62
										'post_type'       => WPSHOP_NEWTYPE_IDENTIFIER_ORDER,
63
										'post_status'     => 'publish'
64
									);
65
									$orders = get_posts($args);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $orders is correct as get_posts($args) (which targets get_posts()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
66
									$order_completed = $order_shipped = $order_awaiting_payment = $order_denied = $order_canceled = $order_refunded = 0;
67 View Code Duplication
									if ($orders) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
68
										foreach ($orders as $o) {
69
											$order = get_post_meta($o->ID, '_order_postmeta', true);
70
											if(!empty($order['order_status'])){
71
												switch($order['order_status']) {
72
													case 'completed': $order_completed++; break;
73
													case 'shipped': $order_shipped++; break;
74
													case 'awaiting_payment': $order_awaiting_payment++; break;
75
													case 'denied': $order_denied++; break;
76
													case 'canceled': $order_canceled++; break;
77
													case 'refunded' : $order_refunded++; break;
78
												}
79
											}
80
										}
81
									}
82
									?>
83
84
									<tr>
85
										<td class="b"><a href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=completed"><span class="total-count"><?php echo $order_completed; ?></span></a></td>
86
										<td class="last t"><a class="completed" href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=completed"><?php _e('Completed', 'wpshop'); ?></a></td>
87
									</tr>
88
89
									<tr>
90
										<td class="b"><a href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=shipped"><span class="total-count"><?php echo $order_shipped; ?></span></a></td>
91
										<td class="last t"><a class="shipped" href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=completed"><?php _e('Shipped', 'wpshop'); ?></a></td>
92
									</tr>
93
94
									<tr class="first">
95
										<td class="b"><a href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=awaiting_payment"><span class="total-count"><?php echo $order_awaiting_payment; ?></span></a></td>
96
										<td class="last t"><a class="pending" href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=awaiting_payment"><?php _e('Awaiting payment', 'wpshop'); ?></a></td>
97
									</tr>
98
99
									<tr>
100
										<td class="b"><a href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=denied"><span class="total-count"><?php echo $order_denied; ?></span></a></td>
101
										<td class="last t"><a class="denied" href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=denied"><?php _e('Denied', 'wpshop'); ?></a></td>
102
									</tr>
103
									<tr>
104
										<td class="b"><a href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=canceled"><span class="total-count"><?php echo $order_canceled; ?></span></a></td>
105
										<td class="last t"><a class="canceled" href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=canceled"><?php _e('Canceled', 'wpshop'); ?></a></td>
106
									</tr>
107
									<tr>
108
										<td class="b"><a href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=refunded"><span class="total-count"><?php echo $order_refunded; ?></span></a></td>
109
										<td class="last t"><a class="refunded" href="edit.php?post_type=<?php echo WPSHOP_NEWTYPE_IDENTIFIER_ORDER; ?>&amp;shop_order_status=refunded"><?php _e('Refunded', 'wpshop'); ?></a></td>
110
									</tr>
111
								</tbody>
112
							</table>
113
						</div>
114
						<div class="versions">
115
							<p id="wp-version-message"><?php _e('You are using', 'wpshop'); ?> <strong>WPShop <?php echo WPSHOP_VERSION; ?></strong></p>
116
						</div>
117
						<div class="wpshop_cls"></div>
118
					</div>
119
120
				</div><!-- postbox end -->
121
122
				<div class="postbox">
123
					<h3 class="hndle"><span><?php _e('Customers stats', 'wpshop') ?></span></h3>
124
					<div class="inside">
125
126
						<span class="alignright"><?php $result = count_users(); echo $result['total_users']; ?></span>
127
						<label><?php _e('Number of customers', 'wpshop'); ?></label><br />
128
129
						<?php
130
						// New customers
131
						$query = $wpdb->prepare('SELECT COUNT(*) FROM '.$wpdb->users.' WHERE user_registered > (NOW()-INTERVAL 7 DAY)', '');
132
						$result = $wpdb->get_var($query);
133
						?>
134
						<span class="alignright"><?php echo $result; ?></span>
135
						<label><?php _e('New customers', 'wpshop'); ?></label><br />
136
137
						<?php
138
						// Number of customers who ordered
139
						$query = $wpdb->prepare('SELECT COUNT(DISTINCT post_author) FROM '.$wpdb->posts.' WHERE post_type="'.WPSHOP_NEWTYPE_IDENTIFIER_ORDER.'"', '');
140
						$result = $wpdb->get_var($query);
141
						?>
142
						<span class="alignright"><?php echo $result; ?></span>
143
						<label><?php _e('Number of customers who ordered', 'wpshop'); ?></label>
144
145
146
						<?php
147
							$query = $wpdb->prepare("SELECT user_id, meta_value FROM " . $wpdb->usermeta . " WHERE meta_key = %s", 'user_preferences');
148
							$user_preferences = $wpdb->get_results($query);
149
							$nb_of_customer_for_newsletter = $nb_of_customer_for_newsletter_partners = 0;
150
							foreach ( $user_preferences as $meta_values ) {
151
								$user_prefs = unserialize( $meta_values->meta_value );
152
153
								if ( !empty($user_prefs['newsletters_site']) && $user_prefs['newsletters_site'] ) {
154
									$nb_of_customer_for_newsletter++;
155
								}
156
								else if ( !empty($user_prefs['newsletters_site_partners']) && $user_prefs['newsletters_site_partners'] ) {
157
									$nb_of_customer_for_newsletter_partners++;
158
								}
159
							}
160
						?>
161
						<br />
162
						<label><?php _e('Number of customers who wants to receive shop newsletters', 'wpshop'); ?></label>
163
						<span class="alignright"><?php echo $nb_of_customer_for_newsletter; ?><a href="<?php echo admin_url(); ?>admin.php?page=wpshop_dashboard&download_users=newsletters_site"><img src="<?php echo WPSHOP_MEDIAS_IMAGES_URL; ?>download.png" alt="<?php _e('Download', 'wpshop'); ?>" id="download_newsletter_contacts" /></a></span>
164
						<br />
165
						<label><?php _e('Number of customers who wants to receive partners newsletters', 'wpshop'); ?></label>
166
						<span class="alignright"><?php echo $nb_of_customer_for_newsletter_partners; ?> <a href="<?php echo admin_url(); ?>admin.php?page=wpshop_dashboard&download_users=newsletters_site_partner"><img src="<?php echo WPSHOP_MEDIAS_IMAGES_URL; ?>download.png" alt="<?php _e('Download', 'wpshop'); ?>" /></a></span>
167
					</div>
168
				</div><!-- postbox end -->
169
170
				<div class="postbox">
171
					<h3 class="hndle"><span><?php _e('Quick Links', 'wpshop') ?></span></h3>
172
					<div class="inside">
173
						<ul id="wps_dashboard_quick_links">
174
							<li><a href="<?php echo admin_url( 'post-new.php?post_type=wpshop_product' ); ?>"><img src="<?php echo WPSHOP_MEDIAS_IMAGES_URL; ?>icon_create_product.jpg" alt="<?php _e( 'Create a new product', 'wpshop'); ?>" /><br/><?php _e('Create a product', 'wpshop'); ?></a></li>
175
							<li><a href="<?php echo admin_url( 'post-new.php?post_type=' . WPSHOP_NEWTYPE_IDENTIFIER_ORDER ); ?>"><img src="<?php echo WPSHOP_MEDIAS_IMAGES_URL; ?>icon_create_order.jpg" alt="<?php _e( 'Create order', 'wpshop'); ?>" /><br/><?php _e('Create an order', 'wpshop'); ?></a></li>
176
							<li><a href="<?php echo admin_url( 'post-new.php?post_type=wpshop_shop_coupon' ); ?>"><img src="<?php echo WPSHOP_MEDIAS_IMAGES_URL; ?>icon_create_coupon.jpg" alt="<?php _e( 'Create a coupon', 'wpshop'); ?>" /><br/><?php _e('Create a coupon', 'wpshop'); ?></a></li>
177
							<li><a href="<?php echo admin_url( 'admin.php?page=wpshop_statistics' ); ?>"><img src="<?php echo WPSHOP_MEDIAS_IMAGES_URL; ?>icon_statistics.jpg" alt="<?php _e( 'Statistics', 'wpshop'); ?>" /><br/><?php _e('Statistics', 'wpshop'); ?></a></li>
178
						</ul>
179
						<?php
180
						// Number of products on sale
181
						/***
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
182
						$query = $wpdb->prepare('SELECT COUNT(*) FROM '.$wpdb->posts.' WHERE post_type="'.WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT.'" AND post_status="publish"', '');
183
						$result = $wpdb->get_var($query);
184
						?>
185
						<span class="alignright"><?php echo $result; ?></span>
186
						<label><?php _e('Number of products on sale', 'wpshop'); ?></label><br />
187
188
						<!--<span class="alignright">0</span>
189
						<label><?php //_e('Number of promotional products', 'wpshop'); ?></label><br />-->
190
191
						<?php
192
193
						$args = array(
194
							'numberposts'     => -1,
195
							'orderby'         => 'post_date',
196
							'order'           => 'DESC',
197
							'post_type'       => WPSHOP_NEWTYPE_IDENTIFIER_PRODUCT,
198
							'post_status'     => 'publish'
199
						);
200
						$products = get_posts($args);
201
						$in_string='';
202
						foreach ($products as $p) {
203
							$in_string.=$p->ID.',';
204
						}
205
						$in_string=substr($in_string,0,-1);
206
207
						// Number of products out of stock
208
						$query = $wpdb->prepare('
209
							SELECT COUNT(DISTINCT(wp_wpshop__attribute_value_decimal.entity_id)) FROM wp_wpshop__attribute_value_decimal
210
							LEFT JOIN wp_wpshop__attribute ON wp_wpshop__attribute.id = wp_wpshop__attribute_value_decimal.attribute_id
211
							WHERE wp_wpshop__attribute.code="product_stock" AND wp_wpshop__attribute_value_decimal.value>0 AND wp_wpshop__attribute_value_decimal.entity_id IN('.$in_string.')
212
						', '');
213
						$result_stock_sup0 = $wpdb->get_var($query);
214
						$result_stock_sup0 = !empty($result_stock_sup0) ? $result_stock_sup0 : 0;
215
216
						$result = $number_of_products-$result_stock_sup0;
217
						?>
218
						<span class="alignright"><?php echo $result; ?></span>
219
						<label><?php _e('Number of products out of stock', 'wpshop'); ?></label><br />
220
221
						<?php
222
						// Number of products sold the last 7 days
223
						$result=0;
224
						$query = $wpdb->prepare('SELECT ID FROM '.$wpdb->posts.' WHERE post_type="'.WPSHOP_NEWTYPE_IDENTIFIER_ORDER.'" AND post_date > (NOW()-INTERVAL 7 DAY)', '');
225
						$data = $wpdb->get_results($query, ARRAY_A);
226
						foreach($data as $d) {
227
							$postmeta = get_post_meta($d['ID'], '_order_postmeta', true);
228
							if(!empty($postmeta) && !empty($postmeta['order_items'])) {
229
								foreach($postmeta['order_items'] as $i) {
230
									$result += $i['item_qty'];
231
								}
232
							}
233
						}
234
						***/
235
						?>
236
						<!--
237
						<span class="alignright"><?php echo $result; ?></span>
238
						<label><?php _e('Number of products sold the last 7 days', 'wpshop'); ?></label>
239
						-->
240
					</div>
241
				</div><!-- postbox end -->
242
243
244
				<!--  BOX ORDERS -->
245
				<div class="postbox">
246
					<h3 class="hndle"><span><?php _e('Recent Orders', 'wpshop') ?></span></h3>
247
					<div class="inside">
248
						<?php echo self::wpshop_dashboard_orders(); ?>
249
					</div>
250
				</div><!-- postbox end -->
251
252
253
254
			</div>
255
			<div class="postbox-container" style="width:49%; float:right;">
256
257
				<?php
258
					global $current_month_offset;
259
260
					$current_month_offset = (isset($_GET['month'])) ? (int) $_GET['month'] : (int) date('m');
261
262
									?>
263
				<div class="postbox stats" id="wpshop-stats">
264
					<h3 class="hndle">
265
						<?php if ($current_month_offset!=date('m')) : ?>
266
							<a href="admin.php?page=wpshop_dashboard&amp;month=<?php echo $current_month_offset+1; ?>" class="next"><?php echo __('Next Month','wpshop'); ?> &rarr;</a>
267
						<?php endif; ?>
268
						<a href="admin.php?page=wpshop_dashboard&amp;month=<?php echo $current_month_offset-1; ?>" class="previous">&larr; <?php echo __('Previous Month','wpshop'); ?></a>
269
						<span><?php _e('Monthly Sales', 'wpshop') ?></span></h3>
270
					<div class="inside">
271
						<div id="placeholder" style="width:100%; height:300px; position:relative;"></div>
272
						<script type="text/javascript">
273
							/* <![CDATA[ */
274
275
							jQuery(function(){
276
277
								function weekendAreas(axes) {
278
									var markings = [];
279
									var d = new Date(axes.xaxis.min);
280
									// go to the first Saturday
281
									d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 1) % 7))
282
									d.setUTCSeconds(0);
283
									d.setUTCMinutes(0);
284
									d.setUTCHours(0);
285
									var i = d.getTime();
286
									do {
287
										// when we don't set yaxis, the rectangle automatically
288
										// extends to infinity upwards and downwards
289
										markings.push({ xaxis: { from: i, to: i + 2 * 24 * 60 * 60 * 1000 } });
290
										i += 7 * 24 * 60 * 60 * 1000;
291
									} while (i < axes.xaxis.max);
292
293
									return markings;
294
								}
295
296
								<?php
297
298
									function orders_this_month( $where = '' ) {
0 ignored issues
show
Best Practice introduced by
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...
299
										global $current_month_offset;
300
301
										$month = $current_month_offset;
302
										$year = (int) date('Y');
303
304
										$first_day = strtotime("{$year}-{$month}-01");
305
										$last_day = strtotime('-1 second', strtotime('+1 month', $first_day));
306
307
										$after = date('Y-m-d', $first_day);
308
										$before = date('Y-m-d', $last_day);
309
310
										$where .= " AND post_date > '$after'";
311
										$where .= " AND post_date < '$before'";
312
313
										return $where;
314
									}
315
									add_filter( 'posts_where', 'orders_this_month' );
316
317
									$args = array(
318
										'numberposts'      => -1,
319
										'orderby'          => 'post_date',
320
										'order'            => 'DESC',
321
										'post_type'        => WPSHOP_NEWTYPE_IDENTIFIER_ORDER,
322
										'post_status'      => 'publish' ,
323
										'suppress_filters' => false
324
									);
325
									$orders = get_posts( $args );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $orders is correct as get_posts($args) (which targets get_posts()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
326
327
									$order_counts = array();
328
									$order_amounts = array();
329
330
									// Blank date ranges to begin
331
									$month = $current_month_offset;
332
									$year = (int) date('Y');
333
334
									$first_day = strtotime("{$year}-{$month}-01");
335
									$last_day = strtotime('-1 second', strtotime('+1 month', $first_day));
336
337
									if ((date('m') - $current_month_offset)==0) :
338
										$up_to = date('d', strtotime('NOW'));
339
									else :
340
										$up_to = date('d', $last_day);
341
									endif;
342
									$count = 0;
343
344
									while ($count < $up_to) :
345
346
										$time = strtotime(date('Ymd', strtotime('+ '.$count.' DAY', $first_day))).'000';
347
348
										$order_counts[$time] = 0;
349
										$order_amounts[$time] = 0;
350
351
										$count++;
352
									endwhile;
353
354
									if ($orders) :
355
										foreach ($orders as $order) :
356
357
											$order_data = get_post_meta($order->ID, '_order_postmeta', true);
358
359
											if ($order_data['order_status']=='denied' || $order_data['order_status']=='awaiting_payment') continue;
360
361
											$time = strtotime(date('Ymd', strtotime($order_data['order_date']))).'000';
362
363
											$order_grand_total = !empty($order_data['order_grand_total']) ? $order_data['order_grand_total'] : 0;
364
365
											if (isset($order_counts[$time])) : $order_counts[$time]++;
366
											else : $order_counts[$time] = 1; endif;
367
368
											if (isset($order_amounts[$time])) $order_amounts[$time] = $order_amounts[$time] + $order_grand_total;
369
											else $order_amounts[$time] = (float) $order_grand_total;
370
371
										endforeach;
372
									endif;
373
374
									remove_filter( 'posts_where', 'orders_this_month' );
375
								?>
376
377
								var d = [
378
									<?php
379
										$values = array();
380
										foreach ($order_counts as $key => $value) $values[] = "[$key, $value]";
381
										echo implode(',', $values);
382
									?>
383
								];
384
385
								for (var i = 0; i < d.length; ++i) d[i][0] += 60 * 60 * 1000;
386
387
								var d2 = [
388
									<?php
389
										$values = array();
390
										foreach ($order_amounts as $key => $value) $values[] = "[$key, $value]";
391
										echo implode(',', $values);
392
									?>
393
								];
394
395
								for (var i = 0; i < d2.length; ++i) d2[i][0] += 60 * 60 * 1000;
396
397
								var plot = jQuery.plot(jQuery("#placeholder"), [ { label: "<?php echo __('Number of sales','wpshop'); ?>", data: d }, { label: "<?php echo __('Sales amount','wpshop'); ?>", data: d2, yaxis: 2 } ], {
398
									series: {
399
										lines: { show: true },
400
										points: { show: true }
401
									},
402
									grid: {
403
										show: true,
404
										aboveData: false,
405
										color: '#545454',
406
										backgroundColor: '#fff',
407
										borderWidth: 2,
408
										borderColor: '#ccc',
409
										clickable: false,
410
										hoverable: true,
411
										markings: weekendAreas
412
									},
413
									xaxis: {
414
										mode: "time",
415
										timeformat: "%d %b",
416
										tickLength: 1,
417
										minTickSize: [1, "day"]
418
									},
419
									yaxes: [ { min: 0, tickSize: 1, tickDecimals: 0 }, { position: "right", min: 0, tickDecimals: 2 } ],
420
									colors: ["#21759B", "#ed8432"]
421
								});
422
423
								function showTooltip(x, y, contents) {
424
									jQuery('<div id="tooltip">' + contents + '</div>').css( {
425
										position: 'absolute',
426
										display: 'none',
427
										top: y + 5,
428
										left: x + 5,
429
										border: '1px solid #fdd',
430
										padding: '2px',
431
										'background-color': '#fee',
432
										opacity: 0.80
433
									}).appendTo("body").fadeIn(200);
434
								}
435
436
								var previousPoint = null;
437
								jQuery("#placeholder").bind("plothover", function (event, pos, item) {
438
									if (item) {
439
										if (previousPoint != item.dataIndex) {
440
											previousPoint = item.dataIndex;
441
442
											jQuery("#tooltip").remove();
443
444
											if (item.series.label=="<?php echo __('Number of sales','wpshop'); ?>") {
445
446
												var y = item.datapoint[1];
447
												showTooltip(item.pageX, item.pageY, y+" <?php echo __('sales','wpshop'); ?>");
448
449
											} else {
450
451
												var y = item.datapoint[1].toFixed(2);
452
												showTooltip(item.pageX, item.pageY, y+" <?php echo wpshop_tools::wpshop_get_currency(); ?>");
453
454
											}
455
456
										}
457
									}
458
									else {
459
										jQuery("#tooltip").remove();
460
										previousPoint = null;
461
									}
462
								});
463
464
							});
465
466
							/* ]]> */
467
						</script>
468
					</div>
469
				</div><!-- postbox end -->
470
471
				<!--
472
				<div class="postbox">
473
					<h3 class="hndle"><span><?php _e('Orders stats', 'wpshop') ?></span></h3>
474
					<div class="inside">
475
476
						<?php
477
						// Number of active order
478
						/*$result=0;
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
479
						$query = $wpdb->prepare('SELECT ID FROM '.$wpdb->posts.' WHERE post_type="'.WPSHOP_NEWTYPE_IDENTIFIER_ORDER.'"');
480
						$data = $wpdb->get_results($query, ARRAY_A);
481
						foreach($data as $d) {
482
							$postmeta = get_post_meta($d['ID'], '_order_postmeta', true);
483
							if(!empty($postmeta) && !empty($postmeta['order_status']) && $postmeta['order_status']!='completed')
484
								$result++;
485
						}*/
486
						$num_posts = wp_count_posts(WPSHOP_NEWTYPE_IDENTIFIER_ORDER);
487
						$result = number_format_i18n($num_posts->publish);
488
						?>
489
						<span class="alignright"><?php echo $result; ?></span>
490
						<label><?php _e('Number of active order', 'wpshop'); ?></label><br />
491
492
						<?php
493
						$result=0;
494
						// Number of orders the last 7 days
495
						$query = $wpdb->prepare('SELECT ID FROM '.$wpdb->posts.' WHERE post_type="'.WPSHOP_NEWTYPE_IDENTIFIER_ORDER.'" AND post_date > (NOW()-INTERVAL 7 DAY)', '');
496
						$data = $wpdb->get_results($query, ARRAY_A);
497
						foreach($data as $d) {
498
							$postmeta = get_post_meta($d['ID'], '_order_postmeta', true);
499
							if(!empty($postmeta) && !empty($postmeta['order_key']) && substr($postmeta['order_key'],0,2)=='OR')
500
								$result++;
501
						}
502
						?>
503
						<span class="alignright"><?php echo $result; ?></span>
504
						<label><?php _e('Number of orders the last 7 days', 'wpshop'); ?></label><br />
505
506
						<?php
507
						$result=0;
508
						// Number of orders the last 7 days
509
						$query = $wpdb->prepare('SELECT ID FROM '.$wpdb->posts.' WHERE post_type="'.WPSHOP_NEWTYPE_IDENTIFIER_ORDER.'" AND post_date > (NOW()-INTERVAL 7 DAY)', '');
510
						$data = $wpdb->get_results($query, ARRAY_A);
511
						foreach($data as $d) {
512
							$postmeta = get_post_meta($d['ID'], '_order_postmeta', true);
513
							if(!empty($postmeta) && !empty($postmeta['order_grand_total']))
514
								$result+=$postmeta['order_grand_total'];
515
						}
516
						if(count($data)>0)
517
							$result = round($result/count($data),2);
518
						?>
519
						<span class="alignright"><?php echo wpshop_tools::wpshop_get_currency(); ?> <?php echo $result; ?></span>
520
						<label><?php _e('Cart price average', 'wpshop'); ?></label>
521
522
					</div>
523
				</div>
524
				-->
525
526
				<div class="postbox">
527
					<h3 class="hndle"><span>WPShop : Wordpress e-commerce</span></h3>
528
					<div class="inside">
529
						<table width="100%">
530
							<tr>
531
								<td><?php self::wpshop_rss_tutorial_videos(); ?></td>
532
								<td valign="top" cellpadding="20" ><h2 class="wps_dashboard"><?php _e('Need help with WPShop', 'wpshop' ); ?> ?</h2>
533
									<p><?php _e( 'You need help with WPShop ? You some questions ?', 'wpshop' ); ?></p>
534
									<p><h3 class="wps_dashboard"><?php _e( 'Two solutions', 'wpshop'); ?></h3></p>
535
									<p><center><br/><a href="https://shop.eoxia.com/ecommerce/assistance-personnalisee-wordpress/" title="<?php _e('WPShop Assistance', 'wpshop'); ?>" target="_blank"><img src="<?php echo WPSHOP_MEDIAS_IMAGES_URL; ?>assistance_wpshop.jpg" alt="<?php _e('WPShop Assistance', 'wpshop'); ?>" /></a><br/>
536
									<a href="http://forums.eoxia.com/" title="<?php _e('WPShop Forum', 'wpshop'); ?>" target="_blank"><img src="<?php echo WPSHOP_MEDIAS_IMAGES_URL; ?>forum_wpshop.jpg" alt="<?php _e('WPShop Forum', 'wpshop'); ?>" /></a></center></p>
537
								</td>
538
							</tr>
539
						</table>
540
					</div>
541
				</div>
542
543
544
545
				<div class="postbox">
546
					<h3 class="hndle"><span><?php _e('WPShop news', 'wpshop') ?></span></h3>
547
					<div class="inside">
548
						<?php
549
						self::wpshop_rss_feed();
550
						?>
551
					</div>
552
				</div><!-- postbox end -->
553
554
555
556
				<!--
557
				<div class="postbox">
558
					<h3 class="hndle"><span><?php _e('Quick product add', 'wpshop') ?></span></h3>
559
					<div class="inside">
560
						<?php do_shortcode('[wpshop_entities post_type="wpshop_product" fields="post_title, post_thumbnail" attribute_set_id="1" button_text="' . __('Add a new product', 'wpshop') . '" ]'); ?>
561
					</div>
562
				</div>
563
				-->
564
				<!-- postbox end -->
565
566
			</div>
567
		</div>
568
	</div>
569
	<?php
570
		$content = ob_get_contents();
571
		ob_end_clean();
572
		return $content;
573
	}
574
575
576
	function wpshop_dashboard_orders() {
0 ignored issues
show
Best Practice introduced by
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...
577
		$output = '';
578
		$orders = get_posts( array( 'posts_per_page' => 10, 'post_type' => WPSHOP_NEWTYPE_IDENTIFIER_ORDER, 'post_status' => 'publish', 'orderby' => 'post_date', 'order' => 'DESC') );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $orders is correct as get_posts(array('posts_p...e', 'order' => 'DESC')) (which targets get_posts()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
579
		if ( !empty($orders) ) {
580
			$payment_status = unserialize( WPSHOP_ORDER_STATUS );
581
582
			$output .= '<table id="wps_dashboard_orders_summary">';
583
			$output .= '<tr><th class="wps_dashboard_order_date">' .__('Date', 'wpshop'). '</th><th class="wps_dashboard_order_customer_name">' .__('Customer', 'wpshop'). '</th><th class="wps_dashboard_order_amount">' .__('Amount', 'wpshop'). '</th><th class="wps_dashboard_order_status">' .__('Status', 'wpshop'). '</th><th class="wps_dashboard_order_actions"></th></tr>';
584
			$stried = false;
585
			foreach( $orders as $order ) {
586
				$stried = ( $stried == false ) ? true : false;
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
587
				$additionnal_class = ($stried) ? 'wps_stried_line' : '';
588
				$output .= '<tr class="' .$additionnal_class. '">';
589
				$order_meta = get_post_meta( $order->ID, '_order_postmeta', true );
590
				$order_info = get_post_meta( $order->ID, '_order_info', true );
591
592
				if ( !empty($order_meta) ) {
593
					$output .= '<td>' .( (!empty($order_meta) && !empty($order_meta['order_date']) ) ? date( 'd-m-Y', strtotime($order_meta['order_date']) ): '' ). '</td>';
594
					$output .= '<td>' .( (!empty($order_info) && !empty($order_info['billing']) && !empty($order_info['billing']['address']) && !empty($order_info['billing']['address']['address_last_name']) && !empty($order_info['billing']['address']['address_first_name']) ) ? strtoupper($order_info['billing']['address']['address_last_name']).' '.$order_info['billing']['address']['address_first_name']: '' ). '</td>';
595
596
					$output .= '<td>' .( (!empty($order_meta['order_grand_total']) ) ? number_format( $order_meta['order_grand_total'], 2, '.', '' ).' '.wpshop_tools::wpshop_get_currency( false ) : '-' ). '</td>';
597
					$output .= '<td><span class="wps_dashboard_' .$order_meta['order_status']. '">' .__($payment_status[ $order_meta['order_status'] ], 'wpshop' ). '</span></td>';
598
					$output .= '<td>';
599
					$output .= '<a href="' .admin_url('/post.php?post=' .$order->ID. '&action=edit'). '"><img src="' .WPSHOP_MEDIAS_ICON_URL. 'icon_loupe.png" alt="' .__('See', 'wpshop'). '" /></a>';
600
601
					$invoice_ref = '';
602
					if ( !empty($order_meta['order_invoice_ref']) ) {
603
						$invoice_ref = $order_meta['order_invoice_ref'];
604
					}
605 View Code Duplication
					if ( !empty($invoice_ref) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
606
						if( !empty($order_meta) && !empty($order_meta['order_payment']) && !empty($order_meta['order_payment']['received']) ) {
607
							$invoice_ref = $order_meta['order_payment']['received'][ count($order_meta['order_payment']['received']) - 1 ]['invoice_ref'];
608
						}
609
					}
610
611
					if ( ( $order_meta['order_status'] == 'partially_paid' || $order_meta['order_status'] == 'completed' || $order_meta['order_status'] == 'shipped' ) && !empty($invoice_ref) ) {
612
						$output .= ' <a href="' .admin_url( 'admin-post.php?action=wps_invoice&order_id=' .$order->ID. '&invoice_ref&=' .$invoice_ref. '&mode=pdf' ). '"><img src="' .WPSHOP_MEDIAS_ICON_URL. 'icon_invoice.png" alt="' .__('Invoice', 'wpshop'). '" /></a>';
613
					}
614 View Code Duplication
					if ( $order_meta['order_status'] == 'shipped' ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
615
						$output .= ' <a href="'.admin_url( 'admin-post.php?action=wps_invoice&order_id=' .$order->ID. '&bon_colisage=ok&mode=pdf' ) . '"><img src="' .WPSHOP_MEDIAS_ICON_URL. 'bon_colisage_icon.png" alt="' .__('Shipping Slip', 'wpshop'). '" /></a>';
616
					}
617
					$output .= '</td>';
618
				}
619
				$output .= '</tr>';
620
			}
621
			$output .= '</table>';
622
		}
623
624
		return $output;
625
	}
626
627 View Code Duplication
	function wpshop_rss_feed() {
0 ignored issues
show
Best Practice introduced by
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...
Duplication introduced by
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...
628
		$output = '';
629
		include_once( ABSPATH . WPINC . '/feed.php' );
630
631
		$rss = fetch_feed( 'http://www.wpshop.fr/feed/' );
632
		if( ! is_wp_error( $rss ) ){
633
			$maxitems = $rss->get_item_quantity( 4 );
634
			$rss_items = $rss->get_items( 0, $maxitems );
635
		}
636
		else {
637
			$output .= '<p>' . __('WPShop News cannot be loaded', 'wpshop') . '</p>';
638
		}
639
640
		if ( $maxitems == 0 ) {
0 ignored issues
show
Bug introduced by
The variable $maxitems does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
641
			$output .= '<p>' . __('No WPShop new has been found', 'wpshop') . '</p>';
642
		}
643
		else {
644
			$output .= '<ul class="recent-orders">';
645
			foreach ( $rss_items as $item ) {
0 ignored issues
show
Bug introduced by
The variable $rss_items does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
646
				$output .= '<li><a href="' .$item->get_permalink() . '" title="' .$item->get_title(). '" target="_blank">' .$item->get_title(). '</a><br/>';
647
				$output .= $item->get_content();
648
				$output .= '</li>';
649
			}
650
			$output .= '</ul>';
651
		}
652
		echo $output;
653
	}
654
655
656
	function wpshop_rss_tutorial_videos() {
0 ignored issues
show
Best Practice introduced by
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...
657
		$ini_get_checking = ini_get( 'allow_url_fopen' );
658
		if ( $ini_get_checking != 0 ) {
659
			$content = file_get_contents('http://www.wpshop.fr/rss_video.xml');
660
			$videos_rss = new SimpleXmlElement($content);
661
			if ( !empty($videos_rss) && !empty($videos_rss->channel) ) {
662
				$videos_items = array();
663
				foreach( $videos_rss->channel->item as $i => $item ) {
664
					$videos_items[] = $item;
665
				}
666
				$rand_element = array_rand( $videos_items );
667
				$output  = '<div class="wps_dashboard_video_container">';
668
				$output .= '<div class="wps_dashboard_video_title">' .$videos_items[ $rand_element ]->title. '</div>';
669
				$output .= '<div class="wps_dashboard_video"><iframe width="400" height="290" src="' .$videos_items[ $rand_element ]->embed_link. '" frameborder="0" allowfullscreen></iframe></div>';
670
				$output .= '<div class="wps_dashboard_video_description">' .$videos_items[ $rand_element ]->description. '</div>';
671
				$output .= '</div>';
672
673
			}
674
			else {
675
				$output =__('No tutorial videos can be loaded', 'wpshop' );
676
			}
677
		}
678
		else {
679
			$output = __( 'Your servor doesn\'t allow to open external files', 'wpshop');
680
		}
681
		echo $output;
682
	}
683
684 View Code Duplication
	function wpshop_dashboard_get_changelog() {
0 ignored issues
show
Best Practice introduced by
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...
Duplication introduced by
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...
685
		$readme_file = fopen( WPSHOP_DIR.'/readme.txt', 'r' );
686
		if ( $readme_file ) {
687
			$txt = file_get_contents( WPSHOP_DIR.'/readme.txt' );
688
			$pre_change_log = explode( '== Changelog ==', $txt );
689
			$versions = explode( '= Version', $pre_change_log[1] );
690
691
			echo $versions[1];
692
		}
693
	}
694
}
695
?>
696