Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

branch 1.3.55 from http://plugins.svn.wordpress.org/role-scoper/tags/…

  • Loading branch information...
commit 6478115f39476be4d651f90ff3fbb1dc5ca2473a 0 parents
Matt Richmond authored
Showing with 25,408 additions and 0 deletions.
  1. +854 −0 RoleScoper_UsageGuide.htm
  2. +87 −0 admin/about.php
  3. +109 −0 admin/about/about.css
  4. +74 −0 admin/about/dialog-align.css
  5. +22 −0 admin/about/dialog-alignIE.css
  6. +37 −0 admin/about/dialog.css
  7. BIN  admin/about/dialog2-green-bottom5d.gif
  8. BIN  admin/about/dialog2-green-bottom5d.png
  9. BIN  admin/about/dialog2-green-mid5d.gif
  10. BIN  admin/about/dialog2-green-mid5d.png
  11. BIN  admin/about/dialog2-green-top5d.gif
  12. BIN  admin/about/dialog2-green-top5d.png
  13. BIN  admin/about/dialog2-greenB2-800x1600.png
  14. BIN  admin/about/img/agapetry-header-repeatE.jpg
  15. BIN  admin/about/img/agapetry-header_finalG.jpg
  16. BIN  admin/about/img/field6b.jpg
  17. BIN  admin/about/img/madein_mich_logo_40.png
  18. +1,118 −0 admin/admin-bulk_rs.php
  19. +51 −0 admin/admin-dashboard_rs.php
  20. +74 −0 admin/admin-init_rs.php
  21. +172 −0 admin/admin_lib-bulk-parent_rs.php
  22. +582 −0 admin/admin_lib-bulk_rs.php
  23. +80 −0 admin/admin_lib-mu_rs.php
  24. +637 −0 admin/admin_lib_rs.php
  25. +740 −0 admin/admin_rs.php
  26. +197 −0 admin/admin_ui_lib_rs.php
  27. +272 −0 admin/agapetry.dev.js
  28. +1 −0  admin/agapetry.js
  29. +489 −0 admin/agents_checklist_rs.php
  30. +263 −0 admin/attachments_utility.php
  31. +142 −0 admin/cache_flush_rs.php
  32. +55 −0 admin/comments-interceptor-admin_rs.php
  33. +80 −0 admin/default_groups.php
  34. +203 −0 admin/dualListBox.dev.js
  35. +14 −0 admin/dualListBox.js
  36. +152 −0 admin/filters-admin-nav_menus_rs.php
  37. +37 −0 admin/filters-admin-save-custom_rs.php
  38. +850 −0 admin/filters-admin-save_rs.php
  39. +93 −0 admin/filters-admin-term-selection_rs.php
  40. +31 −0 admin/filters-admin-terms_rs.php
  41. +272 −0 admin/filters-admin-ui-item_rs.php
  42. +117 −0 admin/filters-admin-ui-listing_rs.php
  43. +243 −0 admin/filters-admin-ui_rs.php
  44. +73 −0 admin/filters-admin-users_rs.php
  45. +800 −0 admin/filters-admin_rs.php
  46. +424 −0 admin/general_roles.php
  47. +118 −0 admin/group-notification_rs.php
  48. +153 −0 admin/group_members.php
  49. +350 −0 admin/groups-support.php
  50. +531 −0 admin/groups.php
  51. BIN  admin/images/menu/restrictions.png
  52. BIN  admin/images/menu/roles.png
  53. +593 −0 admin/item_roles_ui_rs.php
  54. +94 −0 admin/listbox.dev.js
  55. +13 −0 admin/listbox.js
  56. +132 −0 admin/misc/version_notice_rs.php
  57. +235 −0 admin/object_restrictions.php
  58. +85 −0 admin/object_role_edit.php
  59. +233 −0 admin/object_roles.php
  60. +294 −0 admin/object_roles_list.php
  61. +2,198 −0 admin/options.php
  62. +228 −0 admin/permission_lib_rs.php
  63. +418 −0 admin/profile_ui_rs.php
  64. +21 −0 admin/relevanssi-helper-admin_rs.php
  65. +774 −0 admin/role-scoper.css
  66. +37 −0 admin/role-scoper.dev.js
  67. +5 −0 admin/role-scoper.js
  68. +870 −0 admin/role_assigner_rs.php
  69. +140 −0 admin/role_assignment_lib_rs.php
  70. +279 −0 admin/role_definition.php
  71. +123 −0 admin/role_definition_wp.php
  72. +24 −0 admin/rs-objrole-cbox-maint.dev.js
  73. +5 −0 admin/rs-objrole-cbox-maint.js
  74. +163 −0 admin/section_restrictions.php
  75. +225 −0 admin/section_roles.php
  76. +164 −0 admin/subscribe2_helper_rs.php
  77. +93 −0 admin/update-legacy_rs.php
  78. +527 −0 admin/update_rs.php
  79. +137 −0 admin/user_lib_rs.php
  80. +68 −0 admin/user_query_rs.php
  81. +462 −0 admin/user_search_ui_rs.php
  82. +231 −0 analyst_rs.php
  83. +7 −0 api-legacy_rs.php
  84. +226 −0 attachment-filters_rs.php
  85. +38 −0 attachment-helper_rs.php
  86. +45 −0 attachment-interceptor_rs.php
  87. +88 −0 attachment-template_rs.php
  88. +28 −0 bp-helper_rs.php
  89. +89 −0 cap-interceptor-basic_rs.php
  90. +1,009 −0 cap-interceptor_rs.php
  91. +248 −0 capabilities_rs.php
  92. +20 −0 comments-int-administrator_rs.php
  93. +113 −0 comments-interceptor_rs.php
  94. +407 −0 data_sources_rs.php
  95. +46 −0 db-config_rs.php
  96. +413 −0 db-setup_rs.php
  97. +191 −0 defaults_rs.php
  98. +574 −0 definitions_cr.php
  99. +50 −0 error_rs.php
  100. +40 −0 extension-helper_rs.php
  101. +157 −0 feed-interceptor_rs.php
  102. +776 −0 hardway/cache-persistent.php
  103. +45 −0 hardway/hardway-admin-links_rs.php
  104. +270 −0 hardway/hardway-admin_non-administrator-legacy_rs.php
  105. +279 −0 hardway/hardway-admin_non-administrator_rs.php
  106. +49 −0 hardway/hardway-admin_rs.php
  107. +187 −0 hardway/hardway-bookmarks_rs.php
  108. +78 −0 hardway/hardway-front-legacy_rs.php
  109. +238 −0 hardway/hardway-front_rs.php
  110. +193 −0 hardway/hardway-parent-legacy_rs.php
  111. +36 −0 hardway/hardway-parent_rs.php
