From 5461e735595029a8015cc1aaac303cf98a780c6a Mon Sep 17 00:00:00 2001 From: JasWSInc Date: Tue, 7 Oct 2014 17:24:08 -0800 Subject: [PATCH] General cleanup/maintenance. URI restrictions caSe sensitivity. See: websharks/s2member#354 --- s2member/includes/menu-pages/res-ops.inc.php | 1193 +++++++++--------- 1 file changed, 603 insertions(+), 590 deletions(-) diff --git a/s2member/includes/menu-pages/res-ops.inc.php b/s2member/includes/menu-pages/res-ops.inc.php index c246e586..a5f7591f 100644 --- a/s2member/includes/menu-pages/res-ops.inc.php +++ b/s2member/includes/menu-pages/res-ops.inc.php @@ -1,661 +1,674 @@ ' . "\n"; + public function __construct() + { + echo '
'."\n"; - echo '
'."\n"; - c_ws_plugin__s2member_menu_pages_tb::display (); - echo '
'."\n"; + echo '
'."\n"; + c_ws_plugin__s2member_menu_pages_tb::display(); + echo '
'."\n"; - echo '

Restriction Options

' . "\n"; + echo '

Restriction Options

'."\n"; - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; + echo '
'."\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo '' . "\n"; + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; - do_action("ws_plugin__s2member_during_res_ops_page_before_left_sections", get_defined_vars ()); + do_action("ws_plugin__s2member_during_res_ops_page_before_left_sections", get_defined_vars()); - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_post_level_access", true, get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_post_level_access", get_defined_vars ()); + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_post_level_access", TRUE, get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_post_level_access", get_defined_vars()); - echo '
' . "\n"; + echo '
'."\n"; - echo '
' . "\n"; - echo '

Post Level Access Restrictions (optional)

' . "\n"; - echo '

Here you can specify Posts that are restricted to certain Membership Access Levels. s2Member also supports Custom Post Types here. If you have a theme or plugin installed, which has enabled Custom Post Types (i.e. Music/Videos or something else), you can put the IDs for those Posts here.

' . "\n"; - echo '

*Note* Protecting individual Posts, ONLY protects the Permalinks for those Posts. It is still possible for excerpts of protected content to be seen in search results generated by WordPress, feeds, and Archive views; such as your Home Page, inside a Category listing, or through other queries formulated by your theme. This is the intended functionality. Excerpts are a great way to "tease" public visitors. In other words, public visitors may have access to excerpts introduced by your theme, but any attempt to view the full Post (i.e. the Permalink) will result in an automatic redirect to your Membership Options Page; requiring registration.

' . "\n"; - echo '

*Note* If you would like to protect many Posts at once (including Archive views), you can use Category Level Restrictions, Tag Level Restrictions, or have a look down below at s2Member\'s options for "Alternative View Protection", which deals with search results, as well as feeds.

' . "\n"; - echo ((!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) && empty($GLOBALS["WS_PLUGIN__"]["wp_show_ids"])) ? '

*Tip* Can\'t find your Post IDs? Get WP Show IDs.

' . "\n" : ''; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_post_level_access", get_defined_vars ()); + echo '
'."\n"; + echo '

Post Level Access Restrictions (optional)

'."\n"; + echo '

Here you can specify Posts that are restricted to certain Membership Access Levels. s2Member also supports Custom Post Types here. If you have a theme or plugin installed, which has enabled Custom Post Types (i.e. Music/Videos or something else), you can put the IDs for those Posts here.

'."\n"; + echo '

*Note* Protecting individual Posts, ONLY protects the Permalinks for those Posts. It is still possible for excerpts of protected content to be seen in search results generated by WordPress, feeds, and Archive views; such as your Home Page, inside a Category listing, or through other queries formulated by your theme. This is the intended functionality. Excerpts are a great way to "tease" public visitors. In other words, public visitors may have access to excerpts introduced by your theme, but any attempt to view the full Post (i.e. the Permalink) will result in an automatic redirect to your Membership Options Page; requiring registration.

'."\n"; + echo '

*Note* If you would like to protect many Posts at once (including Archive views), you can use Category Level Restrictions, Tag Level Restrictions, or have a look down below at s2Member\'s options for "Alternative View Protection", which deals with search results, as well as feeds.

'."\n"; + echo ((!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) && empty($GLOBALS["WS_PLUGIN__"]["wp_show_ids"])) ? '

*Tip* Can\'t find your Post IDs? Get WP Show IDs.

'."\n" : ''; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_post_level_access", get_defined_vars()); - echo '' . "\n"; - echo '' . "\n"; + echo '
'."\n"; + echo ''."\n"; - for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++) - { - echo '' . "\n"; + for($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++) + { + echo ''."\n"; - echo '' . "\n"; + echo ''."\n"; - echo '' . "\n"; - echo '' . "\n"; + echo ''."\n"; + echo ''."\n"; - echo '' . "\n"; + echo ''."\n"; - echo '' . "\n"; - } + echo ''."\n"; + } - echo '' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo ''."\n"; + echo ''."\n"; + echo '
' . "\n"; - echo '
' . "\n"; - echo 'Post IDs in comma-delimited format. Example: 1,2,3,34,8,21 — or you can type: all.
' . "\n"; - echo 'You can also include all Post IDs of a specific Post Type. Ex: 1,2,3,34,all-newspapers.
' . "\n"; - echo '(which protects several Post IDs, and all Posts of type: newspaper)' . "\n"; - echo '
'."\n"; + echo '
'."\n"; + echo 'Post IDs in comma-delimited format. Example: 1,2,3,34,8,21 — or you can type: all.
'."\n"; + echo 'You can also include all Post IDs of a specific Post Type. Ex: 1,2,3,34,all-newspapers.
'."\n"; + echo '(which protects several Post IDs, and all Posts of type: newspaper)'."\n"; + echo '
' . "\n"; - echo '
' . "\n"; + echo '
'."\n"; + echo ''."\n"; - echo '' . "\n"; + echo ''."\n"; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_post_level_access", get_defined_vars ()); - } + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_post_level_access", get_defined_vars()); + } + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_page_level_access", TRUE, get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_page_level_access", get_defined_vars()); - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_page_level_access", true, get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_page_level_access", get_defined_vars ()); + echo '
'."\n"; - echo '
' . "\n"; + echo '
'."\n"; + echo '

