Issues (1066)

includes/class-lsx-projects-scpo-engine.php (25 issues)

1
<?php
2
3
$lsx_projects_scporder = new LSX_Projects_SCPO_Engine();
4
5
/**
6
 * SCPO Engine
7
 *
8
 * @package   LSX Projects
9
 * @author    LightSpeed
10
 * @license   GPL3
11
 * @link
12
 * @copyright 2016 LightSpeed
13
 */
14
class LSX_Projects_SCPO_Engine {
15
16
	function __construct() {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for __construct.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
17
		if ( ! get_option( 'lsx_projects_scporder_install' ) ) {
18
			$this->lsx_projects_scporder_install();
19
		}
20
21
		add_action( 'admin_init', array( $this, 'refresh' ) );
22
		add_action( 'admin_init', array( $this, 'load_script_css' ) );
23
24
		add_action( 'wp_ajax_update-menu-order', array( $this, 'update_menu_order' ) );
25
26
		add_action( 'pre_get_posts', array( $this, 'lsx_projects_scporder_pre_get_posts' ) );
27
28
		add_filter( 'get_previous_post_where', array( $this, 'lsx_projects_scporder_previous_post_where' ) );
29
		add_filter( 'get_previous_post_sort', array( $this, 'lsx_projects_scporder_previous_post_sort' ) );
30
		add_filter( 'get_next_post_where', array( $this, 'lsx_projects_scporder_next_post_where' ) );
31
		add_filter( 'get_next_post_sort', array( $this, 'lsx_projects_scporder_next_post_sort' ) );
32
	}
33
34
	function lsx_projects_scporder_install() {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for lsx_projects_scporder_install.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
35
		update_option( 'lsx_projects_scporder_install', 1 );
36
	}
37
38
	function _check_load_script_css() {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for _check_load_script_css.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
39
		$active = false;
40
		$objects = $this->get_lsx_projects_scporder_options_objects();
41
42
		if ( empty( $objects ) ) {
43
			return false;
44
		}
45
46
		if ( isset( $_GET['orderby'] ) || strstr( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'action=edit' ) || strstr( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'wp-admin/post-new.php' ) ) {
0 ignored issues
show
It seems like wp_unslash($_SERVER['REQUEST_URI']) can also be of type array; however, parameter $str of sanitize_text_field() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

46
		if ( isset( $_GET['orderby'] ) || strstr( sanitize_text_field( /** @scrutinizer ignore-type */ wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'action=edit' ) || strstr( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'wp-admin/post-new.php' ) ) {
Loading history...
47
			return false;
48
		}
49
50
		if ( ! empty( $objects ) ) {
51
			if ( isset( $_GET['post_type'] ) && ! isset( $_GET['taxonomy'] ) && array_key_exists( sanitize_text_field( wp_unslash( $_GET['post_type'] ) ), $objects ) ) { // if page or custom post types
52
				$active = true;
53
			}
54
55
			if ( ! isset( $_GET['post_type'] ) && strstr( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ), 'wp-admin/edit.php' ) && array_key_exists( 'post', $objects ) ) { // if post
56
				$active = true;
57
			}
58
		}
59
60
		return $active;
61
	}
62
63
	function load_script_css() {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for load_script_css.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
64
		if ( $this->_check_load_script_css() ) {
65
			wp_enqueue_script( 'scporderjs', LSX_PROJECTS_URL . 'assets/js/scporder.min.js', array( 'jquery', 'jquery-ui-sortable' ), null, true );
66
67
			$scporderjs_params = array(
68
				'ajax_url' => admin_url( 'admin-ajax.php' ),
69
				'ajax_nonce' => wp_create_nonce( 'scporder' ),
70
			);
71
72
			wp_localize_script( 'scporderjs', 'scporderjs_params', $scporderjs_params );
73
74
			wp_enqueue_style( 'scporder', LSX_PROJECTS_URL . 'assets/css/scporder.css', array(), null );
75
		}
76
	}
77
78
	function refresh() {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for refresh.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
79
		global $wpdb;
80
81
		$objects = $this->get_lsx_projects_scporder_options_objects();
82
83
		if ( ! empty( $objects ) ) {
84
			foreach ( $objects as $object => $object_data ) {
85
				$result = $wpdb->get_results($wpdb->prepare("
86
					SELECT count(*) as cnt, max(menu_order) as max, min(menu_order) as min
87
					FROM $wpdb->posts
88
					WHERE post_type = '%s' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
89
				", $object));
90
91
				if ( 0 == $result[0]->cnt || $result[0]->cnt == $result[0]->max ) {
92
					continue;
93
				}
94
95
				$results = $wpdb->get_results( $wpdb->prepare("
96
					SELECT ID
97
					FROM $wpdb->posts
98
					WHERE post_type = '%s' AND post_status IN ('publish', 'pending', 'draft', 'private', 'future')
99
					ORDER BY menu_order ASC
100
				", $object ) );
101
102
				foreach ( $results as $key => $result ) {
103
					$wpdb->update(
104
						$wpdb->posts,
105
						array(
106
							'menu_order' => $key + 1,
107
						),
108
						array(
109
							'ID' => $result->ID,
110
						)
111
					);
112
				}
113
			}
114
		}
115
	}
116
117
	function update_menu_order() {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for update_menu_order.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
118
		check_ajax_referer( 'scporder', 'security' );
119
120
		global $wpdb;
121
122
		parse_str( sanitize_text_field( wp_unslash( $_POST['order'] ) ), $data );
123
124
		if ( ! is_array( $data ) ) {
125
			return false;
126
		}
127
128
		$id_arr = array();
129
130
		foreach ( $data as $key => $values ) {
131
			foreach ( $values as $position => $id ) {
132
				$id_arr[] = $id;
133
			}
134
		}
135
136
		$menu_order_arr = array();
137
138
		foreach ( $id_arr as $key => $id ) {
139
			$results = $wpdb->get_results( "SELECT menu_order FROM $wpdb->posts WHERE ID = " . intval( $id ) );
140
141
			foreach ( $results as $result ) {
142
				$menu_order_arr[] = $result->menu_order;
143
			}
144
		}
145
146
		sort( $menu_order_arr );
147
148
		foreach ( $data as $key => $values ) {
149
			foreach ( $values as $position => $id ) {
150
				$wpdb->update(
151
					$wpdb->posts,
152
					array(
153
						'menu_order' => $menu_order_arr[ $position ],
154
					),
155
					array(
156
						'ID' => intval( $id ),
157
					)
158
				);
159
			}
160
		}
161
	}
162
163
	function lsx_projects_scporder_previous_post_where( $where ) {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for lsx_projects_scporder_previous_post_where.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
164
		global $post;
165
166
		$objects = $this->get_lsx_projects_scporder_options_objects();
167
168
		if ( empty( $objects ) ) {
169
			return $where;
170
		}
171
172
		if ( isset( $post->post_type ) && array_key_exists( $post->post_type, $objects ) ) {
173
			$current_menu_order = $post->menu_order;
174
			$where = "WHERE p.menu_order > '" . $current_menu_order . "' AND p.post_type = '" . $post->post_type . "' AND p.post_status = 'publish'";
175
		}
176
177
		return $where;
178
	}
179
180
	function lsx_projects_scporder_previous_post_sort( $orderby ) {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for lsx_projects_scporder_previous_post_sort.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
181
		global $post;
182
183
		$objects = $this->get_lsx_projects_scporder_options_objects();
184
185
		if ( empty( $objects ) ) {
186
			return $orderby;
187
		}
188
189
		if ( isset( $post->post_type ) && array_key_exists( $post->post_type, $objects ) ) {
190
			$orderby = 'ORDER BY p.menu_order ASC LIMIT 1';
191
		}
192
193
		return $orderby;
194
	}
195
196
	function lsx_projects_scporder_next_post_where( $where ) {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for lsx_projects_scporder_next_post_where.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
197
		global $post;
198
199
		$objects = $this->get_lsx_projects_scporder_options_objects();
200
201
		if ( empty( $objects ) ) {
202
			return $where;
203
		}
204
205
		if ( isset( $post->post_type ) && array_key_exists( $post->post_type, $objects ) ) {
206
			$current_menu_order = $post->menu_order;
207
			$where = "WHERE p.menu_order < '" . $current_menu_order . "' AND p.post_type = '" . $post->post_type . "' AND p.post_status = 'publish'";
208
		}
209
210
		return $where;
211
	}
212
213
	function lsx_projects_scporder_next_post_sort( $orderby ) {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for lsx_projects_scporder_next_post_sort.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
214
		global $post;
215
216
		$objects = $this->get_lsx_projects_scporder_options_objects();
217
218
		if ( empty( $objects ) ) {
219
			return $orderby;
220
		}
221
222
		if ( isset( $post->post_type ) && array_key_exists( $post->post_type, $objects ) ) {
223
			$orderby = 'ORDER BY p.menu_order DESC LIMIT 1';
224
		}
225
226
		return $orderby;
227
	}
228
229
	function lsx_projects_scporder_pre_get_posts( $wp_query ) {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for lsx_projects_scporder_pre_get_posts.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
230
		$objects = $this->get_lsx_projects_scporder_options_objects();
231
232
		if ( empty( $objects ) ) {
233
			return false;
234
		}
235
236
		if ( is_admin() ) {
237
			if ( isset( $wp_query->query['post_type'] ) && ! isset( $_GET['orderby'] ) ) {
238
				if ( array_key_exists( $wp_query->query['post_type'], $objects ) ) {
239
					$wp_query->set( 'orderby', 'menu_order' );
240
					$wp_query->set( 'order', 'ASC' );
241
				}
242
			}
243
		} else {
244
			$active = false;
245
246
			if ( isset( $wp_query->query['post_type'] ) ) {
247
				if ( ! is_array( $wp_query->query['post_type'] ) ) {
248
					if ( array_key_exists( $wp_query->query['post_type'], $objects ) ) {
249
						$active = true;
250
					}
251
				}
252
			} else {
253
				if ( array_key_exists( 'post', $objects ) ) {
254
					$active = true;
255
				}
256
			}
257
258
			if ( ! $active ) {
259
				return false;
260
			}
261
262
			if ( isset( $wp_query->query['suppress_filters'] ) ) {
263
				if ( $wp_query->get( 'orderby' ) == 'date' ) {
264
					$wp_query->set( 'orderby', 'menu_order' );
265
				}
266
267
				if ( $wp_query->get( 'order' ) == 'DESC' ) {
268
					$wp_query->set( 'order', 'ASC' );
269
				}
270
			} else {
271
				if ( ! $wp_query->get( 'orderby' ) ) {
272
					$wp_query->set( 'orderby', 'menu_order' );
273
				}
274
275
				if ( ! $wp_query->get( 'order' ) ) {
276
					$wp_query->set( 'order', 'ASC' );
277
				}
278
			}
279
		}
280
	}
281
282
	function get_lsx_projects_scporder_options_objects() {
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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for get_lsx_projects_scporder_options_objects.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
283
		return array(
284
			'project' => esc_html_x( 'Project', 'post type singular name', 'lsx-project' ),
285
		);
286
	}
287
288
}
289
290
/**
291
 * SCP Order Uninstall hook
292
 */
293
register_uninstall_hook( __FILE__, 'lsx_projects_scporder_uninstall' );
294
295
function lsx_projects_scporder_uninstall() {
296
	global $wpdb;
297
298
	if ( function_exists( 'is_multisite' ) && is_multisite() ) {
299
		$curr_blog = $wpdb->blogid;
300
		$blogids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
301
302
		foreach ( $blogids as $blog_id ) {
303
			switch_to_blog( $blog_id );
304
			lsx_projects_scporder_uninstall_db();
305
		}
306
307
		switch_to_blog( $curr_blog );
308
	} else {
309
		lsx_projects_scporder_uninstall_db();
310
	}
311
}
312
313
function lsx_projects_scporder_uninstall_db() {
314
	delete_option( 'lsx_projects_scporder_install' );
315
}
316