Sorry, we could not display the entire diff because it was too big.
854 RoleScoper_UsageGuide.htm
@@ -0,0 +1,854 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html><head>
+<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>Role Scoper Usage Guide</title>
+
+<style type="text/css">
+ul li {
+list-style-type: disc;
+margin-bottom: 0.7em;
+}
+ol li {
+margin-bottom: 0.7em;
+}
+ul {
+margin-right: 1em;
+}
+ol {
+margin-right: 1em;
+}
+.step_list {
+border: 1px solid black;
+margin-left: 2em;
+width: 32em;
+padding-right: 0.5em;
+color: white;
+background-color: #008c00;
+font-family: Verdana,Helvetica,sans-serif;
+margin-top: 0.1em;
+font-weight: bold;
+font-size: small;
+padding-top: 0.2em;
+padding-bottom: 0.2em;
+}
+h1 {
+font-family: Arial,Helvetica,sans-serif;
+margin-top: 2em;
+}
+h2 {
+font-family: Arial,Helvetica,sans-serif;
+}
+h3 {
+font-family: Arial,Helvetica,sans-serif;
+margin-bottom: 0.05em;
+margin-top: 1.75em;
+}
+.steplist li {
+color: white;
+}
+p {
+margin-top: 0.3em;
+}
+h4 {
+font-family: Verdana,Helvetica,sans-serif;
+margin-bottom: 0.2em;
+}
+h5 {
+font-family: "Times New Roman",Times,serif;
+font-weight: bold;
+margin-bottom: 0.2em;
+font-size: medium;
+}
+</style>
+</head>
+<body>
+<div id="wrap">
+<h1 align="center">Role Scoper
+plugin for WordPress</h1>
+<h1 align="center"><span style="font-size: 20pt; font-family: Arial;">Usage Guide</span></h1>
+<h3 style="margin-bottom: 0.2in; text-align: center; font-family: Arial;" align="center"><font size="-1">by Kevin Behrens</font></h3>
+<p style="text-align: center;" align="center"><a href="http://agapetry.net/"><span style="font-family: &quot;Courier New&quot;;">http://agapetry.net/</span></a></p>
+<p style="text-align: center;" align="center"><a href="http://agapetry.net/forum/"><span style="font-family: &quot;Courier New&quot;;">http://agapetry.net/forum/</span></a></p>
+<p style="margin-bottom: 0.2in; text-align: center; font-family: Arial;" align="center"><font size="-1">original
+document: 10
+July 2008</font></p>
+<p style="margin-bottom: 0.2in; text-align: center; font-family: Arial;" align="center"><font size="-1">revision: 3 November 2008</font></p>
+
+<p>This
+document
+contains Topical commentary to orient an experienced WordPress blog
+administrator to the new permission controls offered by Role Scoper.
+Those
+uninterested in this discussion may skip to step-by-step instructions
+in the
+How-to Guide. This document is a work in progress which will be
+expanded and
+updated periodically.</p>
+<p>For
+a general
+overview of Role Scoper&#8217;s motives and screen shots which may provide a
+helpful
+accompaniment, see the following online document: <a href="http://agapetry.net/news/introducing-role-scoper/">http://agapetry.net/news/introducing-role-scoper/</a></p>
+<h3>Contents</h3>
+<p>Section
+1: <a href="#Section1%7Cregion">Glossary
+and Commentary</a></p>
+<p>Section
+2: <a href="#Section2%7Cregion">How-to
+Guide</a></p>
+<p>Section
+3: <a href="#Section3%7Cregion">Customizations
+and Extensions</a></p>
+<p><a href="#Section3%7Cregion"><span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-weight: bold;"></span></span></a></p>
+<h3>Installation</h3>
+<ol class="step_list">
+<li>Upload / extract the zip to your web server such that the
+directory <b>wp-content/plugins/role-scoper/ </b>contains
+role-scoper.php, etc.&nbsp; <br>
+<br>
+<span style="font-weight: normal;">If your site has
+CPanel, just copy the
+zip
+into wp-content/plugins and extract.&nbsp; Otherwise, extract the
+zip on
+your local computer and use FTP to create the new server directory and
+upload all files.</span></li>
+<li>Log into WordPress (yoursite/wp-admin/) as an Administrator</li>
+<li>Click on Plugins; activate Role Scoper</li>
+</ol>
+Once the plugin is activated, this Usage Guide should prove
+helpful.&nbsp; Your steps from here depend on what you're trying to
+accomplish. &nbsp;If this document and the Role Scoper interface
+don't
+point the way, you can always place a request for help in the <a href="http://agapetry.net/forum/">support forum</a>.<br>
+<a name="Section1|region"></a>
+<h1 align="center">Section
+1:
+Glossary and Commentary</h1>
+<h3>Description</h3>
+<p>Role
+Scoper is
+a comprehensive drop-in replacement for capability enforcement and
+administration in WordPress. Assign reading, editing or administration
+roles to
+users or groups on a page-specific, category-specific or other
+content-specific
+basis.</p>
+<h3>Menu
+Access</h3>
+<p>After
+activating Role Scoper, you will find two new utility links on the
+right next
+to &#8220;Settings&#8221;: Roles and Groups. Most of Role Scoper&#8217;s settings are
+accessed
+through the &#8220;Roles&#8221; or &#8220;Groups&#8221; links.</p>
+&#8220;Groups&#8221;
+pertains to the definition of User Groups, and to role assignments for
+those
+groups (see &#8220;User Groups&#8221; below. The role assignment portion of the
+&#8220;Groups&#8221;
+tab is therefore a mirror of corresponding role assignment links on the
+&#8220;Roles&#8221;
+tab which pertain to individual users.
+<p>Those
+wishing
+only to assign or restrict access to an individual post or page may go
+straight
+to the WordPress post/page editor interface and look for the new
+&#8220;Readers&#8221;,
+&#8220;Contributors&#8221; and &#8220;Editors&#8221; tabs.</p>
+<a name="general_roles"></a>
+<h3>Scope:
+Blog, Section or Object</h3>
+<p>By
+default,
+Wordpress roles specify capabilities that a user has blog-wide. Pages
+and Posts
+can be marked private. If a user&#8217;s role includes the read_private_pages
+capability, <b>all</b> private pages are readable to them.
+Otherwise <b>none</b>
+are. The same is true for editing or publishing capabilities - a user
+can edit <b>all</b>
+posts made by other users, or <b>none </b>of them.</p>
+<p>Role
+Scoper
+allows you to assign roles in any of three scopes: blog-wide (Blog
+scope),
+category-wide (Section scope) or for a specific post/page (Object
+scope). To reduce confusions, the
+generic names &#8220;section&#8221; and "object" are not generally used in the User
+Interface or in this documentation. &nbsp;However, a
+section can consist of some custom taxonomy other than &#8220;category&#8221;, and
+may or may not use the WP term_taxonomy schema. &nbsp;Likewise, Role
+Scoper can be configured to control permissions for "objects" other
+than posts and pages. &nbsp;In the future, other
+plugins may use Role Scoper API to define sections
+such as
+forums, calendars or galleries.</p>
+<p>When
+some read
+or edit operation is requested, Role Scoper filters the request and
+grants
+permission if the user has a qualifying role in any scope:</p>
+<p style="text-align: center;" align="center"><span style="color: blue;">Blog
+scope</span> <b>or</b>
+<span style="color: blue;">Section
+scope</span> <b>or</b> <span style="color: blue;">Object
+scope</span>.</p>
+<a name="roles~category"></a>
+<h3>Category&nbsp;Role Assignment</h3>
+<p>Category
+roles, as an instance of &#8220;Section Roles&#8221;, are assigned on the WP Admin
+-&gt;
+Roles -&gt; Category page. &nbsp;Users and/or Groups may
+receive a Category Role assignment.&nbsp;
+Each Category has
+a separate set of role checkboxes. Note that whether assigning or
+removing role
+assignments, you must check all the users/groups and all the roles
+being
+modified. The
+dropdown list next to the &#8220;Update&#8221; button determine what effect the
+update has.</p>
+<p>When
+assigning Category Roles, you can choose whether to assign to the selected
+categories
+only, to the selected and all subcategories (present or future), or to
+subcategories only.</p>
+<a name="roles~page"></a>
+<a name="post"></a>
+<a name="page"></a>
+<h3>Post / Page Role Assignment</h3>
+<p>Post
+Roles and
+Page Roles are instances of &#8220;Object Roles&#8221;. They may be assigned via
+new tabs
+on the WP post / page edit interface - &#8220;Readers&#8221;, &#8220;Editors&#8221;, etc. When
+selecting users or groups for page role assignment, note that the
+normal
+checkboxes assign the role to current page, whereas the braced {[]}
+checkbox
+assigns the role to all subpages (present or future).</p>
+<a name="restrictions~category"></a>
+<h3>Category Restrictions <small><small>(previously
+known as "Exclusive Section
+Roles")</small></small></h3>
+<p>A
+role
+assignment <b>grants </b>a user or group capabilities
+which they may not
+already have. When you assign several users the Post Editor role in
+&#8220;Category
+A&#8221;, you are allowing them to edit &#8220;Category A&#8221; posts on the basis
+of&nbsp;Category Role. Some may already qualify based on their general
+(blog-wide) WordPress role,
+others may not.</p>
+<p>However,
+<b>one
+user&#8217;s role assignment</b> <b>does not reduce access</b>
+for any other users.
+To deny some users access to &#8220;Category A&#8221; even though their General Role
+qualifies, you must specify a<b>&nbsp;Category Restriction</b>.
+There is a
+separate setting for each Role in each Category. For Category A, if the
+Post
+Reader role is restricted, then users with a general Wordpress role of Post
+Reader (which includes anonymous users) cannot read Category A posts
+unless they
+have a Category Role or Post Role assignment. Users with a different general role
+which also contains the required capabilities will not be excluded.</p>
+<p>Another
+way of
+describing&nbsp;Restrictions is that they allow you to selectively
+remove
+one or more qualifying clauses from the {General Role <b>OR</b> Category
+Role <b>OR</b> Post/Page
+Role} formula.</p>
+<h5><b>Some
+&#8220;Category Restriction&#8221; details to note:</b></h5>
+<ul>
+<li>If a
+post is in &#8220;Category A&#8221; and &#8220;Category B&#8221;, a
+user will not be excluded unless both categories have the necessary role restrictions.</li>
+<li>With
+any role assignment, a user is considered
+to possess the assigned role <b>and</b> all roles it
+&#8220;contains&#8221;. The Author
+role contains the Contributor role if Author also has all of
+Contributor&#8217;s
+capabilities. The contained role is a subset of the containing role.</li>
+<li>For a
+user to be excluded, restrictions must be set for their General Role and all the roles it contains. For
+example, if
+a user&#8217;s&nbsp;Author role has been marked Restricted for &#8220;Category
+A&#8221;, they
+are not excluded from reading posts unless the roles &#8220;contained&#8221; in
+Author (Post
+Contributor and Post Reader) are also restricted. The actual role requirement in that case is Post Reader.</li>
+<li>Blogs
+which have used Role Manager to customize
+WP roles should be aware of the following: If Role Scoper is configured
+to use
+&#8220;RS&#8221; role types, Category and Post/Page Restrictions are
+applied on
+the basis of which &#8220;RS&#8221; roles a user&#8217;s WP role contains. This statement will only
+be
+decipherable in conjunction with the documentation on &#8220;role types&#8221;. It
+should
+be a non-issue for WP installations which have removed any caps from
+the
+default WP role definitions.</li>
+</ul>
+<h3>Restricted Post / Page Roles</h3>
+<p>As
+stated
+above, categories can be configured such that a user&#8217;s General Role is
+ignored -
+and a qualifying Category Role or Post/Page role assignment is required.
+Likewise,
+individual posts and pages can be configured such that General Role <b>and</b> Category Roles are ignored. These Post/Page Restrictions can be
+used to
+narrow read or edit access.</p>
+<p>Limiting
+read
+access to a fixed set of users is a three-step operation in the
+WordPress post
+edit interface.</p>
+<ol>
+<li>select those users
+in the &#8220;Readers&#8221; tab</li>
+<li>check the
+&#8220;Restrict&#8221; checkbox</li>
+<li>save the post</li>
+</ol>
+<a name="groups"></a>
+<h3>User
+Groups</h3>
+<p>Any General Role, Category Role or Post/Page role assignment can be applied to
+individual
+users <b>or</b> to a group of users. If your user base
+includes subsets of user
+who commonly get the same role assignments, consider defining those
+users as
+members of a Group.</p>
+<h3>WP
+Role Metagroups</h3>
+<p>In
+addition to
+custom-defined user groups, you may find it convenient to assign some Category
+Role or Post/Page Role to all users who have a certain WordPress-defined Role. You
+will find
+these metagroups (labeled as [WP Editor], [WP Author], etc.) alongside
+the
+custom-defined groups in role assignment interfaces. </p>
+<h3>&#8220;Private&#8221; versus
+&#8220;Restricted&#8221;</h3>
+<p>Wordpress
+defines &#8220;private&#8221; posts and pages as those which require a
+corresponding
+read_private capability, usually possessed only by Administrators,
+Editors, and
+by the content author. Most significantly, the content is hidden from
+anonymous
+users.</p>
+<p>For
+the
+purpose of limiting read access, Role Scoper&nbsp;Restrictions can
+be used
+as an equivalent. If a post&#8217;s categories, or the post itself, Restrict
+the&nbsp;Post Reader role, the post is effectively private regardless
+of the
+WP
+private status. Likewise, Category Role or Post/Page Role assignments
+can
+enable
+access to a &#8220;private&#8221; post or page as long as the assigned role
+includes the
+corresponding read_private capability.</p>
+<p>Despite
+the
+potential equivalence stated above, setting sensitive posts or pages to
+WP
+&#8220;private&#8221; is still the recommended approach. This will ensure that if
+Role
+Scoper is accidentally disabled, content is not revealed
+inappropriately. In
+the future, Role Scoper may automatically set posts/pages to private
+when a
+corresponding Role Scoper setting is made. Due to technical
+difficulties, you
+must currently achieve that extra safeguard manually.</p>
+<h3>Role
+Type</h3>
+<p>In
+Wordpress
+jargon, Roles contain Capabilities. Wordpress comes with a default set
+of Roles
+- Administrator, Editor, Author, Contributor and Subscriber. Those
+default role
+definitions are sensible and sufficient for most WP installations. The
+adventuresome can use the Role Manager plugin to add or remove
+capabilities
+from any role, perhaps to account for new capabilities defined by some
+other
+plugin. The intent is that for any user, there is one role definition
+which
+comprehensively describes every capability the user has, for any object
+type
+which exists within the blog. Every user has one general role.</p>
+<p>By
+default,
+Role Scoper takes a different approach - the &#8220;RS&#8221; role type. Each
+object type
+has a different set of role definitions. So, for posts, there are &#8220;Post
+Reader,
+Private Post Reader, Post Author, Post Editor&#8221; role definitions.
+Likewise for
+pages and, potentially, for other plugin-defined object types which
+choose to
+support RS role definitions. </p>
+<p>The
+upshot of
+this is that instead of defining a modified &#8220;Author&#8221; role which also
+includes
+the &#8220;edit_pages&#8221; capability, you just assign the &#8220;Page Author&#8221; role
+where
+desired. Instead of just assigning one comprehensive WP-defined role,
+you can
+select a pertinent RS-defined role separately for each object type.</p>
+<p>If
+for any
+reason you must apply WP-defined roles as Category Roles or Post/Page
+Roles, simply
+go to WP Admin &gt; Roles &gt; Roles and change the Role Type
+dropdown to &#8220;WP&#8221;.
+</p>
+<h3>Limiting
+the Page Parent Selection</h3>
+<p>Another
+happy
+side effect of &#8220;RS&#8221; role types is the ease with which plugins can
+enable users
+to assign newly-defined capabilities. Role Scoper introduces the
+&#8220;create_child_pages&#8221; capability. This capability enables a user to
+select the
+corresponding page as &#8220;Page Parent&#8221;. Otherwise a page is unavailable as
+parent
+unless the user can edit it. The new RS-defined &#8220;Page Associate&#8221;
+contains
+&#8220;create_child_pages&#8221;, making it one step up from Page Reader. This
+useful role
+distinction would have been difficult to provide if each blog
+administrator was
+required to manually merge the capability into existing WP roles.</p>
+<p>Note
+that Role
+Scoper will not allow a page to be published with a &#8220;Main Page&#8221; parent
+unless
+the user has the blog-wide edit_published_ pages capability. Although
+WordPress
+doesn't provide a means to remove &#8220;Main Page&#8221; from the dropdown,
+attempts by
+unqualified users to publish a new page with &#8220;Main Page&#8221; parent will
+result in
+&#8220;draft&#8221; status. Attempts to modify an existing page from non-Main to
+Main
+(or from Main to non-Main) Page
+Parent will revert the
+page back to the previous stored Page Parent.<span style="font-family: Arial,Helvetica,sans-serif;"><span style="font-weight: bold;"></span></span></p>
+<a name="Section2|region"></a>
+<h1 align="center">Section
+2:
+How-to Guide</h1>
+<p align="center">(note:
+this section is a
+work in progress which does not yet fully address&nbsp;Editing
+Roles)</p>
+<h4>Defining a custom User Group <font size="-1">(not
+required for direct user role assignment)</font></h4>
+<ol class="step_list">
+<li>Go
+to WP Admin
+-&gt; Groups</li>
+<li>Click
+the &#8220;Add New&#8221;
+scroll link</li>
+<li>Enter
+a group name
+and description</li>
+<li>Select
+checkboxes
+for Group Members</li>
+<li>Optionally,
+select
+Group Administrators
+(WP admin can always manage group)</li>
+<li>Click
+the Create
+button</li>
+</ol>
+<p>Groups
+created in this manner will be available for role assignment in the
+following
+procedures.</p>
+<p>Role
+Scoper can be configured to hide or reveal posts regardless of any
+WP-defined
+&#8220;private&#8221; status. The procedures below are sufficient to set post
+visibility.
+However, there are three reasons you might still choose to set the WP
+&#8220;private&#8221;
+status:</p>
+<ul>
+<li>Setting
+the WP &#8220;private&#8221; status will enable more flexibility in controlling
+read access
+per category</li>
+<li>A
+post that has the WP &#8220;private&#8221; status will continue to be hidden if
+Role Scoper
+is accidentally uninstalled.</li>
+<li>Setting
+the WP &#8220;private&#8221; status will make the posts easier to administer,
+taking
+advantage of &#8220;Manage Posts&#8221; filtering provided by the WP core</li>
+</ul>
+<p>The
+following procedures apply regardless of whether you check the &#8220;keep
+this post
+private&#8221; box:</p>
+<h4><b>Restricting
+Read Access to an Individual Post/Page</b></h4>
+<ol class="step_list">
+<li>Enter
+the WordPress
+Write Post / Edit
+Post interface</li>
+<li>Scroll
+down to the
+&#8220;Readers&#8221; tab (under
+&#8220;Advanced Options&#8221;) and expand it</li>
+<li>Check
+the
+&#8220;Restrict&#8221; checkbox at the
+bottom of the tab</li>
+<li>Save
+the post</li>
+</ol>
+<p>The
+post will now be hidden from WP Subscribers who are not selected in
+this
+&#8220;Readers&#8221; tab.&nbsp; If the post must also be hidden from WP
+Contributors, set
+the &#8220;Restrict&#8221; checkbox in the &#8220;Contributors&#8221; tab.&nbsp; To hide
+it from WP
+Authors and Editors, set the &#8220;Restrict&#8221; checkbox in the &#8220;Editors&#8221;
+tab.&nbsp;
+In Role Scoper lingo, the post&nbsp;now&nbsp;Restricts the
+checked
+roles.</p>
+<h4>Granting Read Access to an Individual Post/Page</h4>
+<ol class="step_list">
+<li><span style="font-weight: normal;">Decide
+whether you
+want to manage
+permissions user-by-user, for Wordpress role &#8220;groups&#8221;, and/or for
+custom-defined User Groups.&nbsp;</span> If custom user
+groups are
+desired, define
+those first (see above).</li>
+<li>Enter
+the WordPress
+Write Post / Edit
+Post interface</li>
+<li>Scroll
+down to the
+&#8220;Readers&#8221; tab (under
+&#8220;Advanced Options&#8221;) and expand it</li>
+<li>Select
+the checkbox
+of any User and/or
+Group who should have read access</li>
+<li>Save
+the Post</li>
+</ol>
+<p>If
+it's convenient to manage each hidden post/page with the above
+procedures,
+that's all you need to know.&nbsp; If access control by category is
+desirable,
+read on.</p>
+<h4><b>Restricting
+Read Access by Post Category</b></h4>
+<ol class="step_list">
+<li>Go
+to WP Admin
+-&gt; Restrictions -&gt; Category</li>
+<li>Scroll
+down to your
+category of interest,
+perhaps using the scroll link at top</li>
+<li>Select
+the &#8220;Private
+Post Reader&#8221; checkbox
+to restrict read access to private posts by anonymous users and WP
+Subscribers</li>
+<li>Optionally,
+select
+the &#8220;Post Reader&#8221;
+checkbox to restrict read access to non-private posts by anonymous
+users and WP
+Subscribers <span style="font-weight: normal;">(if the WP
+Subscriber role has not been modified to include
+read_private_posts)</span></li>
+<li>Scroll
+to the top</li>
+<li style="font-weight: normal;">Note
+that the
+adjacent dropdown indicates
+that the Update action will cause blog-wide assignment of the selected
+roles to
+be ignored for posts in the selected category.</li>
+<li>Click
+the Update
+button</li>
+</ol>
+<h4><b>Granting
+Read Access by Post Category</b></h4>
+<ol class="step_list">
+<li>Go
+to WP Admin
+-&gt; Roles -&gt; Category
+<br></li>
+<li>Scroll
+down to your
+category of interest,
+perhaps using the scroll link at top</li>
+<li>Select
+the roles you
+would like to assign</li>
+<li>Scroll
+to the top</li>
+<li>Select users and/or
+groups to assign&nbsp;selected roles</li>
+<li style="font-weight: normal;">Note
+that the
+adjacent dropdown indicates
+that the Update action will cause the selected roles to be assigned
+for
+posts in the selected section.&nbsp;</li>
+<li>If
+you want the same
+role to also be
+assigned for all current and future subcategories, change the dropdown
+to
+&#8220;assign for selected and sub-categories&#8221;.</li>
+<li>Click
+the Update
+button</li>
+</ol>
+<p>Note
+that <b>if</b> a Post Restriction is <b>not</b> set for Readers, read
+access to it will be granted if:</p>
+<ul>
+<li>the
+user has a qualifying Category Role in any post category</li>
+</ul>
+<div style="margin-left: 80px;"><span style="font-weight: bold;">-
+OR -</span></div>
+<ul>
+<li><b>any
+</b>of
+the post's categories
+do not ignore the user's qualifying blog-wide general role (or another qualifying
+role it
+contains)</li>
+</ul>
+<p>So
+you <b>cannot </b>hide a post just by assigning it to an
+additional &#8220;hidden&#8221;
+category.&nbsp; If individual posts don't restrict the Readers role,
+they will be readable if <b>any</b> of their categories
+are readable to the
+user.&nbsp;&nbsp; If your categorization and post restriction
+goals demand the
+&#8220;readable cat + hidden cat = hidden post&#8221; formula, you'll be frustrated
+with
+this plugin.&nbsp; But here are some suggestions for making the
+Role Scoper
+model work with your existing categories:</p>
+<ul>
+<li>As
+mentioned above, different role requirements and assignments can be
+made for
+&#8220;private&#8221; and &#8220;non-private&#8221; posts in the same category.</li>
+<li>Depending
+on how your theme displays categories, you could move some &#8220;Category A&#8221;
+posts
+into a new subcategory ( Category A / Category A*), and remove them
+from
+&#8220;Category A&#8221;.&nbsp; Then set Category Restrictions and Category Role assignments for Category A*.</li>
+</ul>
+<p></p>
+<h4><b>Restrict
+Posting
+/ Editing by Category</b></h4>
+<p>There
+are two pieces:
+granting access and restricting access, and two basic ways to achieve
+the
+desired access and restrictions:</p>
+<ul type="disc">
+<li>Start
+with user(s) who have too little access and elevate them</li>
+<li>Start
+with user(s) who have too much access and restrict them</li>
+</ul>
+<p>You can also use some
+combination
+of the two.&nbsp; Where
+possible simplify your life by setting your users as WordPress
+subscribers,
+then following the first Role Scoper configuration procedure
+below.&nbsp; This also provides the
+greatest security,
+since those users will default to zero editing ability if Role Scoper
+is
+accidentally deactivated or otherwise disabled.</p>
+<h4><b>Enabling
+a
+Subscriber to Post in specific Categor(ies)</b></h4>
+<ol class="step_list">
+<li>Set
+UserA to WordPress role of Subscriber</li>
+<li>Assign
+a Category Role of Post Author to UserA for the desired category (WP
+Admin &gt;
+Roles &gt; Category)</li>
+</ol>
+<p>If some users need to
+retain a
+higher WordPress role
+but still be limited in posting categories, you will also need to
+define that
+extra restriction as follows:</p>
+<p></p>
+<h4><b>Restricting
+Posting Categor(ies) for Contributor/Author/Editor</b></h4>
+<ol class="step_list">
+<li>Go
+to the Category Restrictions admin
+page&nbsp;<br>
+(WP Admin &gt; Restrictions &gt; Category)</li>
+
+<li>In the "DEFAULTS" table, check
+the boxes for &#8220;Post
+Contributor&#8221; and &#8220;Post Author&#8221;.&nbsp; Also &#8220;Post Editor&#8221; if you
+want to
+restrict WP editors.</li><li>Confirm
+the dropdowns next to
+Update button say &#8220;Restrict selected roles" and "for selected categories"</li>
+<li>Click
+Update</li>
+
+</ol>
+<p>Now Contributor and
+Authors (and
+editors, if you restricted
+that role) will not be able to post or edit in any&nbsp;category
+unless you assign them a Category Role for it, as explained for UserA
+above. &nbsp;Note that the "DEFAULTS" setting applies the restriction
+to all existing and future categories (unless one is manually
+unrestricted). &nbsp;To restrict fewer categories, select desired
+restrictions for each category instead.</p>
+<br>
+<h4><b><b>Enabling a User to Edit Specific Page(s),
+and Nothing Else:</b></b></h4>
+<ol class="step_list">
+<li> Give them a WordPress role of Subscriber</li>
+<li>Manage &gt; Pages &gt; Edit their page</li>
+<li>Expand the "Editors" tab under "Advanced Options"</li>
+<li>Check the non-braced checkbox to the left of your user's
+name&nbsp;<span style="font-weight: normal;">(if subpages will be created, also check the braced checkbox {[]}, which
+assigns the role for all current or future subpages)</span></li>
+<li>Save the Page</li>
+</ol>
+<p>Note that if you also assign this user a Role Scoper General Role
+of
+Page Author, they will be able to create subpages off their member
+page, but not off any other pages:</p>
+<ol class="step_list">
+<li> Go to WP Admin &gt; Roles &gt; General</li>
+<li>&nbsp;Select your user name(s)</li>
+<li>&nbsp;Select the Page Author role</li>
+<li>&nbsp;Click Update</li>
+</ol>
+<p> <strong>OR</strong>, if you want all subscribers
+to have this ability:</p>
+<ol class="step_list">
+<li> Go to WP Admin &gt; Roles &gt; General</li>
+<li>Select [WP Subscriber]</li>
+<li>Select the Page Author role</li>
+<li>Click Update</li>
+</ol>
+<p></p>
+<a name="Section3|region"></a>
+<h1 align="center">Section
+3:
+Customizations and Extensions</h1>
+<p align="center">(note:
+this section will
+be expanded in future revisions)</p>
+<h3>Hidden
+Content Teaser</h3>
+<p>By
+default,
+Role Scoper hides content for which users lack a sufficient role
+assignment.
+You can also apply a teaser by activating that option in the Role
+Scoper
+options page at WP Admin &gt; Roles &gt; Roles.</p>
+<h3>Other
+Role Scoper Options</h3>
+<p>Other
+options
+on the Roles &gt; Options page pertain
+primarily to customizations
+of the Role Scoper for future plugin-defined data sources. Most users
+can
+safely leave the default settings. The settings available there do
+contains
+descriptive captions.</p>
+<h3>Template
+Functions</h3>
+<p>To
+support
+customized markup of restricted and/or currently hidden posts, Role
+Scoper
+provides the following template functions for use in themes:</p>
+<p><span style="font-family: &quot;Courier New&quot;; color: blue;">&nbsp;is_restricted_rs(
+);</span></p>
+<p><span style="font-family: &quot;Courier New&quot;; color: blue;">&nbsp;is_teaser_rs(
+);</span><br>
+<br>
+note:
+If
+calling these functions outside the WP loop, you should pass post ID as
+the
+first function argument. Otherwise just call as stated above.</p>
+<h3>Plugin
+API</h3>
+<p>Other
+plugins
+may define their own data sources, taxonomies (WP term_taxonomy or
+custom
+tables), capabilities and roles. See defaults_rs.php and
+role-scoper_main.php
+for example hook usage. Details will be provided in later versions of
+this
+document.</p>
+<p>A
+current
+version of this document is available online at </p>
+<p><a href="http://agapetry.net/downloads/RoleScoper_UsageGuide.htm">http://agapetry.net/downloads/RoleScoper_UsageGuide.htm</a></p>
+</div>
+</body></html>
87 admin/about.php
@@ -0,0 +1,87 @@
+<?php
+
+if( basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME']) )
+ die( 'This page cannot be called directly.' );
+
+
+require_once( SCOPER_ABSPATH . '/lib/agapetry_wp_admin_lib.php' ); // function awp_remote_fopen()
+
+
+function agp_is_ie6() {
+ $agent = strtolower($_SERVER['HTTP_USER_AGENT']);
+
+ if ( (false !== strpos($agent, 'msie 6.0') || false !== strpos($agent, 'msie 5.5'))
+ && ( false === strpos($agent, 'opera') && false === strpos($agent, 'firefox') && false === strpos($agent, 'safari') ) )
+ return true;
+}
+
+
+// Box CSS derived from "Even more rounded corners" by Scott Schiller
+// http://www.schillmania.com/content/projects/even-more-rounded-corners/
+echo ('
+<ul class="masthead"><li id="masthead-main" title="Agapetry Creations"><a class="agp-toplink" href="http://agapetry.net"> </a></li></ul>
+<div id="wrap" style="height: 100%">
+');
+
+echo('
+<div class="rc-about-dialog">
+<p>
+<a title="agape" href="http://www.merriam-webster.com/cgi-bin/audio.pl?agape002.wav=agape" target="_blank">a<small><small>&#8226;</small></small>ga<small><small>&#8226;</small></small>p&eacute;</a> (&alpha;&gamma;&alpha;&pi;&eta;):
+');
+_e('unselfish, benevolent love, born of the Spirit.', 'scoper');
+echo ('</p><p>');
+_e('Agap&eacute; discerns needs and meets them unselfishly and effectively.', 'scoper');
+echo ('</p><p>');
+
+printf(__('This WordPress plugin is part of my agap&eacute; try, a lifelong effort to love God and love people by rightly using the time and abilities He has leant me. As a husband, father, engineer, farmer and/or software developer, I have found this stewardship effort to be often fraught with contradiction. A wise and sustainable balancing of roles has seemed to elude me. Yet I want to keep trying, trusting that if God blesses and multiplies the effort, it will become agapetry, a creative arrangement motivated by benevolent love. A fleeting childlike sketch of the beautiful %1$s chain-breaking agap&eacute;%2$s which %3$s Jesus Christ unleashed%4$s so %5$s freely%6$s and aptly on an enslaving, enslaved world.', 'scoper'), '<a href="http://www.biblegateway.com/passage/?search=Isaiah%2059:1-60:3;Matthew%203:1-12;Luke%204:5-8;Matthew%205:1-48;Matthew%206:9-15;&version=50;" target="_blank">', '</a>', '<a href="http://www.biblegateway.com/passage/?search=Matthew%2020:20-28;Matthew%2026:36-49;John%2018:7-12;John%2019:1-30;1%20John%202:1-6;&version=47;" target="_blank">', '</a>', '<a href="http://www.biblegateway.com/passage/?search=Isaiah%2055;John%207:37-51;&version=47;" target="_blank">', '</a>');
+echo '</p><p>';
+printf(__('Although Role Scoper\'s development was a maniacal hermit-like effort, it was only possible because of the clean and flexible %1$s WordPress code base%2$s. My PHP programming skills grew immensely by the good examples set forth there and in plugins such as %3$s NextGen Gallery%4$s. I\'m not done learning, and look forward to some real-time cooperation with these and other developers now that my all-consuming quest has reached a stable plateau.', 'scoper'), "<a href='http://codex.wordpress.org/Developer_Documentation' target='_blank'>", '</a>', "<a href='http://alexrabe.boelinger.com/wordpress-plugins/nextgen-gallery/' target='_blank'>", '</a>');
+echo '</p><p>';
+
+printf( __('Role Scoper is currently available in the following languages, thanks to volunteer translators:', 'scoper') );
+echo '</p><ul class="rs-notes" style="margin-left: 1em">';
+echo '<li>';
+printf(__('Spanish by %1$s, technical revision by %2$s', 'scoper'), "<a href='http://www.rafo.cl/' target='_blank'>Rafo&copy; Computaci&oacute;n & Web</a>", "<a href='www.desarrollowebdequeretaro.com' target='_blank'>David G&oacute;mez Becerril</a>" );
+echo '</li><li>';
+printf(__('French by %s', 'scoper'), "<a href='http://chryjs.free.fr' target='_blank'>Chryjs</a>");
+echo '</li><li>';
+printf(__('Italian by %s', 'scoper' ), "<a href='http://obertfsp.com' target='_blank'>Alberto Ramacciotti</a>");
+echo '</li></ul><p>';
+_e( 'I do try to be translator-friendly, but any untranslated captions are likely due to a flurry of recent additions and changes by the plugin developer. Now there must be someone else who wants Role Scoper in their language...', 'scoper');
+echo '</p><p>';
+printf(__( 'Role Scoper is open source software released under the %1$s General Public License (GPL)%2$s. Due to limitations, obligations and non-technical aspirations common to most human beings, I will probably never again pursue uncommissioned plugin development on the scale Role Scoper has required. However, I do plan to provide some free support, correct bugs which emerge and revise the plugin for future WordPress versions. If it adds value to your website or saves you time and money, you can express appreciation in several ways:', 'scoper'), '<a href="http://www.opensource.org/licenses/gpl-license.php">', '</a>');
+echo '</p><ul id="agp-thanks" class="rs-notes" style="margin-left: 1em"><li>';
+printf(__('%1$s Submit technical feedback%2$s, including improvement requests.', 'scoper'), '<a href="http://agapetry.net/forum/">', '</a>');
+echo '</li><li>';
+printf(__('%1$s Submit a case study%2$s, explaining how Role Scoper helps you do something excellent and praiseworthy.', 'scoper'), '<a href="http://agapetry.net/forum/">', '</a>');
+echo '</li><li>';
+printf(__('%1$s Localize Role Scoper%2$s to your own language %3$s using poEdit%4$s ', 'scoper'), '<a href="http://weblogtoolscollection.com/archives/2007/08/27/localizing-a-wordpress-plugin-using-poedit/">', '</a>', '<a href="http://weblogtoolscollection.com/archives/2007/08/27/localizing-a-wordpress-plugin-using-poedit/">', '</a>');
+echo '</li><li>';
+$paypal_button = '<form action="https://www.paypal.com/cgi-bin/webscr" method="post" class="donate"><input type="hidden" name="cmd" value="_s-xclick" /> <input type="image" style="background:none" src="http://agapetry.net/btn_donate_SM.gif" name="submit" alt="PayPal - The safer, easier way to pay online!" /> <img alt="" border="0" src="http://agapetry.net/pixel.gif" width="1" height="1" style="opacity:0.01;" /> <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHRwYJKoZIhvcNAQcEoIIHODCCBzQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYBJ1SuZO67UwhfCgc0+nCBqoUlS+HeYvGJXiTHpd6jxN8kls6JQdxU917u9kVx99bZUEaPVoqgHX6hQ0locnaTCG04T0qgkpf/vuzVj5JFSxWscETkgsLUOe0uKbcFvD4amNjgd1qrF/9hIpyWW6onv2vaVKk92WZOL7TShKT9wbDELMAkGBSsOAwIaBQAwgcQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQI9ZIXcxAb7T+AgaCThXFd1yzgLF8M+wj7byobrurQlvnbEqSVhA6kI1yMCdxtcH5i5FoeK2tVFj/sSCkTYO722bvE4QRJNjSQTJW4JAhG8AcVdgc2y/pGkQjZpNva95P6GmwjeBYvqLHG7SzsaQ3o9BmWS/cASu5FFjeuKtTYQlFA/4mLZ6vTC4fu2KtUZ2bjm1ZN2/At18dGUIwpc7TuVYaVdatt/Ld3zJDZoIIDhzCCA4MwggLsoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0MDIxMzEwMTMxNVoXDTM1MDIxMzEwMTMxNVowgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBR07d/ETMS1ycjtkpkvjXZe9k+6CieLuLsPumsJ7QC1odNz3sJiCbs2wC0nLE0uLGaEtXynIgRqIddYCHx88pb5HTXv4SZeuv0Rqq4+axW9PLAAATU8w04qqjaSXgbGLP3NmohqM6bV9kZZwZLR/klDaQGo1u9uDb9lr4Yn+rBQIDAQABo4HuMIHrMB0GA1UdDgQWBBSWn3y7xm8XvVk/UtcKG+wQ1mSUazCBuwYDVR0jBIGzMIGwgBSWn3y7xm8XvVk/UtcKG+wQ1mSUa6GBlKSBkTCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCBXzpWmoBa5e9fo6ujionW1hUhPkOBakTr3YCDjbYfvJEiv/2P+IobhOGJr85+XHhN0v4gUkEDI8r2/rNk1m0GA8HKddvTjyGw/XqXa+LSTlDYkqI8OwR8GEYj4efEtcRpRYBxV8KxAW93YDWzFGvruKnnLbDAF6VR5w/cCMn5hzGCAZowggGWAgEBMIGUMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDgwNTEyMjAxNzEzWjAjBgkqhkiG9w0BCQQxFgQUREfauO+XY0Sx3gWNIf32ThKhGwAwDQYJKoZIhvcNAQEBBQAEgYBwz6QrznijNgQD/CjHJSAALEWI1bxRELLjnE1Cb29foQyB7WgDIyIpVMDwp0anrBKavtIOe202qN6pEHrEDvNCaC1EaX3uoV2d5eQ2xMHCTyVFAELMf72HABuzkReTlZhBHyQYR/17IEaOS3ixGb5CGMNWFn6oPtdmx+DEuF0dqg==-----END PKCS7-----
+" /></form>';
+printf(__('If the plugin has seriously broadened your CMS horizons, %s', 'scoper'), $paypal_button);
+echo '</li><li>';
+printf(__('If you are an established web developer, %1$s grant me your professional opinion%2$s on how this work stacks up. Might the skills, work ethic and values I express here fit into a development team near you?', 'scoper'), '<a href="http://agapetry.net/general-contact-form/">', '</a>');
+echo '</li><li>';
+
+// TODO: update translations once poEdit update is available to fix _x and _n handling
+if ( defined('WPLANG') && WPLANG )
+ printf(__('Hire or refer my services</a> to design, redesign or enhance your site - quality care at reasonable rates.', 'scoper'), '<a href="http://agapetry.net/service-exploration-form/">', '</a>');
+else
+ printf(__('Hire or refer my services</a> to develop or enhance your site - quality care at reasonable rates.', 'scoper'), '<a href="http://agapetry.net/service-exploration-form/">', '</a>');
+
+echo '</li></ul>';
+
+//if ( $status = awp_remote_fopen( 'http://localhost/aglocal/downloads/status.htm', 5) )
+if ( $status = awp_remote_fopen( 'http://agapetry.net/downloads/status.htm', 5) )
+ echo $status;
+
+echo '</div>'; //rc-about-dialog
+
+if ( ! agp_is_ie6() )
+ echo '<div class="madein alignright" style="margin-right: 1em;">&nbsp;</div>';
+
+echo '<div style="height: 150px;">&nbsp;</div>';
+
+echo '</div>'; //wrap
+?>
109 admin/about/about.css
@@ -0,0 +1,109 @@
+#wpbody-content, #wrap {
+ background-color: #7E7B68;
+ background: url(img/field6b.jpg);
+ background-repeat: repeat;
+ padding-top:0;
+}
+
+#wrap {
+ height: 100%;
+ margin: 0;
+}
+
+/* for WP < 2.7 */
+#wpcontent, #wpwrap {
+ padding-bottom: 0;
+}
+
+#screen-meta-links {
+ display: none;
+}
+
+#masthead-main {
+ background: url(img/agapetry-header_finalG.jpg);
+ background-repeat: no-repeat;
+ width: 525px;
+}
+
+.masthead {
+ width: 100%;
+ margin: 0;
+ padding: 0;
+ height: 149px;
+ color: white;
+ background-color: #7E7B68;
+ background: url(img/agapetry-header-repeatE.jpg);
+ background-repeat: repeat-x;
+}
+
+.masthead li {
+ list-style: none;
+ margin: 0;
+ height: 149px;
+}
+
+.masthead li a {
+ display: block;
+ width: 525px;
+ height: 149px;
+ text-decoration: none;
+}
+
+a.agp-toplink, a.agp-toplink:hover {
+ text-decoration: none;
+}
+
+#wpbody-content a img {border:0;}
+
+.donate {
+ opacity: 0.75;
+ margin: 0 0 0 0.5em;
+}
+
+.donate:hover {
+ opacity: 1.0;
+}
+
+/* Links */
+#wrap a {color:#87c0fc; font-weight:700; text-decoration:none;}
+#wrap a:hover {color:#fcd987; font-weight:700; text-decoration:underline;}
+
+/* Headers */
+#wrap h2 {font-size:1.8em;}
+#wrap h3 {font-size:1.5em;}
+
+#wrap p {
+ line-height: 1.5em;
+ margin-bottom: 1.3em;
+}
+
+#agp-thanks li {
+ line-height: 1.5em;
+}
+
+.small {font-size:0.8em;}
+
+.madein {
+ background: url(img/madein_mich_logo_40.png) no-repeat;
+ width: 110px;
+ height: 132px;
+ margin: 1.5em 0 0 2em;
+}
+
+.madein a {
+ display: block;
+ width: 110px;
+ height: 132px;
+}
+
+.rc-about-dialog {
+ min-width: 8em;
+ max-width: 760px;
+ color: #fff;
+ background-color: #1A4C1A;
+ opacity:.85;
+ -moz-opacity:.85;
+ margin: 0 0.5em 0 0.5em;
+ padding: 0.05em 0.5em 0.2em 0.5em;
+ border: 1px solid #aaa;
+}
74 admin/about/dialog-align.css
@@ -0,0 +1,74 @@
+/* default alignment for rounded corner boxes (dialog.css) */
+
+.rc-topper .rc-t,
+.rc-topper .rc-t-left {
+ background:transparent url(dialog2-green-top5d.png) no-repeat top right;
+ opacity:.85;
+ -moz-opacity:.85;
+}
+
+.rc-bottomer .rc-b,
+.rc-bottomer .rc-b-left {
+ background:transparent url(dialog2-green-bottom5d.png) no-repeat top right;
+ opacity:.85;
+ -moz-opacity:.85;
+}
+
+.rc-topper .rc-t,
+.rc-bottomer .rc-b {
+ border-right: 1px solid transparent; /* otherwise td runs beyond table bounds. same effect as nbsp, but without messing height */
+}
+
+.rc-topper,
+.rc-bottomer {
+ border: none;
+}
+
+.rc-topper tr,
+.rc-bottomer tr {
+ padding: 0;
+ margin: 0;
+}
+
+.rc-topper tr td,
+.rc-bottomer tr td{
+ padding: 0;
+ margin: 0;
+}
+
+.rc-topper .rc-t,
+.rc-bottomer .rc-b {
+ background-position:bottom right;
+}
+
+.rc-topper .rc-t-left,
+.rc-bottomer .rc-b-left {
+ width:20px; /* bottom corner width */
+ background-position:bottom left;
+}
+
+
+/* the rest was non-IE specific when we attempted to round IE corners */
+.rc-topper .rc-t,
+.rc-topper .rc-t-left,
+.rc-topper .rc-b,
+.rc-topper .rc-b-left {
+ height:12px; /* height of bottom cap/shade */
+}
+
+.rc-topper {
+ margin: 0;
+}
+
+.rc-topper,
+.rc-bottomer {
+ width: 100%
+}
+
+#wrap {
+ margin-top: -25px;
+}
+
+#leftside {
+ margin-top: 5px;
+}
22 admin/about/dialog-alignIE.css
@@ -0,0 +1,22 @@
+/* IE 5.5 / 6 alignment: gave up on rounded corners */
+
+.rc-dialog .rc-content {
+ _background-image: url(dialog2-green-mid5d.gif);
+ filter: alpha(opacity=80);
+ padding-top: 0.35em;
+ margin: 0 8px 10px -4px;
+ border: 1px solid #aaa;
+}
+
+#wrap {
+ margin-top: -20px;
+}
+
+#leftside {
+ margin-top: 0px;
+}
+
+#contentwide {
+ margin-top: 0 15px 0 15px;
+ padding 0 5px 0 5px;
+}
37 admin/about/dialog.css
@@ -0,0 +1,37 @@
+/*
+ -- Even more rounded corners with CSS: Base stylesheet --
+ by Scott Schiller
+ http://www.schillmania.com/content/projects/even-more-rounded-corners/
+
+ (extensive modifications by Kevin Behrens - original used a single large png)
+*/
+
+.rc-dialog {
+ margin: 0 0.1em 0.5em 0.1em;
+ min-width: 8em;
+ max-width: 760px;
+ color: #fff;
+}
+
+.rc-dialog .rc-content {
+ background:transparent url(dialog2-green-mid5d.png) repeat-y top right;
+ opacity: .92;
+ -moz-opacity: .92;
+ margin: -1px 0 -1px 0;
+ height: 100%;
+ border-bottom: 1px solid transparent; /* Opera fix (otherwise background is not painted through entire height) */
+}
+
+.rc-dialog .rc-content {
+ padding: 0 1em 0 0.5em;
+}
+
+.rc-dialog h1,
+.rc-dialog p {
+ margin: 0;
+ padding: 0.5em 0 0.5em 0;
+}
+
+.rc-dialog h1 {
+ padding-bottom: 0;
+}
BIN  admin/about/dialog2-green-bottom5d.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  admin/about/dialog2-green-bottom5d.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  admin/about/dialog2-green-mid5d.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  admin/about/dialog2-green-mid5d.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  admin/about/dialog2-green-top5d.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  admin/about/dialog2-green-top5d.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  admin/about/dialog2-greenB2-800x1600.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  admin/about/img/agapetry-header-repeatE.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  admin/about/img/agapetry-header_finalG.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  admin/about/img/field6b.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  admin/about/img/madein_mich_logo_40.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1,118 admin/admin-bulk_rs.php
@@ -0,0 +1,1118 @@
+<?php
+if( basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME']) )
+ die();
+
+require_once(dirname(__FILE__).'/admin_lib-bulk_rs.php' );
+require_once(dirname(__FILE__).'/admin_ui_lib_rs.php');
+require_once( SCOPER_ABSPATH . '/hardway/hardway-parent_rs.php');
+
+class ScoperAdminBulk {
+
+function get_agents($role_bases = '') {
+ if ( empty($role_bases) )
+ $role_bases = array(ROLE_BASIS_USER, ROLE_BASIS_GROUPS);
+
+ $agents = array();
+
+ if ( in_array(ROLE_BASIS_USER, $role_bases) ) {
+ global $scoper;
+ $agents[ROLE_BASIS_USER] = $scoper->users_who_can('', COLS_ID_NAME_RS);
+ }
+
+ if ( in_array(ROLE_BASIS_GROUPS, $role_bases) ) {
+ $agents[ROLE_BASIS_GROUPS] = ScoperAdminLib::get_all_groups(UNFILTERED_RS);
+ if ( ! $agents[ROLE_BASIS_GROUPS] )
+ unset( $agents[ROLE_BASIS_GROUPS] );
+ }
+
+ return $agents;
+}
+
+function agent_names($agents) {
+ $agent_names = array();
+ foreach ( array_keys($agents) as $role_basis )
+ foreach( $agents[$role_basis] as $agent )
+ $agent_names[$role_basis][$agent->ID] = str_replace(' ', '&nbsp;', $agent->display_name);
+
+ return $agent_names;
+}
+
+function agent_list_prefixes() {
+ $agent_list_prefix = array();
+ $agent_list_prefix[ROLE_BASIS_USER] = '';
+ $agent_list_prefix[ROLE_BASIS_GROUPS] = __('Groups') . ': ';
+
+ return $agent_list_prefix;
+}
+
+function agent_captions_plural($role_bases) {
+ if ( count($role_bases) > 1 )
+ return __('Users or Groups', 'scoper');
+ elseif ( in_array(ROLE_BASIS_USER, $role_bases) )
+ return __awp('Users');
+ elseif ( in_array(ROLE_BASIS_GROUPS, $role_bases) )
+ return __('Groups', 'scoper');
+}
+
+function agent_captions($role_bases) {
+ if ( count($role_bases) > 1 )
+ return __('User / Group', 'scoper');
+ elseif ( in_array(ROLE_BASIS_USER, $role_bases) )
+ return __('User', 'scoper');
+ elseif ( in_array(ROLE_BASIS_GROUPS, $role_bases) )
+ return __('Group', 'scoper');
+}
+
+function get_role_codes() {
+ global $scoper;
+
+ $role_defs = $scoper->role_defs->get_matching('rs');
+
+ $role_codes = array(); //generate temporary numeric id for each defined role, to reduce html bulk
+ $i = 0;
+ foreach( array_keys($role_defs) as $role_handle) {
+ $role_codes[$role_handle] = $i;
+ $i++;
+ }
+ return $role_codes;
+}
+
+function display_inputs($mode, $assignment_modes, $args = array()) {
+ $defaults = array( 'role_bases' => '', 'agents' => '', 'agent_caption_plural' => '', 'max_scopes' => array(), 'scope' => '', 'src_or_tx_name' => '' );
+ $args = array_merge($defaults, (array) $args);
+ extract($args);
+
+ global $scoper;
+
+ echo "<br /><a name='scoper_submit'></a>";
+
+ echo '<ul class="rs-list_horiz"><li style="float:left;"><h3>1.&nbsp;';
+
+ if ( ROLE_ASSIGNMENT_RS == $mode ) {
+ $msg = __('Select Assignment Mode', 'scoper');
+ echo "$msg</h3></li>";
+
+ if ( OBJECT_SCOPE_RS == $scope ) {
+ $src = $scoper->data_sources->get($src_or_tx_name);
+ $date_col_defined = ! empty( $src->cols->date );
+ } elseif ( TERM_SCOPE_RS == $scope ) {
+ $tx = $scoper->taxonomies->get($src_or_tx_name);
+ $date_col_defined = $scoper->data_sources->member_property( $tx->object_source, 'cols', 'date' );
+ } else
+ $date_col_defined = true;
+
+ $duration_limits_enabled = $date_col_defined && scoper_get_option('role_duration_limits');
+ $content_date_limits_enabled = ( OBJECT_SCOPE_RS != $scope ) && $date_col_defined && scoper_get_option('role_content_date_limits');
+
+ $num = ( $duration_limits_enabled || $content_date_limits_enabled ) ? 5 : 4;
+ } else {
+ $msg = __('Select Restriction Mode', 'scoper');
+ echo "$msg</h3></li>";
+ $num = 3;
+
+ $duration_limits_enabled = $content_date_limits_enabled = false;
+ }
+
+ echo "<li style='float:right;'><h3>$num.&nbsp;";
+ _e('Review and Submit', 'scoper');
+ echo '</h3></li>';
+ echo '</ul>';
+ ?>
+
+ <ul class="rs-list_horiz">
+
+ <?php
+ if( ROLE_RESTRICTION_RS == $mode ) {
+ echo '<li>';
+ echo '<select id="max_scope" name="max_scope">';
+ $retain_value = ( isset($_POST["max_scope"]) ) ? $_POST["max_scope"] : '';
+
+ foreach($max_scopes as $max_scope => $caption) {
+ $selected = ( $status_id === $retain_value ) ? 'selected="selected"' : '';
+ echo "<option value='$max_scope' $selected>$caption</option>";
+ }
+ echo '</select></li>';
+ }
+ ?>
+
+ <li style="margin-left:0.5em">
+ <?php
+ $for_name = ( ROLE_ASSIGNMENT_RS == $mode ) ? 'assign_for' : 'require_for';
+ echo "<select id='$for_name' name='$for_name'>";
+ $retain_value = ( isset($_POST[$for_name]) ) ? $_POST[$for_name] : 0;
+
+ foreach($assignment_modes as $status_id => $caption) {
+ $selected = ( $status_id === $retain_value ) ? 'selected="selected"' : '';
+ echo "<option value='$status_id' $selected>$caption</option>";
+ }
+ echo '</select>';
+ ?>
+ </li><li style='margin: 0 0.25em 0.25em 0.5em;padding-top:0.35em;'>
+
+ </li>
+ <li style='float:right;margin: 0 0.25em 0.25em 0.25em;'><span class="submit" style="border:none;">
+ <input type="submit" name="rs_submit" class="button-primary" value="<?php _e('Update &raquo;', 'scoper');?>" />
+ </span></li>
+ </ul>
+ <p style="clear:both"></p>
+ <?php
+ if ( ROLE_ASSIGNMENT_RS == $mode ) {
+ echo '<br /><h3>2.&nbsp;';
+ //printf( _ x('Select %s to Modify', 'Users or Groups', 'scoper'), $agent_caption_plural );
+ printf( __('Select %s to Modify', 'scoper'), $agent_caption_plural );
+ echo '</h3>';
+
+ $args = array( 'suppress_extra_prefix' => true, 'filter_threshold' => 20, 'default_hide_threshold' => 20, 'check_for_incomplete_submission' => true );
+ require_once(dirname(__FILE__).'/agents_checklist_rs.php');
+ ScoperAgentsChecklist::all_agents_checklist($role_bases, $agents, $args);
+
+ echo '<p style="clear:both"></p>';
+ echo '<hr />';
+ }
+ //=================== end users/groups and assignment mode selection display ====================
+
+ if ( $duration_limits_enabled || $content_date_limits_enabled ) {
+ echo '<br /><h3 style="margin-bottom: 0">3.&nbsp;';
+ _e('Set Role Duration and/or Content Date Limits (optional)', 'scoper');
+ echo '</h3>';
+
+ ScoperAdminBulkLib::display_date_limit_inputs( $duration_limits_enabled, $content_date_limits_enabled );
+ }
+
+ if ( ROLE_ASSIGNMENT_RS == $mode ) {
+ $num = ( $duration_limits_enabled || $content_date_limits_enabled ) ? 4 : 3;
+ echo "<br /><h3>$num.&nbsp;";
+ $msg = __('Select Roles to Assign / Remove', 'scoper');
+ echo "$msg</h3>";
+ } else {
+ $num = 2;
+ echo "<br /><h3>$num.&nbsp;";
+ $msg = __('Select Roles to Modify', 'scoper');
+ echo "$msg</h3>";
+ }
+}
+
+function role_submission($scope, $mode, $role_bases, $src_or_tx_name, $role_codes, $agent_caption_plural, $nonce_id) {
+ global $scoper;
+ $role_assigner = init_role_assigner();
+
+ $err = 0;
+ $role_count = 0;
+ check_admin_referer( $nonce_id );
+
+ $set_roles = array();
+ $selected_roles = isset($_POST['roles']) ? $_POST['roles'] : array();
+
+ if ( OBJECT_SCOPE_RS == $scope ) {
+ $src = $scoper->data_sources->get($src_or_tx_name);
+ $date_col_defined = ! empty( $src->cols->date );
+ } elseif ( TERM_SCOPE_RS == $scope ) {
+ $tx = $scoper->taxonomies->get($src_or_tx_name);
+ $date_col_defined = $scoper->data_sources->member_property( $tx->object_source, 'cols', 'date' );
+ } else
+ $date_col_defined = true;
+
+ switch ($mode) {
+ case ROLE_ASSIGNMENT_RS:
+ $assign_for = $_POST['assign_for'];
+
+ $selected_agents = array();
+ foreach ( $role_bases as $role_basis ) {
+ if ( ! empty($_POST[$role_basis]) )
+ $selected_agents[$role_basis] = $_POST[$role_basis];
+ else {
+ $csv_id = "{$role_basis}_csv";
+ if ( ! empty( $_POST[$csv_id] ) )
+ $selected_agents[$role_basis] = ScoperAdminLib::agent_ids_from_csv( $csv_id, $role_basis );
+ else
+ $role_bases = array_diff($role_bases, array($role_basis) );
+ }
+ }
+
+ $agents_msg = array();
+ $valid_role_selection = ! empty($selected_roles);
+
+ $duration_limits_enabled = $date_col_defined && scoper_get_option('role_duration_limits');
+ $content_date_limits_enabled = $date_col_defined && scoper_get_option('role_content_date_limits');
+ break;
+
+ case ROLE_RESTRICTION_RS:
+ $role_bases = array('n/a');
+ $default_restrictions = isset($_POST['default_restrictions']) ? $_POST['default_restrictions'] : array();
+ $max_scope = $_POST['max_scope'];
+ $require_for = $_POST['require_for'];
+ $selected_agents = array('n/a' => array(0) );
+ $valid_role_selection = ! empty($selected_roles) || ! empty($default_restrictions);
+ $modcount = 0;
+
+ $duration_limits_enabled = $content_date_limits_enabled = false;
+ break;
+ }
+
+ if ( ! $selected_agents ) {
+ $_POST['scoper_error'] = 1;
+ echo '<div id="message" class="error"><p><strong>';
+ printf( __('Error: no %s were selected!', 'scoper'), $agent_caption_plural);
+ echo '</strong></p></div>';
+ $err = 1;
+ } elseif ( ! $valid_role_selection ) {
+ $_POST['scoper_error'] = 1;
+ echo '<div id="message" class="error"><p><strong>';
+ _e('Error: no roles were selected!', 'scoper');
+ echo '</strong></p></div>';
+ $err = 2;
+ } else {
+ if ( ROLE_ASSIGNMENT_RS == $mode ) {
+ if ( ! empty($_POST['set_role_duration']) || ! empty($_POST['set_content_date_limits']) )
+ $date_entries_gmt = ScoperAdminBulkLib::process_role_date_entries();
+ }
+
+ foreach ( $role_bases as $role_basis ) {
+ foreach($selected_agents[$role_basis] as $agent_id) {
+ // must set default restrictions first
+ if ( ! empty($default_restrictions) ) {
+ $def_roles = array();
+ foreach($default_restrictions as $role) {
+ $keys = explode('-', $role); //keys[0]=role_code, 1=term_id or obj_id
+
+ if ( count($keys) < 2 )
+ continue;
+
+ if ( ! $role_handle = array_search($keys[0], $role_codes) )
+ continue;
+
+ $def_roles[ $keys[1] ][ $role_handle ] = array( 'max_scope' => $max_scope, 'for_item' => false, 'for_children' => true );
+ $modcount++;
+ }
+
+ $role_assigner->restrict_roles($scope, $src_or_tx_name, 0, $def_roles[0], array('force_flush' => true) );
+ }
+
+ if ( ! empty($selected_roles) ) {
+ foreach($selected_roles as $role) {
+ $keys = explode('-', $role); //keys[0]=role_code, 1=term_id or obj_id, 2=group_id or user_id
+
+ if ( count($keys) < 2 )
+ continue;
+
+ if ( ! $role_handle = array_search($keys[0], $role_codes) )
+ continue;
+
+ switch ($mode) {
+ case ROLE_ASSIGNMENT_RS:
+ $set_roles[ $role_basis ][ $keys[1] ][ $role_handle ][ $agent_id ] = ( $keys[1] || ! $assign_for ) ? $assign_for : ASSIGN_FOR_CHILDREN_RS; // always assign default category assignments as for_children
+ break;
+
+ case ROLE_RESTRICTION_RS:
+ $for_item = (ASSIGN_FOR_ENTITY_RS == $require_for) || (ASSIGN_FOR_BOTH_RS == $require_for);
+ $for_children = (ASSIGN_FOR_CHILDREN_RS == $require_for) || (ASSIGN_FOR_BOTH_RS == $require_for);
+ $set_roles[ $keys[1] ][ $role_handle ] = array( 'max_scope' => $max_scope, 'for_item' => $for_item, 'for_children' => $for_children );
+ $modcount++;
+ break;
+ }
+ }
+ }
+ }// end foreach selected agents
+
+ if ( ROLE_ASSIGNMENT_RS == $mode ) {
+ $args = array( 'force_flush' => true, 'set_role_duration' => '', 'set_content_date_limits' => '' );
+
+ if ( $duration_limits_enabled && ! empty($_POST['set_role_duration']) ) {
+ $is_limited = ( $date_entries_gmt->start_date_gmt || ( $date_entries_gmt->end_date_gmt != SCOPER_MAX_DATE_STRING ) || ! empty( $_POST['start_date_gmt_keep-timestamp'] ) || ! empty( $_POST['end_date_gmt_keep-timestamp'] ) );
+ $args[ 'set_role_duration' ] = (object) array( 'date_limited' => $is_limited, 'start_date_gmt' => $date_entries_gmt->start_date_gmt, 'end_date_gmt' => $date_entries_gmt->end_date_gmt );
+ }
+
+ if( $content_date_limits_enabled && ! empty($_POST['set_content_date_limits']) ) {
+ $is_limited = ( $date_entries_gmt->content_min_date_gmt || ( $date_entries_gmt->content_max_date_gmt != SCOPER_MAX_DATE_STRING ) || ! empty( $_POST['content_min_date_gmt_keep-timestamp'] ) || ! empty( $_POST['content_max_date_gmt_keep-timestamp'] ) );
+ $args[ 'set_content_date_limits' ] = (object) array( 'content_date_limited' => $is_limited, 'content_min_date_gmt' => $date_entries_gmt->content_min_date_gmt, 'content_max_date_gmt' => $date_entries_gmt->content_max_date_gmt );
+ }
+
+ if ( isset($set_roles[$role_basis]) )
+ foreach ( $set_roles[$role_basis] as $id => $item_roles )
+ $role_assigner->assign_roles($scope, $src_or_tx_name, $id, $item_roles, $role_basis, $args );
+ } else {
+ foreach ( $set_roles as $id => $item_roles )
+ $role_assigner->restrict_roles($scope, $src_or_tx_name, $id, $item_roles, array('force_flush' => true) );
+ }
+
+ if ( ! empty($selected_agents[$role_basis]) ) {
+ if ( ROLE_BASIS_USER == $role_basis )
+ $agents_msg []= sprintf(_n("%d user", "%d users", count($selected_agents[$role_basis]), 'scoper'), count($selected_agents[$role_basis]) );
+ else
+ $agents_msg []= sprintf(_n("%d group", "%d groups", count($selected_agents[$role_basis]), 'scoper'), count($selected_agents[$role_basis]) );
+ }
+ } // end foreach role basis
+
+ echo '<div id="message" class="updated fade"><p>';
+
+ switch ($mode) {
+ case ROLE_ASSIGNMENT_RS:
+ $roles_msg = sprintf(_n("%d role selection", "%d role selections", count($selected_roles), 'scoper'), count($selected_roles) );
+ $agents_msg = implode( ", ", $agents_msg );
+ //printf( _ x('Role Assignments Updated: %1$s for %2$s', 'n role selections for x users, y groups', 'scoper'), $roles_msg, $agents_msg );
+ printf( __('Role Assignments Updated: %1$s for %2$s', 'scoper'), $roles_msg, $agents_msg );
+ break;
+
+ case ROLE_RESTRICTION_RS:
+ printf(_n("Role Restrictions Updated: %d setting", "Role Restrictions Updated: %d settings", $modcount, 'scoper'), $modcount );
+ break;
+ }
+
+ echo '</p></div>';
+
+ // allow the DB server a little time to refresh before querying what we just put in
+ global $wpdb;
+ $junk = scoper_get_col("SELECT assignment_id FROM $wpdb->user2role2object_rs LIMIT 10");
+ } //endif no input error
+
+ return $err;
+}
+
+function get_objects_info($object_ids, &$object_names, &$object_status, &$unlisted_objects, $src, $otype, $ignore_hierarchy) {
+ global $wpdb;
+
+ // buffer titles in case they are translated
+ if ( 'page' == $otype->name ) // todo: other hierarchical types?
+ $titles = ScoperAdminBulkParent::get_page_titles();
+
+ $col_id = $src->cols->id;
+ $col_name = $src->cols->name;
+
+ $cols = "$col_name, $col_id";
+ if ( isset($src->cols->parent) && ! $ignore_hierarchy ) {
+ $col_parent = $src->cols->parent;
+ $cols .= ", $col_parent";
+ } else
+ $col_parent = '';
+
+ $col_status = ( ! empty($src->cols->status) ) ? $src->cols->status : '';
+ if ( $col_status )
+ $cols .= ", $col_status";
+
+ $unroled_count = 0;
+ $unroled_limit = ( ! empty($otype->admin_max_unroled_objects) ) ? $otype->admin_max_unroled_objects : 999999;
+
+ if ( ! empty($src->cols->type) ) {
+ $otype_clause = "AND {$src->cols->type} = '$otype->name'";
+ if ( 'post' == $src->name )
+ $otype_clause .= "AND {$src->cols->status} != 'auto-draft'";
+ } else
+ $otype_clause = '';
+
+ $obj = '';
+
+ if ( $results = scoper_get_results("SELECT $cols FROM $src->table WHERE 1=1 $otype_clause ORDER BY $col_id DESC") ) {
+
+ foreach ( $results as $row ) {
+ if ( isset($titles[$row->$col_id]) )
+ $object_names[$row->$col_id] = $titles[$row->$col_id];
+ elseif ( 'post' == $src->name )
+ $object_names[$row->$col_id] = apply_filters( 'the_title', $row->$col_name, $row->$col_id );
+ else
+ $object_names[$row->$col_id] = $row->$col_name;
+
+ if ( $col_status )
+ $object_status[$row->$col_id] = $row->$col_status;
+
+ unset($obj);
+
+ if ( $col_parent ) // temporarily key by name for alpha sort of additional items prior to hierarchy sort
+ $obj = (object) array($col_id => $row->$col_id, $col_name => $row->$col_name, $col_parent => $row->$col_parent);
+ else
+ $obj = (object) array($col_id => $row->$col_id, $col_name => $row->$col_name);
+
+ // List only a limited number of unroled objects
+ if ( ($unroled_limit >= 0) && ! isset($object_ids[$row->$col_id]) ) {
+ if ( $unroled_count >= $unroled_limit ) {
+
+ $unlisted_objects[$row->$col_id] = $obj;
+ continue;
+ }
+ $unroled_count++;
+
+ }
+
+ $listed_objects[$row->$col_id] = $obj;
+ }
+ }
+
+ // restore buffered page titles in case they were filtered previously
+ if ( 'page' == $otype->name ) {
+ scoper_restore_property_array( $listed_objects, $titles, 'ID', 'post_title' );
+ scoper_restore_property_array( $unlisted_objects, $titles, 'ID', 'post_title' );
+ }
+
+ return $listed_objects;
+}
+
+function filter_objects_listing($mode, &$role_settings, $src, $object_type) {
+ global $wpdb;
+
+ $filter_args = array();
+
+ // only list role assignments which the logged-in user can administer
+ $filter_args['required_operation'] = OP_EDIT_RS;
+
+ // Possible TODO: re-implement OP_ADMIN distinction with admin-specific capabilities
+ /* global $scoper;
+
+ if ( cr_get_reqd_caps( $src->name, OP_ADMIN_RS, $object_type ) ) {
+ $filter_args['required_operation'] = OP_ADMIN_RS;
+ } else {
+ $reqd_caps = array();
+ foreach (array_keys($src->statuses) as $status_name) {
+ $admin_caps = $scoper->cap_defs->get_matching($src->name, $object_type, OP_ADMIN_RS, $status_name);
+ $delete_caps = $scoper->cap_defs->get_matching($src->name, $object_type, OP_DELETE_RS, $status_name);
+ $reqd_caps[$object_type][$status_name] = array_merge(array_keys($admin_caps), array_keys($delete_caps));
+ }
+ $filter_args['force_reqd_caps'] = $reqd_caps;
+ }
+ */
+
+ $qry = "SELECT $src->table.{$src->cols->id} FROM $src->table WHERE 1=1 AND {$src->cols->type} = '$object_type'";
+
+ //$filter_args['require_full_object_role'] = true;
+ $qry_flt = apply_filters('objects_request_rs', $qry, $src->name, $object_type, $filter_args);
+
+ if ( $cu_admin_results = scoper_get_col( $qry_flt ) )
+ $cu_admin_results = array_fill_keys( $cu_admin_results, true );
+
+ if ( ROLE_ASSIGNMENT_RS == $mode ) {
+ foreach ( array_keys($role_settings) as $role_basis )
+ foreach ( array_keys($role_settings[$role_basis]) as $obj_id )
+ if ( ! isset($cu_admin_results[$obj_id]) )
+ unset($role_settings[$role_basis][$obj_id]);
+ } else {
+ $setting_types = array('restrictions', 'unrestrictions');
+ foreach ($setting_types as $setting_type)
+ if ( isset($role_settings[$setting_type]) )
+ foreach ( array_keys($role_settings[$setting_type]) as $role_handle )
+ foreach ( array_keys($role_settings[$setting_type][$role_handle]) as $obj_id )
+ if ( ! isset($cu_admin_results[$obj_id]) )
+ unset($role_settings[$setting_type][$role_handle][$obj_id]);
+ }
+
+ return $cu_admin_results;
+}
+
+function item_tree_jslinks($mode, $args='') {
+ $defaults = array ( 'role_bases' => '', 'default_hide_empty' => false, 'hide_roles' => false, 'scope' => '', 'src' => '', 'otype' => '' );
+ $args = array_merge($defaults, (array) $args);
+ extract($args);
+
+ if ( (ROLE_ASSIGNMENT_RS == $mode) && empty($role_bases) )
+ $role_bases = array(ROLE_BASIS_USER, ROLE_BASIS_GROUPS);
+
+ $tr_display = (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) ? 'block' : 'table-row';
+
+ /* // this is problematic because some roles are mutually exclusive for assignment
+ echo "<a href='javascript:void(0);' onclick=\"agp_check_by_name('roles[]', true, false, true);\">";
+ _e('select all roles', 'scoper');
+ echo "</a> | ";
+ */
+
+ echo "<a href='javascript:void(0);' onclick=\"agp_check_by_name('roles[]', '', false, true);\">";
+ _e('unselect all roles', 'scoper');
+ echo '</a> | ';
+
+ if ( $role_bases && in_array(ROLE_BASIS_USER, $role_bases) ) {
+ echo "<a id='rs-hide_users' href='javascript:void(0);' onclick=\"agp_setcss('.user-csv','display','none');agp_set_display('rs-show_users','inline',this.id);\">";
+ _e('hide users', 'scoper');
+ echo '</a>';
+
+ echo "<a id='rs-show_users' style='display:none;' href='javascript:void(0);' onclick=\"agp_setcss('.user-csv','display','inline');agp_set_display('rs-hide_users','inline',this.id);\">";
+ _e('show users', 'scoper');
+ echo '</a> | ';
+ }
+
+ if ( $role_bases && in_array(ROLE_BASIS_GROUPS, $role_bases) ) {
+ echo "<a id='rs-hide_groups' href='javascript:void(0);' onclick=\"agp_setcss('.groups-csv','display','none');agp_set_display('rs-show_groups','inline',this.id);\">";
+ _e('hide groups', 'scoper');
+ echo '</a>';
+
+ echo "<a id='rs-show_groups' style='display:none;' href='javascript:void(0);' onclick=\"agp_setcss('.groups-csv','display','inline');agp_set_display('rs-hide_groups','inline',this.id);\">";
+ _e('show groups', 'scoper');
+ echo '</a> | ';
+ }
+
+ if ( $hide_roles ) {
+ echo "<a id='rs-hide_roles' href='javascript:void(0);' onclick=\"agp_setcss('.rs-role-tbl','display','none');agp_set_display('rs-show_roles','inline',this.id);\">";
+ _e('hide roles', 'scoper');
+ echo '</a>';
+
+ echo "<a id='rs-show_roles' style='display:none;' href='javascript:void(0);' onclick=\"agp_setcss('.rs-role-tbl','display','block');agp_set_display('rs-hide_roles','inline',this.id);\">";
+ _e('show roles', 'scoper');
+ echo '</a> | ';
+ }
+
+
+ // Hide Empty
+ $hide_tr_sfx = ( $default_hide_empty ) ? '-hide' : '';
+ $hide_li_sfx = ( $default_hide_empty ) ? '-hide' : '';
+
+ $js_call = "
+ agp_set_display('rs-show_empty','inline',this.id);
+ agp_display_marked_elements('li','no-rol-li{$hide_li_sfx}','none');
+ agp_setcss('.no-rol{$hide_tr_sfx}','display','none');
+ agp_set_display('max_unroled_notice','none');
+ ";
+
+ if ( $role_bases )
+ $js_call .= "
+ agp_setcss('.user-csv','display','inline');
+ agp_setcss('.groups-csv','display','inline');
+ agp_set_display('max_unroled_notice','none','');
+ ";
+
+ $unroled_limit = ( ! empty($otype->max_unroled_objects) ) ? $otype->max_unroled_objects : 999999;
+
+ $style = ( $default_hide_empty ) ? ' style="display:none;"' : '';
+ $title = __('hide unmodified items', 'scoper');
+ echo "<a id='rs-hide_empty' href='javascript:void(0);'{$style} onclick=\"$js_call\" title='$title'>";
+ if ( ROLE_RESTRICTION_RS == $mode )
+ _e('hide defaulted', 'scoper');
+ else
+ _e('hide unassigned', 'scoper');
+ echo '</a>';
+
+ $js_call = "
+ agp_set_display('rs-hide_empty','inline',this.id);
+ agp_display_marked_elements('li','no-rol-li{$hide_li_sfx}','block');
+ agp_setcss('.no-rol{$hide_tr_sfx}','display','$tr_display');
+ agp_set_display('max_unroled_notice','block');
+ ";
+ $style = ( $default_hide_empty ) ? '' : ' style="display:none;"';
+
+ $src_label = ( ! empty($src->labels->name) ) ? agp_strtolower($src->labels->name) : __('items', 'scoper');
+
+ if ( ROLE_RESTRICTION_RS == $mode )
+ $title = sprintf(__('include the newest %s with default restrictions', 'scoper'), $src_label);
+ else
+ $title = sprintf(__('include the newest %s with no role assignments', 'scoper'), $src_label);
+
+ echo "<a id='rs-show_empty' href='javascript:void(0);'{$style} onclick=\"$js_call\" title='$title'>";
+ if ( ROLE_RESTRICTION_RS == $mode )
+ _e('show defaulted', 'scoper');
+ else
+ _e('show unassigned', 'scoper');
+
+
+ // Collapse All
+ if ( empty($otype->ignore_object_hierarchy) ) {
+ echo '</a> | ';
+
+ $js_call = "
+ agp_set_display('rs-expand_all','inline',this.id);
+ agp_display_marked_elements('li','role-li','none');
+ agp_set_marked_elem_property('a','term-tgl','innerHTML','+');
+ agp_display_marked_elements('span','rs-termjump','none');
+ ";
+ echo "<a id='rs-collapse_all' href='javascript:void(0);' onclick=\"$js_call\">";
+ _e('collapse all', 'scoper');
+ echo '</a>';
+ }
+
+ $js_call = "
+ agp_set_display('rs-collapse_all','inline',this.id);
+ agp_display_marked_elements('li','role-li','block');
+ agp_set_marked_elem_property('a','term-tgl','innerHTML','-');
+ agp_display_marked_elements('span','rs-termjump','inline');
+ ";
+ echo "<a id='rs-expand_all' style='display:none;' href='javascript:void(0);' onclick=\"$js_call\">";
+ _e('expand all', 'scoper');
+ echo '</a>';
+
+ if ( ! empty($otype->admin_max_unroled_objects) ) {
+ $display_style = ( $default_hide_empty ) ? 'style="display:none;"' : '';
+ echo "<div id='max_unroled_notice' class='rs-warning' $display_style><br />";
+ if ( ROLE_RESTRICTION_RS == $mode )
+ printf(__('Note: %1$s with default restrictions will not be listed here unless they are among the %2$s newest.', 'scoper'), $src_label, $otype->admin_max_unroled_objects);
+ else
+ printf(__('Note: %1$s with no role assignments will not be listed here unless they are among the %2$s newest.', 'scoper'), $src_label, $otype->admin_max_unroled_objects);
+ echo '</div>';
+ }
+}
+
+function item_tree($scope, $mode, $src, $otype_or_tx, $all_items, $assigned_roles, $strict_items, $role_defs_by_otype, $role_codes, $args = array()) {
+
+ $defaults = array ( 'admin_items' => '', 'editable_roles' => '',
+ 'ul_class' => 'rs-termlist', 'ie_link_style' => '', 'object_names' => '',
+ 'table_captions' => '', 'err' => '', 'object_status' => '',
+ 'agent_caption_plural' => '', 'agent_list_prefix' => '', 'agent_names' => '',
+ 'default_hide_empty' => false, 'role_bases' => array(ROLE_BASIS_USER, ROLE_BASIS_GROUPS),
+ 'single_item' => false );
+ $args = array_merge($defaults, (array) $args);
+ extract($args);
+
+ global $scoper;
+
+ if ( ! is_object($src) )
+ $src = $scoper->data_sources->get($src);
+
+ $col_id = $src->cols->id;
+ $col_name = $src->cols->name;
+ $col_parent = ( isset($src->cols->parent) ) ? $src->cols->parent : '';
+
+ $item_label = $otype_or_tx->labels->singular_name;
+
+ if ( TERM_SCOPE_RS == $scope ) {
+ $src_or_tx_name = $otype_or_tx->name;
+ $edit_url_base = ( ! empty($otype_or_tx->edit_url) ) ? $otype_or_tx->edit_url : '';
+ } else {
+ $src_or_tx_name = $src->name;
+ $edit_url_base = ( ! empty($src->edit_url) ) ? $src->edit_url : '';
+ }
+
+ if ( $default_hide_empty ) {
+ $hide_tr_sfx = '-hide';
+ $hide_li_sfx = '-hide';
+ } else {
+ $hide_tr_sfx = '';
+ $hide_li_sfx = '';
+ }
+
+ $nextlink = '';
+ $prevlink = '';
+
+ if ( empty($admin_items) )
+ $admin_items = array();
+
+ if ( empty($agent_caption_plural) )
+ $agent_caption_plural = __('Users or Groups', 'scoper');
+
+ if ( empty($agent_list_prefix) ) {
+ $agent_list_prefix = array();
+ $agent_list_prefix[ROLE_BASIS_USER] = '';
+ $agent_list_prefix[ROLE_BASIS_GROUPS] = __('Groups') . ': ';
+ }
+
+ static $prevtext, $nexttext, $is_administrator, $role_header, $agents_header;
+ if ( empty($prevtext) ) {
+ // buffer prev/next caption for display with each term
+ //$prevtext = _ x('prev', '|abbreviated link to previous item', 'scoper');
+ //$nexttext = _ x('next', '|abbreviated link to next item', 'scoper');
+ $prevtext = __('prev', 'scoper');
+ $nexttext = __('next', 'scoper');
+
+ $is_administrator = is_administrator_rs($src, 'user');
+
+ $role_header = __awp('Role');
+
+ switch ( $mode ) {
+ case ROLE_ASSIGNMENT_RS:
+ //$agents_header = sprintf( _ x('Current %s', 'users or groups', 'scoper'), $agent_caption_plural);
+ $agents_header = sprintf( __('Current %s', 'scoper'), $agent_caption_plural);
+
+ break;
+ case ROLE_RESTRICTION_RS:
+ $agents_header = __('Current Restrictions', 'scoper');
+
+ break;
+ default:
+ return;
+ }
+ }
+
+ // disregard roles that don't apply to this scope
+ foreach ( $role_defs_by_otype as $object_type => $role_defs )
+ foreach ( $role_defs as $role_handle => $role )
+ if ( ! isset($role->valid_scopes[$scope]) )
+ unset( $role_defs_by_otype[$object_type][$role_handle] );
+
+ // for object scope, assign "private post reader" role, but label it as "post reader" to limit confusion
+ $role_display_name = array();
+ foreach ( $role_defs_by_otype as $role_defs )
+ foreach ( array_keys($role_defs) as $role_handle )
+ $role_display_name[$role_handle] = $scoper->role_defs->get_display_name( $role_handle, $scope . '_ui' );
+
+ // display a separate role assignment list for each individual term / object
+ $last_id = -1;
+ $last_name = '';
+ $last_parent_id = -1;
+ $parent_id = 0;
+ $parents = array();
+ $depth = 0;
+
+ $_top_link = "<a{$ie_link_style} href='#scoper_top'>" . __('top', 'scoper') . '</a>';
+ $tr_display = (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) ? 'block' : 'table-row';
+ $show_all_caption = __('show all', 'scoper');
+
+ echo "<ul class='$ul_class' style='padding-left:0.1em;'>";
+
+ if ( empty($all_items) )
+ $all_items = array();
+
+ if ( ! $single_item && is_user_administrator_rs() && ( 'nav_menu' != $src_or_tx_name ) ) { // TODO: action handler for new menu item storage
+ if ( ROLE_ASSIGNMENT_RS == $mode )
+ $root_caption = sprintf( __('DEFAULTS for new %s', 'scoper'), $otype_or_tx->labels->name );
+ else
+ $root_caption = sprintf(__('DEFAULTS for all %s', 'scoper'), $otype_or_tx->labels->name );
+
+ if ( TERM_SCOPE_RS == $scope ) {
+ $root_item = (object) array( $col_id => 0, $col_name => $root_caption, $col_parent => 0 );
+ array_unshift( $all_items, $root_item);
+ } else {
+ $obj = (object) array($col_id => 0);
+ $all_items = array( $root_caption => $obj ) + $all_items;
+
+ $object_names[0] = $root_caption;
+
+ $status_objects = ( 'post' == $src->name ) ? get_post_stati( array(), 'object' ) : array();
+ }
+ }
+
+ $title_roles = __('edit roles', 'scoper');
+ $title_item = sprintf(__('edit %s', 'scoper'), agp_strtolower($item_label) );
+
+ foreach($all_items as $key => $item) {
+ $id = $item->$col_id;
+
+ if ( ! empty($object_names[$id]) )
+ $name = esc_attr(str_replace(' ', '&nbsp;', $object_names[$id]) );
+ else
+ $name = str_replace(' ', '&nbsp;', $item->$col_name);
+
+ if ( $col_parent && isset($item->$col_parent) ) {
+ $parent_id = $item->$col_parent;
+
+ if ( $parent_id != $last_parent_id ) {
+ if ( ($parent_id == $last_id) && $last_id ) {
+ $parents[$last_name] = $last_id;
+ echo "<ul class='$ul_class'>";
+ $depth++;
+ } elseif ($depth) {
+ do {
+ //echo "term $name: depth $depth, current parents: " . print_r($parents);
+ array_pop($parents);
+ echo '</li></ul>';
+ $depth--;
+ } while ( $parents && ( end($parents) != $parent_id ) && $depth);