Page Level Access Restrictions (optional)

'."\n"; + echo '

Here you can specify Pages that are restricted to certain Membership Access Levels.

'."\n"; + echo ((!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) && empty($GLOBALS["WS_PLUGIN__"]["wp_show_ids"])) ? '

*Tip* Can\'t find your Page IDs? Get WP Show IDs.

'."\n" : ''; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_page_level_access", get_defined_vars()); - echo '
' . "\n"; - echo '

Page Level Access Restrictions (optional)

' . "\n"; - echo '

Here you can specify Pages that are restricted to certain Membership Access Levels.

' . "\n"; - echo ((!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) && empty($GLOBALS["WS_PLUGIN__"]["wp_show_ids"])) ? '

*Tip* Can\'t find your Page IDs? Get WP Show IDs.

' . "\n" : ''; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_page_level_access", get_defined_vars ()); + echo ''."\n"; + echo ''."\n"; - echo '
' . "\n"; - echo '' . "\n"; + for($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++) + { + echo ''."\n"; - for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++) - { - echo '' . "\n"; + echo ''."\n"; - echo '' . "\n"; + echo ''."\n"; + echo ''."\n"; - echo '' . "\n"; - echo '' . "\n"; + echo ''."\n"; - echo '' . "\n"; + echo ''."\n"; + } - echo '' . "\n"; - } + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '' . "\n"; - echo '' . "\n"; - echo '
'."\n"; + echo '
'."\n"; + echo 'Page IDs in comma-delimited format. Example: 1,2,3,34,8,21 — or you can type: all.'."\n"; + echo '
' . "\n"; - echo '
' . "\n"; - echo 'Page IDs in comma-delimited format. Example: 1,2,3,34,8,21 — or you can type: all.' . "\n"; - echo '
'."\n"; + echo '
'."\n"; - echo '
' . "\n"; - echo '
' . "\n"; + echo ''."\n"; - echo '' . "\n"; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_page_level_access", get_defined_vars()); + } + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_tag_level_access", TRUE, get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_tag_level_access", get_defined_vars()); - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_page_level_access", get_defined_vars ()); - } + echo '
'."\n"; - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_tag_level_access", true, get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_tag_level_access", get_defined_vars ()); + echo '
'."\n"; + echo '

Tag Level Access Restrictions (optional)

'."\n"; + echo '

Here you can specify Tags that are restricted to certain Membership Access Levels. This is very similar to Category Level Access. When you restrict access to a Tag Archive, it also restricts access to any Post having that Tag; even if a Post has other Tags. *Tip* ... Tags can be applied to any Post, without affecting your Category structure at all. If you\'d like to use Tags with Pages, get Page Tagger.

'."\n"; + echo '

Tags are caSe sensitive. The Tag members only is NOT the same as Members Only.

'."\n"; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_tag_level_access", get_defined_vars()); - echo '
' . "\n"; + echo ''."\n"; + echo ''."\n"; - echo '
' . "\n"; - echo '

Tag Level Access Restrictions (optional)

' . "\n"; - echo '

Here you can specify Tags that are restricted to certain Membership Access Levels. This is very similar to Category Level Access. When you restrict access to a Tag Archive, it also restricts access to any Post having that Tag; even if a Post has other Tags. *Tip* ... Tags can be applied to any Post, without affecting your Category structure at all. If you\'d like to use Tags with Pages, get Page Tagger.

' . "\n"; - echo '

Tags are caSe sensitive. The Tag members only is NOT the same as Members Only.

' . "\n"; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_tag_level_access", get_defined_vars ()); + for($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++) + { + echo '
'."\n"; - echo '
' . "\n"; - echo '' . "\n"; + echo ''."\n"; - for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++) - { - echo '' . "\n"; + echo ''."\n"; + echo ''."\n"; - echo '' . "\n"; + echo ''."\n"; - echo '' . "\n"; - echo '' . "\n"; + echo ''."\n"; + } - echo '' . "\n"; + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '
' . "\n"; - echo '' . "\n"; - echo ''."\n"; + echo '
'."\n"; + echo 'Tags in comma-delimited format. Example: '.(($n === 0) ? 'free,subscribers only' : 'members,members only').' — or you can type: all.'."\n"; + echo '
' . "\n"; - echo '
' . "\n"; - echo 'Tags in comma-delimited format. Example: ' . (($n === 0) ? 'free,subscribers only' : 'members,members only') . ' — or you can type: all.' . "\n"; - echo '
'."\n"; + echo '
'."\n"; - echo '' . "\n"; - } + echo '
'."\n"; - echo '' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_tag_level_access", get_defined_vars()); + } + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_category_level_access", TRUE, get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_category_level_access", get_defined_vars()); - echo '' . "\n"; + echo '
'."\n"; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_tag_level_access", get_defined_vars ()); - } + echo '
'."\n"; + echo '

Category Level Access Restrictions (optional)

'."\n"; + echo '

Here you can specify Categories that are restricted to certain Membership Access Levels. Category restrictions are a bit more complex. When you restrict access to a Category, it also restricts access to any child Categories it may have (aka: sub-Categories). In other words, restricting a Category, protects a Category Archive, all of its child Category Archives, and any Posts contained within the Category, or its child Categories. This is a VERY powerful form of protection, so please be careful. It\'s very easy to protect too much content by accident.

'."\n"; + echo ((!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) && empty($GLOBALS["WS_PLUGIN__"]["wp_show_ids"])) ? '

