Passed
Push — master ( aaaeb8...fae2ce )
by Joseph
07:18 queued 10s
created

Metabox::isPostPublic()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
nc 3
nop 1
dl 0
loc 12
rs 9.8666
c 2
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the Subway WordPress Plugin Package.
4
 * This file contains the class which handles the metabox of the plugin.
5
 *
6
 * (c) Joseph G <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * Props: Jasper Jardin
12
 *
13
 * PHP Version 5.4
14
 *
15
 * @category Subway\Metabox
16
 * @package  Subway
17
 * @author   Joseph G. <[email protected]>
18
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
19
 * @version  GIT:github.com/codehaiku/subway
20
 * @link     github.com/codehaiku/subway The Plugin Repository
21
 */
22
23
namespace Subway;
24
25
if ( ! defined( 'ABSPATH' ) ) {
26
	return;
27
}
28
29
/**
30
 * Subway Metabox methods.
31
 *
32
 * @category Subway\Metabox
33
 * @package  Subway
34
 * @author   Jasper J. <[email protected]>
35
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
36
 * @link     github.com/codehaiku/subway The Plugin Repository
37
 * @since    2.0.9
38
 */
39
final class Metabox {
40
41
42
	/**
43
	 * Subway visibility meta value,
44
	 *
45
	 * @since 2.0.9
46
	 * @const string VISIBILITY_METAKEY
47
	 */
48
	const VISIBILITY_METAKEY = 'subway_visibility_meta_key';
49
50
	/**
51
	 * Registers and update metabox with its intended method below.
52
	 *
53
	 * @since  2.0.9
54
	 * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
55
	 */
56
	public function __construct() {
57
58
		add_action( 'add_meta_boxes', array( $this, 'addMetabox' ) );
59
		add_action( 'save_post', array( $this, 'saveMetaboxValues' ) );
60
		add_filter( 'the_content', array( $this, 'showContentToAllowedRoles' ) );
61
62
		return $this;
0 ignored issues
show
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
63
	}
64
65
	/**
66
	 * Initialize metabox
67
	 *
68
	 * @since  2.0.9
69
	 * @access public
70
	 * @return void
71
	 */
72
	public static function initMetabox() {
73
74
		new Metabox();
75
	}
76
77
	/**
78
	 * Initialize metabox
79
	 *
80
	 * @since  2.0.9
81
	 * @access public
82
	 * @return void
83
	 */
84
	public function addMetabox() {
85
86
		$post_types = $this->getPostTypes();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $post_types is correct as $this->getPostTypes() (which targets Subway\Metabox::getPostTypes()) 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...
87
88
		foreach ( $post_types as $post_type => $value ) {
0 ignored issues
show
Bug introduced by
The expression $post_types of type null is not traversable.
Loading history...
89
			add_meta_box(
90
				'subway_visibility_metabox',
91
				esc_html__( 'Subway: Visibility Option', 'subway' ),
92
				array( $this, 'visibilityMetabox' ),
93
				$post_type,
94
				'side',
95
				'high'
96
			);
97
		}
98
	}
99
100
	/**
101
	 * This method displays the Subway Visibility checkbox.
102
	 *
103
	 * @param object $post Contains data from the current post.
104
	 *
105
	 * @since  2.0.9
106
	 * @access public
107
	 * @return void
108
	 */
109
	public function visibilityMetabox( $post ) {
110
111
		$howto = __(
112
			'Choose the accessibility of this page from the options above.',
113
			'subway'
114
		);
115
116
		$private_setting_label = __( 'Members Only', 'subway' );
0 ignored issues
show
Unused Code introduced by
$private_setting_label is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
117
118
		$is_post_private         = self::isPostPrivate( $post->ID );
119
120
		// Make sure the form request comes from WordPress
121
		wp_nonce_field( basename( __FILE__ ),  'subway_post_visibility_nonce' );
122
123
		// Disable the options (radio) when site is selected as public
124
		?>
125
		
126
		<?php if ( ! Options::isPublicSite() ) :  ?>
127
		<?php // Site is private. Give them some Beer! ?>
128
			<p>
129
				<label class="subway-visibility-settings-checkbox-label" for="subway-visibility-public">
130
					<input type="radio" class="subway-visibility-settings-radio" id="subway-visibility-public" name="subway-visibility-settings" value="public" <?php echo checked( false, $is_post_private, false ); ?>>
131
					<?php esc_html_e( 'Public', 'subway' ) ?>
132
				</label>
133
			</p>
134
			<p>
135
				<label class="subway-visibility-settings-checkbox-label" for="subway-visibility-private">
136
					<input type="radio" class="subway-visibility-settings-radio" id="subway-visibility-private" name="subway-visibility-settings"
137
					value="private" <?php echo checked( true, $is_post_private, false ); ?>>
138
					<?php esc_html_e( 'Members Only', 'subway' ) ?>
139
				 </label>
140
			</p>
141
			<div id="subway-roles-access-visibility-fields" class="hidden">
142
				<dl>
143
					<?php $post_allowed_user_roles = self::getAllowedUserRoles( $post->ID ); ?>
144
					<?php $editable_roles = get_editable_roles(); ?>
145
					<?php // Remove administrator for editable roles. ?>
146
					<?php unset( $editable_roles['administrator'] ); ?>
147
					<?php foreach ( $editable_roles as $role_name => $role_info ) { ?>
148
						<dt>
149
							<?php $id = 'subway-visibility-settings-user-role-' . esc_html( $role_name ); ?>
150
							<label for="<?php echo esc_attr( $id ); ?>">
151
							<?php if ( is_array( $post_allowed_user_roles ) && in_array( $role_name, $post_allowed_user_roles ) ) { ?>
152
								<?php $checked = 'checked'; ?>
153
							<?php } else { ?>
154
								<?php if ( false === $post_allowed_user_roles ) { ?>
155
									<?php $checked = 'checked'; ?>
156
								<?php } else { ?>
157
										<?php $checked = ''; ?>
158
								<?php } ?>
159
							<?php } ?>
160
							<input <?php echo esc_attr( $checked ); ?> id="<?php echo esc_attr( $id ); ?>" type="checkbox" 
161
							name="subway-visibility-settings-user-role[]" class="subway-visibility-settings-role-access" value="<?php echo esc_attr( $role_name ); ?>" />
162
								<?php echo esc_html( $role_info['name'] ); ?>
163
							</label>
164
						</dt>
165
					<?php } ?>
166
					<p class="howto"><?php echo esc_html_e( 'Uncheck the user roles that you do not want to have access to this content','subway' ); ?></p>
167
				</dl>
168
			</div>
169
			<script>
170
				jQuery(document).ready(function(){
171
					'use strict';
172
					if ( $('#subway-visibility-private').is(':checked') ) {
173
						$('#subway-roles-access-visibility-fields').css('display', 'block');
174
					}
175
					$('.subway-visibility-settings-radio').click(function(){
176
						$('#subway-roles-access-visibility-fields').css('display', 'none');
177
						if ( $('#subway-visibility-private').is(':checked') ) {
178
							$('#subway-roles-access-visibility-fields').css('display', 'block');
179
						}
180
					});
181
				});
182
			</script>
183
			<p class="howto"><?php echo esc_html( $howto ); ?></p>
184
		<?php else : ?>
185
			<?php // Site is public! Explain to them ?>
186
			<p><em>
187
				<?php esc_html_e( 'You have chosen to make your site public inside Settings > Subway. Make your site private so that you can select visibility options.', 'subway' ); ?>
188
			</em>
189
			</p>
190
		<?php endif; ?>
191
		<?php
192
	}
193
194
	/**
195
	 * This method verify if nonce is valid then updates a post_meta.
196
	 *
197
	 * @param integer $post_id Contains ID of the current post.
198
	 *
199
	 * @since  2.0.9
200
	 * @access public
201
	 * @return boolean false Returns false if nonce is not valid.
202
	 */
203
	public function saveVisibilityMetabox( $post_id = '' ) {
204
205
		$public_posts     = Options::getPublicPostsIdentifiers();
206
207
		$posts_implode    = '';
0 ignored issues
show
Unused Code introduced by
$posts_implode is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
208
209
		$visibility_field = 'subway-visibility-settings';
210
211
		$visibility_nonce = filter_input(
212
			INPUT_POST, 'subway_post_visibility_nonce',
213
			FILTER_SANITIZE_STRING
214
		);
215
216
		$post_visibility = filter_input(
217
			INPUT_POST,  $visibility_field,
218
			FILTER_SANITIZE_STRING
219
		);
220
221
		$is_valid_visibility_nonce = self::isNonceValid(
222
			$visibility_nonce
223
		);
224
225
		$allowed_roles = filter_input( INPUT_POST, 'subway-visibility-settings-user-role', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
226
227
		// verify taxonomies meta box nonce
228
		if ( false === $is_valid_visibility_nonce ) {
229
			return;
230
		}
231
		if ( empty( $allowed_roles ) ) {
232
			$allowed_roles = array();
233
		}
234
235
		// Update user roles.
236
		update_post_meta( $post_id, 'subway-visibility-settings-allowed-user-roles', $allowed_roles );
237
238
		if ( ! empty( $post_visibility ) ) {
239
			if ( ! empty( $post_id ) ) {
240
				if ( 'public' === $post_visibility ) {
241
					if ( ! in_array( $post_id, $public_posts ) ) {
242
						array_push( $public_posts, $post_id );
243
					}
244
				}
245
				if ( 'private' === $post_visibility ) {
246
					unset( $public_posts[ array_search( $post_id, $public_posts ) ] );
247
				}
248
			}
249
		}
250
251
		if ( ! empty( $post_id ) ) {
252
			$posts_implode = implode( ', ', $public_posts );
253
254
			if ( 'inherit' !== get_post_status( $post_id ) ) {
255
256
				if ( true === $is_valid_visibility_nonce ) {
257
					update_option( 'subway_public_post', $posts_implode );
258
					update_post_meta(
259
						$post_id,
260
						self::VISIBILITY_METAKEY,
261
						$post_visibility
262
					);
263
				}
264
			}
265
		}
266
	}
267
268
	/**
269
	 * This method runs the methods that handles the update for a post_meta.
270
	 *
271
	 * @param integer $post_id Contains ID of the current post.
272
	 *
273
	 * @since  2.0.9
274
	 * @access public
275
	 * @return boolean false Returns false if nonce is not valid.
276
	 */
277
	public function saveMetaboxValues( $post_id ) {
278
279
		$this->saveVisibilityMetabox( $post_id );
280
		return;
281
	}
282
283
	/**
284
	 * Initialize metabox arguments.
285
	 *
286
	 * @param array  $args   The arguments for the get_post_types().
287
	 * @param string $output Your desired output for the data.
288
	 *
289
	 * @since  2.0.9
290
	 * @access public
291
	 * @return void
292
	 */
293
	public static function getPostTypes( $args = '', $output = '' ) {
294
295
		if ( empty( $args ) ) {
296
			$args = array(
297
			'public'   => true,
298
			);
299
			$output = 'names';
300
		}
301
302
		$post_types = get_post_types( $args, $output );
303
304
		return $post_types;
305
	}
306
307
	/**
308
	 * This method verify if nonce is valid.
309
	 *
310
	 * @param mixed $nonce the name of a metabox nonce.
311
	 *
312
	 * @since  2.0.9
313
	 * @access public
314
	 * @return boolean true Returns true if nonce is valid.
315
	 */
316
	public function isNonceValid( $nonce ) {
317
318
		if ( ! isset( $nonce ) || ! wp_verify_nonce( $nonce, basename( __FILE__ ) ) ) {
319
			return;
320
		}
321
322
		return true;
323
	}
324
325
	/**
326
	 * Checks if a post is set to private.
327
	 *
328
	 * @param integer $post_id Contains ID of the current post.
329
	 *
330
	 * @since  2.0.9
331
	 * @access public
332
	 * @return boolean true Returns true if post is private. Otherwise false.
333
	 */
334
	public static function isPostPrivate( $post_id ) {
335
336
		$meta_value = '';
0 ignored issues
show
Unused Code introduced by
$meta_value is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
337
338
		if ( ! empty( $post_id ) ) {
339
			$meta_value = get_post_meta( $post_id, self::VISIBILITY_METAKEY, true );
340
341
			// New page or old pages that don't have Subway'\ Visibility Options
342
			if ( empty( $meta_value ) ) {
343
				// Get the value from the general settings (Settings > Subway)
344
				$is_site_public = Options::isPublicSite();
345
				if ( ! $is_site_public ) {
346
					// It's private.
347
					return true;
348
				}
349
			}
350
			if ( 'private' === $meta_value ) {
351
				return true;
352
			}
353
		}
354
355
		return false;
356
	}
357
358
	/**
359
	 * Checks if a post is set to public.
360
	 *
361
	 * @param integer $post_id Contains ID of the current post.
362
	 *
363
	 * @since  2.0.9
364
	 * @access public
365
	 * @return boolean true Returns true if post is public. Otherwise false.
366
	 */
367
	public static function isPostPublic( $post_id ) {
368
369
		$public_post = Options::getPublicPostsIdentifiers();
370
371
		if ( ! empty( $post_id ) ) {
372
			if ( ! in_array( $post_id, $public_post, true ) ) {
373
				return true;
374
			}
375
		}
376
377
		return false;
378
	}
379
380
	/**
381
	 * Get the allowed users roles
382
	 *
383
	 * @param  integer $post_id The post ID.
384
	 * @return mixed Boolean false if metadata does not exists. Otherwise, return the array value of meta.
385
	 */
386
	public static function getAllowedUserRoles( $post_id = 0 ) {
387
388
		$allowed_roles = array();
389
390
		if ( ! empty( $post_id ) ) {
391
			if ( metadata_exists( 'post', $post_id, 'subway-visibility-settings-allowed-user-roles' ) ) {
392
				$allowed_roles = get_post_meta( $post_id, 'subway-visibility-settings-allowed-user-roles', true );
393
				if ( ! is_null( $allowed_roles ) ) {
394
					return $allowed_roles;
395
				} else {
396
					return false;
397
				}
398
			} else {
399
				return false;
400
			}
401
		}
402
403
		return $allowed_roles;
404
	}
405
406
	/**
407
	 * Check if the current user has role for the current content.
408
	 *
409
	 * @param  string $content The content of the post.
410
	 * @return string The content of the post.
411
	 */
412
	public function showContentToAllowedRoles( $content ) {
413
414
		$post_id = get_the_ID();
415
		$allowed_user_roles = self::getAllowedUserRoles( $post_id );
416
417
		if ( ! is_singular() && is_main_query() ) {
418
			return $content;
419
		}
420
421
		if ( is_user_logged_in() ) {
422
423
			$user = wp_get_current_user();
424
425
			if ( ! is_array( $user->roles ) ) {
426
				$user->roles = (array) $user->roles;
427
			}
428
429
			$current_user_role = end( $user->roles );
430
431
			$no_privilege = '<div class="subway-role-not-allowed"><p>' . apply_filters( 'subway-content-restricted-to-role', esc_html__( 'You do not have the right privilege or role to view this page.', 'subway' ) ) . '</p></div>';
432
433
			// Restrict access to non admins only.
434
			if ( ! current_user_can( 'manage_options' ) ) {
435
				if ( is_array( $allowed_user_roles ) ) {
436
					if ( ! in_array( $current_user_role, $allowed_user_roles ) ) {
437
						return $no_privilege;
438
					}
439
				}
440
			}
441
442
			// Return the content if the post is not yet saved.
443
			if ( false === $allowed_user_roles ) {
444
				return $content;
445
			}
446
		}
447
448
		return $content;
449
450
	}
451
452
}
453