Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/paid-memberships-pro/includes/content.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
/*
3
+
Functions to detect member content and protect it.
4
+
*/
5
+
function pmpro_has_membership_access($post_id = NULL, $user_id = NULL, $return_membership_levels = false)
6
+
{
7
+
global $post, $wpdb, $current_user;
8
+
9
+
//get queried object in case we check against that
10
+
if(!is_admin())
11
+
$queried_object = get_queried_object();
12
+
else
13
+
$queried_object = NULL;
14
+
15
+
//use post global or queried object if no $post_id was passed in
16
+
if(!$post_id && !empty($post) && !empty($post->ID))
17
+
$post_id = $post->ID;
18
+
elseif(!$post_id && !empty($queried_object) && !empty($queried_object->ID))
19
+
$post_id = $queried_object->ID;
20
+
21
+
//no post, return true (changed from false in version 1.7.2)
22
+
if(!$post_id)
23
+
return true;
24
+
25
+
//use current user if no value is supplied
26
+
if(!$user_id)
27
+
$user_id = $current_user->ID;
28
+
29
+
//if no post or current_user object, set them up
30
+
if(isset($queried_object->ID) && !empty($queried_object->ID) && $post_id == $queried_object->ID)
31
+
$mypost = $queried_object;
32
+
elseif(isset($post->ID) && !empty($post->ID) && $post_id == $post->ID)
33
+
$mypost = $post;
34
+
else
35
+
$mypost = get_post($post_id);
36
+
37
+
if($user_id == $current_user->ID)
38
+
$myuser = $current_user;
39
+
else
40
+
$myuser = get_userdata($user_id);
41
+
42
+
//for these post types, we want to check the parent
43
+
if(isset($mypost->post_type) && in_array( $mypost->post_type, array("attachment", "revision")))
44
+
{
45
+
$mypost = get_post($mypost->post_parent);
46
+
}
47
+
48
+
// Allow plugins and themes to find the protected post
49
+
$mypost = apply_filters( 'pmpro_membership_access_post', $mypost, $myuser );
50
+
51
+
if(isset($mypost->post_type) && $mypost->post_type == "post")
52
+
{
53
+
// Get the categories for this post.
54
+
$post_terms = wp_get_post_categories( $mypost->ID );
55
+
56
+
// Get the tags for this post.
57
+
$post_terms = array_merge( $post_terms, wp_get_post_tags( $mypost->ID, array('fields' => 'ids' ) ) );
58
+
59
+
if( ! $post_terms )
60
+
{
61
+
//just check for entries in the memberships_pages table
62
+
$sqlQuery = "SELECT m.id, m.name FROM $wpdb->pmpro_memberships_pages mp LEFT JOIN $wpdb->pmpro_membership_levels m ON mp.membership_id = m.id WHERE mp.page_id = '" . esc_sql( $mypost->ID ) . "'";
63
+
}
64
+
else
65
+
{
66
+
//are any of the post categories associated with membership levels? also check the memberships_pages table
67
+
$sqlQuery = "(SELECT m.id, m.name FROM $wpdb->pmpro_memberships_categories mc LEFT JOIN $wpdb->pmpro_membership_levels m ON mc.membership_id = m.id WHERE mc.category_id IN(" . implode(",", array_map( 'intval', $post_terms ) ) . ") AND m.id IS NOT NULL) UNION (SELECT m.id, m.name FROM $wpdb->pmpro_memberships_pages mp LEFT JOIN $wpdb->pmpro_membership_levels m ON mp.membership_id = m.id WHERE mp.page_id = '" . esc_sql( $mypost->ID ) . "')";
68
+
}
69
+
}
70
+
else
71
+
{
72
+
//are any membership levels associated with this page?
73
+
$sqlQuery = "SELECT m.id, m.name FROM $wpdb->pmpro_memberships_pages mp LEFT JOIN $wpdb->pmpro_membership_levels m ON mp.membership_id = m.id WHERE mp.page_id = '" . esc_sql( $mypost->ID ) . "'";
74
+
}
75
+
76
+
77
+
$post_membership_levels = $wpdb->get_results($sqlQuery);
78
+
79
+
$post_membership_levels_ids = array();
80
+
$post_membership_levels_names = array();
81
+
82
+
if(!$post_membership_levels)
83
+
{
84
+
$hasaccess = true;
85
+
}
86
+
else
87
+
{
88
+
// Reorder the $post_membership_levels to match sorted order.
89
+
$post_membership_levels = pmpro_sort_levels_by_order( $post_membership_levels );
90
+
91
+
//we need to see if the user has access
92
+
foreach($post_membership_levels as $level)
93
+
{
94
+
$post_membership_levels_ids[] = $level->id;
95
+
$post_membership_levels_names[] = $level->name;
96
+
}
97
+
98
+
//levels found. check if this is in a feed or if the current user is in at least one of those membership levels
99
+
if(is_feed())
100
+
{
101
+
//always block restricted feeds
102
+
$hasaccess = false;
103
+
}
104
+
elseif(!empty($myuser->ID))
105
+
{
106
+
$myuser->membership_level = pmpro_getMembershipLevelForUser($myuser->ID); // kept in for legacy filter users below.
107
+
$myuser->membership_levels = pmpro_getMembershipLevelsForUser($myuser->ID);
108
+
$mylevelids = array();
109
+
foreach($myuser->membership_levels as $curlevel) {
110
+
$mylevelids[] = $curlevel->id;
111
+
}
112
+
if(count($myuser->membership_levels)>0 && count(array_intersect($mylevelids, $post_membership_levels_ids))>0)
113
+
{
114
+
//the users membership id is one that will grant access
115
+
$hasaccess = true;
116
+
}
117
+
else
118
+
{
119
+
//user isn't a member of a level with access
120
+
$hasaccess = false;
121
+
}
122
+
}
123
+
else
124
+
{
125
+
//user is not logged in and this content requires membership
126
+
$hasaccess = false;
127
+
}
128
+
}
129
+
130
+
/*
131
+
Filters
132
+
The generic filter is run first. Then if there is a filter for this post type, that is run.
133
+
*/
134
+
//general filter for all posts
135
+
$hasaccess = apply_filters("pmpro_has_membership_access_filter", $hasaccess, $mypost, $myuser, $post_membership_levels);
136
+
//filter for this post type
137
+
if( isset($mypost->post_type) && has_filter("pmpro_has_membership_access_filter_" . $mypost->post_type))
138
+
$hasaccess = apply_filters("pmpro_has_membership_access_filter_" . $mypost->post_type, $hasaccess, $mypost, $myuser, $post_membership_levels);
139
+
140
+
//return
141
+
if($return_membership_levels)
142
+
return array($hasaccess, $post_membership_levels_ids, $post_membership_levels_names);
143
+
else
144
+
return $hasaccess;
145
+
}
146
+
147
+
/**
148
+
* Filter PMPro pages from search results.
149
+
* @since 3.0 This functionality was moved out
150
+
* of the pmpro_search_filter function.
151
+
*/
152
+
function pmpro_search_filter_pmpro_pages( $query ) {
153
+
global $pmpro_pages;
154
+
155
+
// Ignore queries from the admin dashboard.
156
+
if ( $query->is_admin ) {
157
+
return $query;
158
+
}
159
+
160
+
// Ignore queries that aren't search related.
161
+
if ( ! $query->is_search ) {
162
+
return $query;
163
+
}
164
+
165
+
// Ignore post parent queries.
166
+
if ( ! empty( $query->query['post_parent'] ) ) {
167
+
return $query;
168
+
}
169
+
170
+
// We're good. Remove the PMPro pages from the results.
171
+
$pmpro_page_ids = empty( $pmpro_pages ) ? array() : array_filter( array_values( $pmpro_pages ) );
172
+
$query->set( 'post__not_in', array_merge( pmpro_get_post_not_in( $query ), $pmpro_page_ids ) );
173
+
174
+
return $query;
175
+
}
176
+
add_filter( 'pre_get_posts', 'pmpro_search_filter_pmpro_pages' );
177
+
178
+
/**
179
+
* Filter restricted posts from searches and archive queries.
180
+
*/
181
+
function pmpro_search_filter( $query ) {
182
+
global $current_user, $wpdb, $pmpro_pages;
183
+
184
+
/**
185
+
* Filter which post types to hide members-only content from search.
186
+
*
187
+
* @param array $pmpro_search_filter_post_types The post types to include in the search filter.
188
+
* The default included post types are page and post.
189
+
*
190
+
* @return array $pmpro_search_filter_post_types.
191
+
*/
192
+
$pmpro_search_filter_post_types = apply_filters( 'pmpro_search_filter_post_types', array( 'page', 'post' ) );
193
+
if ( ! is_array( $pmpro_search_filter_post_types ) ) {
194
+
$pmpro_search_filter_post_types = array( $pmpro_search_filter_post_types );
195
+
}
196
+
197
+
// Ignore queries from the admin dashboard.
198
+
if ( $query->is_admin ) {
199
+
return $query;
200
+
}
201
+
202
+
// Ignore single post queries.
203
+
if ( $query->is_singular ) {
204
+
return $query;
205
+
}
206
+
207
+
// Ignore REST API requests.
208
+
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
209
+
return $query;
210
+
}
211
+
212
+
// If post_parent is set, this is probably a menu/submenu query. Ignore it.
213
+
if ( ! empty( $query->query['post_parent'] ) ) {
214
+
return $query;
215
+
}
216
+
217
+
// If post_type is set, make sure it's in the array of post types to filter.
218
+
if ( ! empty( $query->query_vars['post_type'] ) && ! array_intersect( (array)$query->query_vars['post_type'], $pmpro_search_filter_post_types ) ) {
219
+
return $query;
220
+
}
221
+
222
+
// If posts aren't being filtered, don't filter categories either.
223
+
if ( ! in_array( 'post', $pmpro_search_filter_post_types ) && $query->is_category() ) {
224
+
return $query;
225
+
}
226
+
227
+
// If posts aren't being filtered, don't filter tags either.
228
+
if ( ! in_array( 'post', $pmpro_search_filter_post_types ) && $query->is_tag() ) {
229
+
return $query;
230
+
}
231
+
232
+
/**
233
+
* Okay. We're going to filter the search results.
234
+
* We save the array of posts to hide in a static var for cache.
235
+
* So first, check if we have a cache, and if so use that.
236
+
*/
237
+
static $final_hidden_posts = null;
238
+
if ( isset( $final_hidden_posts ) ) {
239
+
if( ! empty( $final_hidden_posts ) ) {
240
+
$query->set( 'post__not_in', array_merge( pmpro_get_post_not_in( $query ), $final_hidden_posts ) );
241
+
}
242
+
return $query;
243
+
}
244
+
245
+
/**
246
+
* No cache yet. Let's run the queries.
247
+
* Some explanation of what we're doing.
248
+
* A = All posts hidden by level.
249
+
* B = All posts hidden by category.
250
+
* C = All posts the current user has access to by level.
251
+
* D = All posts the current user has access to by category.
252
+
*
253
+
* Then the final hidden posts = (A + B) - (C + D)
254
+
*
255
+
* Then we merge and add to post__not_in.
256
+
*/
257
+
258
+
// First, figure out if their is a current user with levels.
259
+
if ( ! empty( $current_user->ID ) ) {
260
+
$levels = pmpro_getMembershipLevelsForUser( $current_user->ID );
261
+
$level_ids = ! empty( $levels ) ? wp_list_pluck( $levels, 'ID' ) : [];
262
+
} else {
263
+
$level_ids = [];
264
+
}
265
+
266
+
// Query A: All posts hidden by level
267
+
$sql_A = "SELECT DISTINCT(mp.page_id)
268
+
FROM {$wpdb->pmpro_memberships_pages} mp
269
+
LEFT JOIN {$wpdb->posts} p ON mp.page_id = p.ID
270
+
WHERE p.post_type IN('" . implode( "', '", array_map('esc_sql', $pmpro_search_filter_post_types)) . "')";
271
+
$posts_hidden_by_level = $wpdb->get_col( $sql_A );
272
+
273
+
// Query B: All posts hidden by category
274
+
$sql_B = "SELECT DISTINCT(tr.object_id)
275
+
FROM {$wpdb->term_relationships} tr
276
+
LEFT JOIN {$wpdb->posts} p ON tr.object_id = p.ID
277
+
WHERE tr.term_taxonomy_id IN(
278
+
SELECT category_id
279
+
FROM {$wpdb->pmpro_memberships_categories}
280
+
)
281
+
AND p.post_type IN('" . implode( "', '", array_map('esc_sql', $pmpro_search_filter_post_types)) . "')";
282
+
$posts_hidden_by_category = $wpdb->get_col( $sql_B );
283
+
284
+
// Query C: All posts the current user has access to by level
285
+
if ( ! empty( $level_ids ) ) {
286
+
$sql_C = "SELECT DISTINCT(mp.page_id)
287
+
FROM {$wpdb->pmpro_memberships_pages} mp
288
+
LEFT JOIN {$wpdb->posts} p ON mp.page_id = p.ID
289
+
WHERE mp.membership_id IN (" . implode(',', array_map('esc_sql', $level_ids)) . ")
290
+
AND p.post_type IN('" . implode( "', '", array_map('esc_sql', $pmpro_search_filter_post_types)) . "')";
291
+
$accessible_posts_by_level = $wpdb->get_col( $sql_C );
292
+
} else {
293
+
$accessible_posts_by_level = [];
294
+
}
295
+
296
+
// Query D: All posts the current user has access to by category
297
+
if ( ! empty ($level_ids ) ) {
298
+
$sql_D = "SELECT DISTINCT(tr.object_id)
299
+
FROM {$wpdb->term_relationships} tr
300
+
LEFT JOIN {$wpdb->posts} p ON tr.object_id = p.ID
301
+
WHERE tr.term_taxonomy_id IN(
302
+
SELECT category_id
303
+
FROM {$wpdb->pmpro_memberships_categories}
304
+
WHERE membership_id IN (" . implode(',', array_map('esc_sql', $level_ids)) . ")
305
+
) AND p.post_type IN('" . implode( "', '", array_map('esc_sql', $pmpro_search_filter_post_types)) . "')";
306
+
$accessible_posts_by_category = $wpdb->get_col ($sql_D );
307
+
} else {
308
+
$accessible_posts_by_category = [];
309
+
}
310
+
311
+
// Combine and compute final hidden posts
312
+
$hidden_posts = array_unique(array_merge($posts_hidden_by_level, $posts_hidden_by_category));
313
+
$accessible_posts = array_unique(array_merge($accessible_posts_by_level, $accessible_posts_by_category));
314
+
$final_hidden_posts = array_diff($hidden_posts, $accessible_posts);
315
+
316
+
// If we have posts to hide, add them to the query.
317
+
if( ! empty( $final_hidden_posts ) ) {
318
+
$query->set( 'post__not_in', array_merge( pmpro_get_post_not_in( $query ), $final_hidden_posts ) );
319
+
}
320
+
321
+
return $query;
322
+
}
323
+
$filterqueries = get_option("pmpro_filterqueries");
324
+
if( ! empty( $filterqueries ) ) {
325
+
add_filter( 'pre_get_posts', 'pmpro_search_filter' );
326
+
}
327
+
328
+
function pmpro_membership_content_filter( $content, $skipcheck = false ) {
329
+
global $post, $current_user;
330
+
331
+
if( ! $skipcheck ) {
332
+
$hasaccess = pmpro_has_membership_access(NULL, NULL, true);
333
+
if( is_array( $hasaccess ) ) {
334
+
//returned an array to give us the membership level values
335
+
$post_membership_levels_ids = $hasaccess[1];
336
+
$post_membership_levels_names = $hasaccess[2];
337
+
$hasaccess = $hasaccess[0];
338
+
}
339
+
}
340
+
341
+
/**
342
+
* Filter to let other plugins change how PMPro filters member content.
343
+
* If anything other than false is returned, that value will overwrite
344
+
* the $content variable and no further processing is done in this function.
345
+
*/
346
+
$content_filter = apply_filters( 'pmpro_membership_content_filter', false, $content, $hasaccess );
347
+
if ( $content_filter !== false ) {
348
+
return $content_filter;
349
+
}
350
+
351
+
if( $hasaccess ) {
352
+
//all good, return content
353
+
return $content;
354
+
} else {
355
+
//if show excerpts is set, return just the excerpt
356
+
if( get_option( "pmpro_showexcerpts" ) ) {
357
+
//show excerpt
358
+
global $post;
359
+
if( $post->post_excerpt ) {
360
+
//defined excerpt
361
+
$content = wpautop( $post->post_excerpt );
362
+
} elseif(strpos($content, "<span id=\"more-" . $post->ID . "\"></span>") !== false) {
363
+
//more tag
364
+
$pos = strpos($content, "<span id=\"more-" . $post->ID . "\"></span>");
365
+
$content = substr($content, 0, $pos);
366
+
} elseif(strpos($content, 'class="more-link">') !== false) {
367
+
//more link
368
+
$content = preg_replace("/\<a.*class\=\"more\-link\".*\>.*\<\/a\>/", "", $content);
369
+
} elseif(strpos($content, "<!-- wp:more -->") !== false) {
370
+
//more block
371
+
$pos = strpos($content, "<!-- wp:more -->");
372
+
$content = substr($content, 0, $pos);
373
+
} elseif(strpos($content, "<!--more-->") !== false) {
374
+
//more tag
375
+
$pos = strpos($content, "<!--more-->");
376
+
$content = substr($content, 0, $pos);
377
+
} else {
378
+
//auto generated excerpt. pulled from wp_trim_excerpt
379
+
$content = strip_shortcodes( $content );
380
+
$content = str_replace(']]>', ']]>', $content);
381
+
$content = wp_strip_all_tags( $content );
382
+
$excerpt_length = apply_filters('excerpt_length', 55);
383
+
$words = preg_split("/[\n\r\t ]+/", $content, $excerpt_length + 1, PREG_SPLIT_NO_EMPTY);
384
+
if ( count($words) > $excerpt_length ) {
385
+
array_pop($words);
386
+
$content = implode(' ', $words);
387
+
$content = $content . "... ";
388
+
} else {
389
+
$content = implode(' ', $words) . "... ";
390
+
}
391
+
392
+
$content = wpautop($content);
393
+
}
394
+
} else {
395
+
//else hide everything
396
+
$content = "";
397
+
}
398
+
399
+
$content = pmpro_get_no_access_message( $content, $post_membership_levels_ids, $post_membership_levels_names );
400
+
}
401
+
402
+
return $content;
403
+
}
404
+
add_filter('the_content', 'pmpro_membership_content_filter', 5);
405
+
add_filter('the_content_rss', 'pmpro_membership_content_filter', 5);
406
+
add_filter('comment_text_rss', 'pmpro_membership_content_filter', 5);
407
+
408
+
/*
409
+
If the_excerpt is called, we want to disable the_content filters so the PMPro messages aren't added to the content before AND after the excerpt.
410
+
*/
411
+
function pmpro_membership_excerpt_filter($content, $skipcheck = false) {
412
+
remove_filter('the_content', 'pmpro_membership_content_filter', 5);
413
+
$content = pmpro_membership_content_filter($content, $skipcheck);
414
+
add_filter('the_content', 'pmpro_membership_content_filter', 5);
415
+
416
+
return $content;
417
+
}
418
+
419
+
function pmpro_membership_get_excerpt_filter_start($content, $skipcheck = false) {
420
+
remove_filter('the_content', 'pmpro_membership_content_filter', 5);
421
+
return $content;
422
+
}
423
+
424
+
function pmpro_membership_get_excerpt_filter_end($content, $skipcheck = false) {
425
+
add_filter('the_content', 'pmpro_membership_content_filter', 5);
426
+
return $content;
427
+
}
428
+
add_filter('the_excerpt', 'pmpro_membership_excerpt_filter', 15);
429
+
add_filter('get_the_excerpt', 'pmpro_membership_get_excerpt_filter_start', 1);
430
+
add_filter('get_the_excerpt', 'pmpro_membership_get_excerpt_filter_end', 100);
431
+
432
+
function pmpro_comments_filter($comments, $post_id = NULL) {
433
+
global $current_user;
434
+
435
+
if(!$comments)
436
+
return $comments; //if they are closed anyway, we don't need to check
437
+
438
+
$hasaccess = pmpro_has_membership_access(NULL, NULL, true);
439
+
if( is_array( $hasaccess ) ) {
440
+
//returned an array to give us the membership level values
441
+
$post_membership_levels_ids = $hasaccess[1];
442
+
$post_membership_levels_names = $hasaccess[2];
443
+
$hasaccess = $hasaccess[0];
444
+
}
445
+
446
+
if($hasaccess)
447
+
{
448
+
//all good, return content
449
+
return $comments;
450
+
} else {
451
+
if(!$post_membership_levels_ids)
452
+
$post_membership_levels_ids = array();
453
+
454
+
if(!$post_membership_levels_names)
455
+
$post_membership_levels_names = array();
456
+
457
+
//get the correct message
458
+
if(is_feed())
459
+
{
460
+
if(is_array($comments))
461
+
return array();
462
+
else
463
+
return false;
464
+
}
465
+
elseif($current_user->ID)
466
+
{
467
+
//not a member
468
+
if(is_array($comments))
469
+
return array();
470
+
else
471
+
return false;
472
+
}
473
+
else
474
+
{
475
+
//not logged in!
476
+
if(is_array($comments))
477
+
return array();
478
+
else
479
+
return false;
480
+
}
481
+
}
482
+
return $comments;
483
+
}
484
+
add_filter("comments_array", "pmpro_comments_filter", 10, 2);
485
+
add_filter("comments_open", "pmpro_comments_filter", 10, 2);
486
+
487
+
//keep non-members from getting to certain pages (attachments, etc)
488
+
function pmpro_hide_pages_redirect() {
489
+
global $post;
490
+
491
+
if( ! is_admin() && ! empty( $post->ID ) ) {
492
+
if( $post->post_type == "attachment" ) {
493
+
//check if the user has access to the parent
494
+
if( ! pmpro_has_membership_access( $post->ID ) ) {
495
+
wp_redirect( pmpro_url( "levels" ) );
496
+
exit;
497
+
}
498
+
}
499
+
}
500
+
}
501
+
add_action( 'wp', 'pmpro_hide_pages_redirect' );
502
+
503
+
/**
504
+
* Adds custom classes to the array of post classes.
505
+
*
506
+
* pmpro-level-required = this post requires at least one level
507
+
* pmpro-level-1 = this post requires level 1
508
+
* pmpro-has-access = this post is usually locked, but the current user has access to this post
509
+
*
510
+
* @param array $classes Classes for the post element.
511
+
* @return array
512
+
*
513
+
* @since 1.8.5.4
514
+
*/
515
+
function pmpro_post_classes( $classes, $class, $post_id ) {
516
+
517
+
$post = get_post($post_id);
518
+
519
+
if(empty($post))
520
+
return $classes;
521
+
522
+
$post_levels = array();
523
+
$post_levels = pmpro_has_membership_access( $post->ID, NULL, true );
524
+
525
+
if( ! empty( $post_levels ) ) {
526
+
if( ! empty( $post_levels[1] ) ) {
527
+
$classes[] = 'pmpro-level-required';
528
+
foreach( $post_levels[1] as $post_level_id ) {
529
+
$classes[] = 'pmpro-level-' . $post_level_id;
530
+
}
531
+
}
532
+
if(!empty($post_levels[0]) && $post_levels[0] == true) {
533
+
$classes[] = 'pmpro-has-access';
534
+
} else {
535
+
$classes[] = 'pmpro-no-access';
536
+
}
537
+
}
538
+
return $classes;
539
+
}
540
+
add_filter( 'post_class', 'pmpro_post_classes', 10, 3 );
541
+
542
+
/**
543
+
* Adds custom classes to the array of body classes.
544
+
* Same as the above, but acts on the "queried object" instead of the post global.
545
+
*
546
+
* pmpro-body-level-required = this post requires at least one level
547
+
* pmpro-body-level-1 = this post requires level 1
548
+
* pmpro-body-has-access = this post is usually locked, but the current user has access to this post
549
+
*
550
+
* @param array $classes Classes for the body element.
551
+
* @return array
552
+
*
553
+
* @since 1.8.6.1
554
+
*/
555
+
function pmpro_body_classes( $classes ) {
556
+
557
+
$post = get_queried_object();
558
+
559
+
if(empty($post) || !is_singular())
560
+
return $classes;
561
+
562
+
$post_levels = array();
563
+
$post_levels = pmpro_has_membership_access($post->ID,NULL,true);
564
+
565
+
if( ! empty( $post_levels ) ) {
566
+
if( ! empty( $post_levels[1] ) ) {
567
+
$classes[] = 'pmpro-body-level-required';
568
+
foreach( $post_levels[1] as $post_level_id ) {
569
+
$classes[] = 'pmpro-body-level-' . $post_level_id;
570
+
}
571
+
}
572
+
if( ! empty( $post_levels[0] ) && $post_levels[0] == true) {
573
+
$classes[] = 'pmpro-body-has-access';
574
+
}
575
+
}
576
+
return $classes;
577
+
}
578
+
add_filter( 'body_class', 'pmpro_body_classes' );
579
+
580
+
/**
581
+
* Helper function to get the post__not_in array from a WP_Query object ensuring it is an array.
582
+
*
583
+
* @since 3.5.2
584
+
*
585
+
* @param WP_Query $query The WP_Query object.
586
+
* @return array The post__not_in array.
587
+
*/
588
+
function pmpro_get_post_not_in( $query ) {
589
+
if ( ! is_a( $query, 'WP_Query' ) ) {
590
+
return array();
591
+
}
592
+
593
+
$post_not_in = $query->get( 'post__not_in' );
594
+
if ( empty( $post_not_in ) || ! is_array( $post_not_in ) ) {
595
+
$post_not_in = array();
596
+
}
597
+
598
+
return $post_not_in;
599
+
}
600
+