*Tip* Can\'t find your Category IDs? Get WP Show IDs.

'."\n" : ''; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_category_level_access", get_defined_vars()); - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_category_level_access", true, get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_category_level_access", get_defined_vars ()); + echo ''."\n"; + echo ''."\n"; - echo '
' . "\n"; + for($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++) + { + echo '
'."\n"; - echo '
' . "\n"; - echo '

Category Level Access Restrictions (optional)

' . "\n"; - echo '

Here you can specify Categories that are restricted to certain Membership Access Levels. Category restrictions are a bit more complex. When you restrict access to a Category, it also restricts access to any child Categories it may have (aka: sub-Categories). In other words, restricting a Category, protects a Category Archive, all of its child Category Archives, and any Posts contained within the Category, or its child Categories. This is a VERY powerful form of protection, so please be careful. It\'s very easy to protect too much content by accident.

' . "\n"; - echo ((!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) && empty($GLOBALS["WS_PLUGIN__"]["wp_show_ids"])) ? '

*Tip* Can\'t find your Category IDs? Get WP Show IDs.

' . "\n" : ''; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_category_level_access", get_defined_vars ()); + echo '
'."\n"; - echo '
'."\n"; + echo ''."\n"; + echo '
' . "\n"; - echo '' . "\n"; + echo ''."\n"; + echo ''."\n"; - for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++) - { - echo '' . "\n"; + echo ''."\n"; - echo '' . "\n"; + echo ''."\n"; - echo '' . "\n"; - echo '' . "\n"; + echo ''."\n"; + } - echo '' . "\n"; + echo ''."\n"; + echo '
'."\n"; + echo '
'."\n"; + echo 'Category IDs in comma-delimited format. Example: 1,2,3,34,8,21 — or you can type: all.'."\n"; + echo '
' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - echo 'Category IDs in comma-delimited format. Example: 1,2,3,34,8,21 — or you can type: all.' . "\n"; - echo '
'."\n"; + echo '
'."\n"; - echo '' . "\n"; + echo '
'."\n"; - echo '' . "\n"; - } + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_category_level_access", get_defined_vars()); + } + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_uri_level_access", TRUE, get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_uri_level_access", get_defined_vars()); + + echo '
'."\n"; + + echo '
'."\n"; + echo '

URI Level Access Restrictions (optional)

'."\n"; + echo '

Here you can specify URIs (or word fragments found in URIs) that are restricted to certain Membership Access Levels. Control over URIs is a little more complex. This section is intended for advanced webmasters only. That being said, here are the basics... A REQUEST_URI, is the portion of a URL that comes immediately after the domain. This is a URL http://www.example.com/path/to/file.php, and this is the URI: /path/to/file.php. In other words, a REQUEST_URI is the full path to a real (or virtual) directory and/or file on your domain.

'."\n"; + echo '

In the fields below, you can provide a list (one per line) of URIs on your site that should be off-limits based on Membership Level. You can also use word fragments instead of a full URI. If a word fragment is found anywhere in the URI, it will be protected. Wildcards and other regex patterns are NOT supported here, and therefore you don\'t need to escape special characters or anything. Please note, depending on your caSe configuration option (as seen below), your exclusion patterns might be caSe sensitive. If you choose to make these caSe sensitive, you must be specific. The word fragment some-path/ would NOT match a URI that contains some-Path/. A few Replacement Codes are also supported here.

'."\n"; + echo '

*BuddyPress (and similar)* URI Restrictions work great with plugins like BuddyPress that add new areas to your site (where those new areas are NOT necessarily a Post/Page/Tag/Category). In other words, anytime you\'d like to protect a specific feature offered by BuddyPress (or other plugins), you\'ll need to nail down specific word fragments found in the URIs associated with those areas. For instance, with BuddyPress you might have: [ click for example ].

'."\n"; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_uri_level_access", get_defined_vars()); + + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + echo '
'."\n"; + echo 'Recommended setting: (No; caSe-insensitive)'."\n"; + echo '
'."\n"; + + echo '
'."\n"; + + echo ''."\n"; + echo ''."\n"; + + for($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++) + { + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + } + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + echo '
'."\n"; + echo 'URIs and/or word fragments found in URIs. One per line please.'."\n"; + echo '
'."\n"; + echo '
'."\n"; + + echo '
'."\n"; + + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_uri_level_access", get_defined_vars()); + } + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_query_level_access", TRUE, get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_query_level_access", get_defined_vars()); + + echo '
'."\n"; + + echo '
'."\n"; + echo '

Alternative View Protection (optional / experimental)

'."\n"; + echo '

s2Member protects Categories, Tags, Posts, Pages, Files, URIs & more. BUT, even with all of those security restrictions, it\'s still possible for protected content excerpts to be seen through XML feeds, in search results generated by WordPress; and/or (depending on your theme), possibly in other Archive views; which might include: Posts by Author, Posts by Date, a list of featured items formulated by your theme, OR even through other widgets/plugins adding functionality to your site. ~ We refer to all of these collectively, as "Alternative Views".

'."\n"; + echo '

Using the options below, you can tell s2Member to protect some (or all) of these "Alternative Views", by filtering WordPress database queries for you. s2Member can automatically hide protected content that is NOT available to the current User/Member. In other words, s2Member is capable of pre-filtering ALL database queries, so that excerpts of protected content will not be allowed to slip through. This is marked "experimental", because we\'re still testing this against MANY widget/plugin/theme combinations. Please report all bugs.

'."\n"; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_uri_level_access", get_defined_vars()); + + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + echo '
'."\n"; + echo ''."\n"; + foreach(array("all" => "Filter ALL WordPress queries; protecting all Alternative Views.", "searches" => "└─ Searches (hide protected content in search results)", "feeds" => "└─ Feeds (hide protected content in standard XML/RSS/ATOM feeds)", "comment-feeds" => "└─ Comment Feeds (hide comments associated with protected content, in comment feeds)", "nav-menus" => "└─ Nav Menus (hide protected content in menus generated with WordPress -› Appearance -› Menus)", "pages" => "└─ Pages (hide protected content in widgets that list Pages)") as $ws_plugin__s2member_temp_s_value => $ws_plugin__s2member_temp_s_label) + echo '
'."\n"; + echo '
'."\n"; + echo 'Attn Developers: Filters can be suppressed dynamically, using this technique:
'."\n"; + echo 'query_posts("suppress_filters=true");
'."\n"; + echo 'get_posts() auto-suppresses filters.
'."\n"; + echo 'Also see this article in the s2Member Codex.'."\n"; + echo '
'."\n"; + echo '
'."\n"; + + echo '
'."\n"; + + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_query_level_access", get_defined_vars()); + } + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_conditionals", (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()), get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_conditionals", get_defined_vars()); + + echo '
'."\n"; + + echo '
'."\n"; + echo '

Simple Shortcode Conditionals (optional — to protect only parts of your content)

'."\n"; + echo '

s2Member makes it very simple to protect entire Posts/Pages/Categories/Tags/URIs/etc. This can be accomplished here in your WordPress Dashboard, using one of the many tools made available on this page. Or, from your Post/Page editing station in WordPress. We consider this to be point-and-click functionality ~ very easy.

'."\n"; + echo '

s2Member also makes it pretty simple to protect "parts" of a Post or Page. You can even get creative about what you display to certain Users/Members, based upon your own custom criteria. s2Member\'s Simple Shortcode Conditionals are the key to accomplishing this.

'."\n"; + echo '

Please see this KB article to learn more: s2Member Simple Shortcode Conditionals

'."\n"; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_conditionals", get_defined_vars()); + echo '
'."\n"; + + if((!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) && c_ws_plugin__s2member_utils_conds::pro_is_installed()) + { + echo '
'."\n"; + + echo '

Arbitrary PHP Code via [s2If php=""]

'."\n"; + echo '

By default, the [s2If] Shortcode is limited to a specific set of Conditional Tags provided by WordPress and the s2Member plugin; e.g. [s2If current_user_can(access_s2member_level1)]; as one quick example. Arbitrary PHP code is NOT allowed with this syntax.

'."\n"; + echo '

However, a second syntax variation exists; where it IS possible to use arbitrary PHP code (but only if enabled below). The second syntax variation uses one php Shortcode Attribute to run your conditional check; e.g. [s2If php="current_user_can(\'access_s2member_level1\')"]. For developers, this has some obvious advantages. The code inside the php attribute is evaluated at runtime, so it\'s possible to accomplish more when necessary. Of course, you could also use a plugin like ezPHP to accomplish the same thing (if you prefer).

'."\n"; + + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + } + echo '
'."\n"; + + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_conditionals", get_defined_vars()); + } + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_sp_access", TRUE, get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_sp_access", get_defined_vars()); - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; + echo '
'."\n"; - echo '
' . "\n"; + echo '
'."\n"; + echo '

Specific Post/Page Access Restrictions (optional)

'."\n"; + echo '

s2Member now supports an additional layer of functionality (very powerful), which allows you to sell access to specific Posts/Pages that you\'ve created in WordPress. Specific Post/Page Access works independently from Member Level Access. That is, you can sell an unlimited number of Posts/Pages using "Buy Now" Buttons, and your Customers will NOT be required to have a Membership Account with your site in order to receive access. If they are already a Member, that\'s fine, but they won\'t need to be.

'."\n"; + echo '

In other words, Customers will NOT need to login, just to receive access to the Specific Post/Page they purchased access to. s2Member will immediately redirect the Customer to the Specific Post/Page after checkout is completed successfully. An email is also sent to the Customer with a link (see: s2Member -› PayPal Options -› Specific Post/Page Email). Authentication is handled automatically through self-expiring links, good for 72 hours by default.

'."\n"; + echo '

Specific Post/Page Access, is sort of like selling a product. Only, instead of shipping anything to the Customer, you just give them access to a specific Post/Page on your site; one that you created in WordPress. A Specific Post/Page that is protected by s2Member, might contain a download link for your eBook, access to file & music downloads, access to additional support services, and the list goes on and on. The possibilities with this are endless; as long as your digital product can be delivered through access to a WordPress Post/Page that you\'ve created.

'."\n"; + echo '

Very simple. All you do is protect the Specific Post/Page IDs that are being sold on your site. Then, you can go to s2Member -› PayPal Buttons -› Specific Post/Page to generate "Buy Now" Buttons that you can insert into your WordPress Editor, and make available on your site. The Button Generator for s2Member, will even let you Package Additional Posts/Pages together into one transaction.

'."\n"; + echo ((!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) && empty($GLOBALS["WS_PLUGIN__"]["wp_show_ids"])) ? '

*Tip* Can\'t find your Post/Page IDs? Get WP Show IDs.

'."\n" : ''; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_sp_access", get_defined_vars()); - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_category_level_access", get_defined_vars ()); - } + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_uri_level_access", true, get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_uri_level_access", get_defined_vars ()); + echo ''."\n"; - echo '
' . "\n"; + echo '
'."\n"; + echo ''."\n"; - echo '
' . "\n"; - echo '

URI Level Access Restrictions (optional)

' . "\n"; - echo '

Here you can specify URIs (or word fragments found in URIs) that are restricted to certain Membership Access Levels. Control over URIs is a little more complex. This section is intended for advanced webmasters only. That being said, here are the basics... A REQUEST_URI, is the portion of a URL that comes immediately after the domain. This is a URL http://www.example.com/path/to/file.php, and this is the URI: /path/to/file.php. In other words, a REQUEST_URI is the full path to a real (or virtual) directory and/or file on your domain.

' . "\n"; - echo '

In the fields below, you can provide a list (one per line) of URIs on your site that should be off-limits based on Membership Level. You can also use word fragments instead of a full URI. If a word fragment is found anywhere in the URI, it will be protected. Wildcards and other regex patterns are NOT supported here, and therefore you don\'t need to escape special characters or anything. Please note, these ARE caSe sensitive. You must be specific with respect to case sensitivity. The word fragment some-path/ would NOT match a URI that contains some-Path/. A few Replacement Codes are also supported here.

' . "\n"; - echo '

*BuddyPress (and similar)* URI Restrictions work great with plugins like BuddyPress that add new areas to your site (where those new areas are NOT necessarily a Post/Page/Tag/Category). In other words, anytime you\'d like to protect a specific feature offered by BuddyPress (or other plugins), you\'ll need to nail down specific word fragments found in the URIs associated with those areas. For instance, with BuddyPress you might have: [ click for example ].

' . "\n"; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_uri_level_access", get_defined_vars ()); + echo '
'."\n"; - echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + echo '
'."\n"; + echo 'Post/Page IDs in comma-delimited format. Example: 1,2,3,34,8,21 * Note... the word all does NOT work here. Also, please be careful not to create a conflict with other Access Restrictions. If you are going to sell Specific Post/Page Access, you should enter specific Post/Page IDs here; and make SURE that you\'ve NOT already protected any of these Posts/Pages with Member Level Access Restrictions. In other words, if you configure s2Member, in such as a way, that a Post/Page requires Membership Level Access, you cannot sell that same Post/Page through Specific Post/Page Access. Doing so, would create a conflict. Customers that purchased Specific Post/Page Access, would be unable to access the Post/Page - without also having a Membership. Not good. So please be careful.'."\n"; + echo '
' . "\n"; - echo '' . "\n"; + echo ''."\n"; + echo ''."\n"; + echo '
'."\n"; + echo '
'."\n"; - for ($n = 0; $n <= $GLOBALS["WS_PLUGIN__"]["s2member"]["c"]["levels"]; $n++) - { - echo '' . "\n"; + echo ''."\n"; - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_sp_access", get_defined_vars()); + } + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_brute_force_restrictions", TRUE, get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_brute_force_restrictions", get_defined_vars()); + + echo '
'."\n"; + + echo '
'."\n"; + echo '

Brute Force IP/Login Restrictions (prevents username/password guessing)

'."\n"; + echo ''."\n"; + echo '

As with any Membership system, it is possible for someone to try and guess Username/Password combinations by attempting a Brute Force Attack; whereby multiple/repeated logins are strategically attempted with various Username/Password combinations until a correct guess is made. It is NOT likely that you\'ll be attacked in this way, but it\'s still a good idea to protect your system; just in case somebody tries this. s2Member thwarts this behavior by monitoring failed login attempts that occur within a short period of time. Whenever s2Member detects an IP address (i.e. a remote user) that is consistently failing to enter a valid Username/Password, a temporary ban is created; preventing additional attempts from taking place for 30 minutes. This temporary ban, will ONLY affect the offending IP address.

'."\n"; + echo '

*Note* an empty IP address (associated with someone browsing anonymously), is also considered a unique IP address, so it cannot circumvent s2Member\'s security.

'."\n"; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_ip_restrictions", get_defined_vars()); + + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + echo '
'."\n"; + echo 'When/if you change this, you should also Reset Brute Force Logs (click button above).'."\n"; + echo (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? '

The default period of "30 minutes" could be modified through this WordPress Filter:
ws_plugin__s2member_track_failed_logins__exp_time'."\n" : ''; + echo '
'."\n"; + echo '
'."\n"; + + echo '
'."\n"; + + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_ip_restrictions", get_defined_vars()); + } + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_ip_restrictions", TRUE, get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_ip_restrictions", get_defined_vars()); + + echo '
'."\n"; + + echo '
'."\n"; + echo '

Unique IP Access Restrictions (prevents username/link sharing)

'."\n"; + echo ''."\n"; + echo '

As with any Membership system, it is possible for one Member to signup, and then share their Username with someone else; or even post it online for the whole world to see. This is known as Link Sharing (aka: Username Sharing). It is NOT likely that you\'ll be attacked in this way, but it\'s still a good idea to protect your system; just in case somebody tries this. s2Member\'s IP Restrictions work for Membership Level Access (account logins), Specific Post/Page Access, Registration Links, and other secure Entry Points. In all cases, the rules are simple. A single Username, Access Link, and/or Entry Point ... is only valid for a certain number of unique IP addresses. Once that limit is reached, s2Member assumes there has been a security breach. At that time, s2Member will place a temporary ban (preventing access) to a Specific Post/Page, or to an account associated with a particular Username. This temporary ban, will ONLY affect the offending Link and/or Username associated with the security breach. You can fine-tune this behavior, using the options below.

'."\n"; + echo '

*Note* an empty IP address (associated with someone browsing anonymously), is also considered a unique IP address, so it cannot circumvent s2Member\'s security.

'."\n"; + echo '

Note: This feature can work with or without Simultaneous Login Monitoring (Simultaneous Login Monitoring is available only in s2Member Pro). You can choose to implement both Unique IP Access Restrictions and Simultaneous Login Monitoring together; or just one of these; or neither of them. It\'s a matter of preference.

'."\n"; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_ip_restrictions", get_defined_vars()); + + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo (!is_multisite() || !c_ws_plugin__s2member_utils_conds::is_multisite_farm() || is_main_site()) ? '
The default period of "30 days" could be modified through this WordPress Filter:
ws_plugin__s2member_ip_restrictions__concurrency_time_per_ip'."\n" : ''; + echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + echo '
'."\n"; + echo 'When/if you change this, you should also Reset IP Restriction Logs (click button above).'."\n"; + echo '
'."\n"; + echo '
'."\n"; + + echo '
'."\n"; + + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_ip_restrictions", get_defined_vars()); + } + if(apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_slogin_restrictions", c_ws_plugin__s2member_utils_conds::pro_is_installed(), get_defined_vars())) + { + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_slogin_restrictions", get_defined_vars()); + + echo '
'."\n"; + + echo '
'."\n"; + echo '

Simultaneous Login Restrictions (prevents username sharing)

'."\n"; + echo '

As with any Membership system, it is possible for one Member to signup, and then share their Username with someone else; or even post it online for the whole world to see. This is known as Username Sharing. It is NOT likely that you\'ll be attacked in this way, but it\'s not a bad idea to protect your system; just in case somebody tries this.

'."\n"; + echo '

s2Member\'s Simultaneous Login Monitoring (for Membership Access only); works w/ user account logins (Usernames) to help you prevent a security breach. The rules are simple. A single Username can only have X number of simultaneous logins (as configured below). Once that limit is reached, s2Member assumes there has been a security breach. At that time, s2Member will place a temporary ban (preventing access) and the offending Username will be unable to login until somebody else (who is already logged into the account) has logged-out; clearing the way for someone new.

'."\n"; + echo '

This can be a tricky feature to configure, because not everyone actually clicks the "Logout" link obviously, and so it can be challenging to know when someone is still logged into the site and when they\'re not. s2Member monitors simultaneous logins by updating a timer when someone actually logs in; and then again on each page view while they navigate the site. If there is no activity after X amount of time, s2Member\'s Simultaneous Login Monitor considers that person inactive, and will not include them in security checks until they login again, or visit a new page on the site. You can configure the timeout period below. The default value is 30 minutes (we recommend a low value to reduce the chance of error).

'."\n"; + echo '

Note: This feature can work with or without Unique IP Access Restrictions being enabled. You can choose to implement both Unique IP Access Restrictions and Simultaneous Login Monitoring together; or just one of these; or neither of them. It\'s a matter of preference.

'."\n"; + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_slogin_restrictions", get_defined_vars()); + + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + echo '
'."\n"; + echo 'Examples: 0 (to disable this functionality), 1 (maximum of 1 login at a time), 2, 3, 10, 20, etc.
'."\n"; + echo 'Suggestion: 3 — the chance to open your site in multiple browsers; but still prevents major security issues.
'."\n"; + echo '
'."\n"; + echo ''."\n"; + echo '
'."\n"; + echo '
'."\n"; + echo 'Examples: 30 minutes, 1 hour, 2 hours; anything compatible with PHP\'s strtotime().
'."\n"; + echo 'Recommended Setting: 30 minutes; if they stop browsing the site, they\'re considered inactive.
'."\n"; + echo '
'."\n"; + echo '
'."\n"; + + echo '
'."\n"; + + do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_slogin_restrictions", get_defined_vars()); + } + do_action("ws_plugin__s2member_during_res_ops_page_after_left_sections", get_defined_vars()); - echo '' . "\n"; - echo '' . "\n"; + echo '
'."\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo 'URIs and/or word fragments found in URIs. One per line please.' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - } - - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; + echo '

'."\n"; - echo '' . "\n"; - - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_uri_level_access", get_defined_vars ()); - } - - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_query_level_access", true, get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_query_level_access", get_defined_vars ()); + echo ''."\n"; - echo '
' . "\n"; - - echo '
' . "\n"; - echo '

Alternative View Protection (optional / experimental)

' . "\n"; - echo '

s2Member protects Categories, Tags, Posts, Pages, Files, URIs & more. BUT, even with all of those security restrictions, it\'s still possible for protected content excerpts to be seen through XML feeds, in search results generated by WordPress; and/or (depending on your theme), possibly in other Archive views; which might include: Posts by Author, Posts by Date, a list of featured items formulated by your theme, OR even through other widgets/plugins adding functionality to your site. ~ We refer to all of these collectively, as "Alternative Views".

' . "\n"; - echo '

Using the options below, you can tell s2Member to protect some (or all) of these "Alternative Views", by filtering WordPress database queries for you. s2Member can automatically hide protected content that is NOT available to the current User/Member. In other words, s2Member is capable of pre-filtering ALL database queries, so that excerpts of protected content will not be allowed to slip through. This is marked "experimental", because we\'re still testing this against MANY widget/plugin/theme combinations. Please report all bugs.

' . "\n"; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_uri_level_access", get_defined_vars ()); - - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - foreach (array("all" => "Filter ALL WordPress queries; protecting all Alternative Views.", "searches" => "└─ Searches (hide protected content in search results)", "feeds" => "└─ Feeds (hide protected content in standard XML/RSS/ATOM feeds)", "comment-feeds" => "└─ Comment Feeds (hide comments associated with protected content, in comment feeds)", "nav-menus" => "└─ Nav Menus (hide protected content in menus generated with WordPress -› Appearance -› Menus)", "pages" => "└─ Pages (hide protected content in widgets that list Pages)") as $ws_plugin__s2member_temp_s_value => $ws_plugin__s2member_temp_s_label) - echo '
' . "\n"; - echo '
' . "\n"; - echo 'Attn Developers: Filters can be suppressed dynamically, using this technique:
' . "\n"; - echo 'query_posts("suppress_filters=true");
' . "\n"; - echo 'get_posts() auto-suppresses filters.
' . "\n"; - echo 'Also see this article in the s2Member Codex.' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - - echo '
' . "\n"; - - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_query_level_access", get_defined_vars ()); - } - - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_conditionals", (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()), get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_conditionals", get_defined_vars ()); - - echo '
' . "\n"; - - echo '
' . "\n"; - echo '

Simple Shortcode Conditionals (optional — to protect only parts of your content)

' . "\n"; - echo '

s2Member makes it very simple to protect entire Posts/Pages/Categories/Tags/URIs/etc. This can be accomplished here in your WordPress Dashboard, using one of the many tools made available on this page. Or, from your Post/Page editing station in WordPress. We consider this to be point-and-click functionality ~ very easy.

'."\n"; - echo '

s2Member also makes it pretty simple to protect "parts" of a Post or Page. You can even get creative about what you display to certain Users/Members, based upon your own custom criteria. s2Member\'s Simple Shortcode Conditionals are the key to accomplishing this.

'."\n"; - echo '

Please see this KB article to learn more: s2Member Simple Shortcode Conditionals

' . "\n"; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_conditionals", get_defined_vars ()); - echo '
' . "\n"; - - if((!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) && c_ws_plugin__s2member_utils_conds::pro_is_installed()) - { - echo '
' . "\n"; - - echo '

Arbitrary PHP Code via [s2If php=""]

' . "\n"; - echo '

By default, the [s2If] Shortcode is limited to a specific set of Conditional Tags provided by WordPress and the s2Member plugin; e.g. [s2If current_user_can(access_s2member_level1)]; as one quick example. Arbitrary PHP code is NOT allowed with this syntax.

'."\n"; - echo '

However, a second syntax variation exists; where it IS possible to use arbitrary PHP code (but only if enabled below). The second syntax variation uses one php Shortcode Attribute to run your conditional check; e.g. [s2If php="current_user_can(\'access_s2member_level1\')"]. For developers, this has some obvious advantages. The code inside the php attribute is evaluated at runtime, so it\'s possible to accomplish more when necessary. Of course, you could also use a plugin like ezPHP to accomplish the same thing (if you prefer).

' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - } - echo '
' . "\n"; - - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_conditionals", get_defined_vars ()); - } - - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_sp_access", true, get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_sp_access", get_defined_vars ()); - - echo '
' . "\n"; - - echo '
' . "\n"; - echo '

Specific Post/Page Access Restrictions (optional)

' . "\n"; - echo '

s2Member now supports an additional layer of functionality (very powerful), which allows you to sell access to specific Posts/Pages that you\'ve created in WordPress. Specific Post/Page Access works independently from Member Level Access. That is, you can sell an unlimited number of Posts/Pages using "Buy Now" Buttons, and your Customers will NOT be required to have a Membership Account with your site in order to receive access. If they are already a Member, that\'s fine, but they won\'t need to be.

' . "\n"; - echo '

In other words, Customers will NOT need to login, just to receive access to the Specific Post/Page they purchased access to. s2Member will immediately redirect the Customer to the Specific Post/Page after checkout is completed successfully. An email is also sent to the Customer with a link (see: s2Member -› PayPal Options -› Specific Post/Page Email). Authentication is handled automatically through self-expiring links, good for 72 hours by default.

' . "\n"; - echo '

Specific Post/Page Access, is sort of like selling a product. Only, instead of shipping anything to the Customer, you just give them access to a specific Post/Page on your site; one that you created in WordPress. A Specific Post/Page that is protected by s2Member, might contain a download link for your eBook, access to file & music downloads, access to additional support services, and the list goes on and on. The possibilities with this are endless; as long as your digital product can be delivered through access to a WordPress Post/Page that you\'ve created.

' . "\n"; - echo '

Very simple. All you do is protect the Specific Post/Page IDs that are being sold on your site. Then, you can go to s2Member -› PayPal Buttons -› Specific Post/Page to generate "Buy Now" Buttons that you can insert into your WordPress Editor, and make available on your site. The Button Generator for s2Member, will even let you Package Additional Posts/Pages together into one transaction.

' . "\n"; - echo ((!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) && empty($GLOBALS["WS_PLUGIN__"]["wp_show_ids"])) ? '

*Tip* Can\'t find your Post/Page IDs? Get WP Show IDs.

' . "\n" : ''; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_sp_access", get_defined_vars ()); - - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - echo 'Post/Page IDs in comma-delimited format. Example: 1,2,3,34,8,21 * Note... the word all does NOT work here. Also, please be careful not to create a conflict with other Access Restrictions. If you are going to sell Specific Post/Page Access, you should enter specific Post/Page IDs here; and make SURE that you\'ve NOT already protected any of these Posts/Pages with Member Level Access Restrictions. In other words, if you configure s2Member, in such as a way, that a Post/Page requires Membership Level Access, you cannot sell that same Post/Page through Specific Post/Page Access. Doing so, would create a conflict. Customers that purchased Specific Post/Page Access, would be unable to access the Post/Page - without also having a Membership. Not good. So please be careful.' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - - echo '
' . "\n"; - - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_sp_access", get_defined_vars ()); - } - - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_brute_force_restrictions", true, get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_brute_force_restrictions", get_defined_vars ()); - - echo '
' . "\n"; - - echo '
' . "\n"; - echo '

Brute Force IP/Login Restrictions (prevents username/password guessing)

' . "\n"; - echo '' . "\n"; - echo '

As with any Membership system, it is possible for someone to try and guess Username/Password combinations by attempting a Brute Force Attack; whereby multiple/repeated logins are strategically attempted with various Username/Password combinations until a correct guess is made. It is NOT likely that you\'ll be attacked in this way, but it\'s still a good idea to protect your system; just in case somebody tries this. s2Member thwarts this behavior by monitoring failed login attempts that occur within a short period of time. Whenever s2Member detects an IP address (i.e. a remote user) that is consistently failing to enter a valid Username/Password, a temporary ban is created; preventing additional attempts from taking place for 30 minutes. This temporary ban, will ONLY affect the offending IP address.

' . "\n"; - echo '

*Note* an empty IP address (associated with someone browsing anonymously), is also considered a unique IP address, so it cannot circumvent s2Member\'s security.

' . "\n"; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_ip_restrictions", get_defined_vars ()); - - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - echo 'When/if you change this, you should also Reset Brute Force Logs (click button above).' . "\n"; - echo (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) ? '

The default period of "30 minutes" could be modified through this WordPress Filter:
ws_plugin__s2member_track_failed_logins__exp_time' . "\n" : ''; - echo '
' . "\n"; - echo '
' . "\n"; - - echo '
' . "\n"; - - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_ip_restrictions", get_defined_vars ()); - } - - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_ip_restrictions", true, get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_ip_restrictions", get_defined_vars ()); - - echo '
' . "\n"; - - echo '
' . "\n"; - echo '

Unique IP Access Restrictions (prevents username/link sharing)

' . "\n"; - echo '' . "\n"; - echo '

As with any Membership system, it is possible for one Member to signup, and then share their Username with someone else; or even post it online for the whole world to see. This is known as Link Sharing (aka: Username Sharing). It is NOT likely that you\'ll be attacked in this way, but it\'s still a good idea to protect your system; just in case somebody tries this. s2Member\'s IP Restrictions work for Membership Level Access (account logins), Specific Post/Page Access, Registration Links, and other secure Entry Points. In all cases, the rules are simple. A single Username, Access Link, and/or Entry Point ... is only valid for a certain number of unique IP addresses. Once that limit is reached, s2Member assumes there has been a security breach. At that time, s2Member will place a temporary ban (preventing access) to a Specific Post/Page, or to an account associated with a particular Username. This temporary ban, will ONLY affect the offending Link and/or Username associated with the security breach. You can fine-tune this behavior, using the options below.

' . "\n"; - echo '

*Note* an empty IP address (associated with someone browsing anonymously), is also considered a unique IP address, so it cannot circumvent s2Member\'s security.

' . "\n"; - echo '

Note: This feature can work with or without Simultaneous Login Monitoring (Simultaneous Login Monitoring is available only in s2Member Pro). You can choose to implement both Unique IP Access Restrictions and Simultaneous Login Monitoring together; or just one of these; or neither of them. It\'s a matter of preference.

' . "\n"; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_ip_restrictions", get_defined_vars ()); - - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo (!is_multisite () || !c_ws_plugin__s2member_utils_conds::is_multisite_farm () || is_main_site ()) ? '
The default period of "30 days" could be modified through this WordPress Filter:
ws_plugin__s2member_ip_restrictions__concurrency_time_per_ip' . "\n" : ''; - echo '
' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - echo 'When/if you change this, you should also Reset IP Restriction Logs (click button above).' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - - echo '
' . "\n"; - - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_ip_restrictions", get_defined_vars ()); - } - - if (apply_filters("ws_plugin__s2member_during_res_ops_page_during_left_sections_display_slogin_restrictions", c_ws_plugin__s2member_utils_conds::pro_is_installed(), get_defined_vars ())) - { - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_before_slogin_restrictions", get_defined_vars ()); - - echo '
' . "\n"; - - echo '
' . "\n"; - echo '

Simultaneous Login Restrictions (prevents username sharing)

' . "\n"; - echo '

As with any Membership system, it is possible for one Member to signup, and then share their Username with someone else; or even post it online for the whole world to see. This is known as Username Sharing. It is NOT likely that you\'ll be attacked in this way, but it\'s not a bad idea to protect your system; just in case somebody tries this.

'."\n"; - echo '

s2Member\'s Simultaneous Login Monitoring (for Membership Access only); works w/ user account logins (Usernames) to help you prevent a security breach. The rules are simple. A single Username can only have X number of simultaneous logins (as configured below). Once that limit is reached, s2Member assumes there has been a security breach. At that time, s2Member will place a temporary ban (preventing access) and the offending Username will be unable to login until somebody else (who is already logged into the account) has logged-out; clearing the way for someone new.

' . "\n"; - echo '

This can be a tricky feature to configure, because not everyone actually clicks the "Logout" link obviously, and so it can be challenging to know when someone is still logged into the site and when they\'re not. s2Member monitors simultaneous logins by updating a timer when someone actually logs in; and then again on each page view while they navigate the site. If there is no activity after X amount of time, s2Member\'s Simultaneous Login Monitor considers that person inactive, and will not include them in security checks until they login again, or visit a new page on the site. You can configure the timeout period below. The default value is 30 minutes (we recommend a low value to reduce the chance of error).

' . "\n"; - echo '

Note: This feature can work with or without Unique IP Access Restrictions being enabled. You can choose to implement both Unique IP Access Restrictions and Simultaneous Login Monitoring together; or just one of these; or neither of them. It\'s a matter of preference.

' . "\n"; - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_during_slogin_restrictions", get_defined_vars ()); - - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - echo 'Examples: 0 (to disable this functionality), 1 (maximum of 1 login at a time), 2, 3, 10, 20, etc.
' . "\n"; - echo 'Suggestion: 3 — the chance to open your site in multiple browsers; but still prevents major security issues.
' . "\n"; - echo '
' . "\n"; - echo '' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - echo 'Examples: 30 minutes, 1 hour, 2 hours; anything compatible with PHP\'s strtotime().
' . "\n"; - echo 'Recommended Setting: 30 minutes; if they stop browsing the site, they\'re considered inactive.
' . "\n"; - echo '
' . "\n"; - echo '
' . "\n"; - - echo '
' . "\n"; - - do_action("ws_plugin__s2member_during_res_ops_page_during_left_sections_after_slogin_restrictions", get_defined_vars ()); - } - - do_action("ws_plugin__s2member_during_res_ops_page_after_left_sections", get_defined_vars ()); - - echo '
' . "\n"; - - echo '

' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - - echo '' . "\n"; - c_ws_plugin__s2member_menu_pages_rs::display (); - echo '' . "\n"; - - echo '' . "\n"; - echo '' . "\n"; - echo '' . "\n"; + echo ''."\n"; - echo '' . "\n"; - } - } - } + echo ''."\n"; + c_ws_plugin__s2member_menu_pages_rs::display(); + echo ''."\n"; + + echo ''."\n"; + echo ''."\n"; + echo ''."\n"; -new c_ws_plugin__s2member_menu_page_res_ops (); -?> \ No newline at end of file + echo ''."\n"; + } + } +} +new c_ws_plugin__s2member_menu_page_res_ops (); \ No newline at end of file