=== MembershipPortal ===
Contributors: membershipportal
Tags: membership, access-control, sso, events, gutenberg
Requires at least: 6.6
Tested up to: 7.1
Requires PHP: 8.1
Stable tag: 0.2.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Connect your MembershipPortal organization, sign members in, protect content, and share live events and publications.

== Description ==
Keep your WordPress website and connect it to your memberships. Membership tiers, prices, and benefits are imported from MembershipPortal. There are no duplicate membership products or billing records to maintain in WordPress.

* Guided connection with a one-time code from MembershipPortal.
* OAuth authorization-code sign-in with PKCE and explicit member consent.
* Access rules for pages, posts, custom post types, taxonomy terms, and sections.
* Current-member, signed-in-member, selected-tier, and selected-benefit audiences.
* Live membership checks, including expiry and revoked website connections.
* Public events filtered by kind, topic, series, place, and upcoming/past dates.
* Membership options, publications, benefits, member-access and member-status blocks.
* Private downloads stored outside the public media library, with a download block.
* Searchable choices, clear summaries, editor previews, and starter block patterns.
* Shortcodes for classic editors and page builders.

== Installation ==
1. Upload membership-portal.zip using Plugins → Add New → Upload Plugin, then activate it.
2. Open MembershipPortal in WordPress and copy the website address shown there.
3. In your organization portal, open Connected services → WordPress and create a website connection.
4. Paste the one-time connection code into WordPress. Your tiers and benefits are imported automatically.
5. Add access rules or edit an individual page’s MembershipPortal access panel.
6. In the block editor, search for MembershipPortal to insert live content and member sections.

Both the WordPress website and the portal service must use HTTPS for member sign-in. Use the exact website address shown in the plugin. Subdirectory installations are supported when WordPress and its public website use the same base path; split home/site URLs require an exact callback configuration.

== Updates and member experience ==
After installing 0.2.0, future releases appear in the standard Plugins and Updates screens. You can opt into WordPress automatic updates. The plugin checks https://membershipportal.org/wordpress/update.json and verifies each downloaded archive against its published SHA-256 checksum. No GitHub account or token is required.

Use MembershipPortal → Design & messages for shared appearance and paywall text. Blocks can override colors, spacing, columns, corners, buttons and visible fields.

Save a page, then open its Preview access panel to simulate a visitor, current member, expired member, or selected tiers and benefits. These editor-only, non-cacheable previews do not change anyone’s membership. The banner explains each page and section rule.

Classic menu items and Navigation links/submenus include Membership visibility settings. Enable automatic account links to show Member sign-in to visitors and My account / Sign out to connected members. Menu visibility does not protect the destination page.

Event blocks let visitors search, filter and move between list and calendar views within the editor’s selected boundaries. Calendar dates use each event’s timezone. Add to calendar downloads a public iCalendar file. Calendars are paginated when a month contains more than the configured number of events.

Member sign-in can renew automatically while the WordPress session remains valid, for up to 14 days from portal authorization. Membership access is still checked live. Logging out, revoking the connection, or rotating its secret ends access. A reused refresh credential revokes its session.

== Frequently Asked Questions ==

= Can I create membership tiers in WordPress? =
No. Manage them in MembershipPortal. The plugin imports your catalog and refreshes it hourly or when you select Refresh catalog. Access checks use current portal data on each protected request.

= Why do benefits appear in access rules but not in the Membership benefits block? =
Access rules use the full imported catalog. The public block only displays descriptions approved for this website. In MembershipPortal, open Connected services, find your WordPress website, expand Benefits this website may describe publicly, and select the benefits to share. Back in the block settings, choose Refresh public benefits. With no block selections, all approved benefits appear; selecting specific benefits narrows that list.

= Does everyone need to sign in to see events? =
No. Public blocks work for anonymous visitors and only show content approved for public viewing. Select event kinds and topics to make a cartridge-show calendar or a focused museum-events listing.

= What happens if a membership expires? =
The next protected request checks current eligibility. An expired tier no longer grants access. Explicit signed-in-only rules still allow a verified member account, including a lapsed member, as the rule editor explains.

= Do members receive a second password? =
New linked members use Continue with MembershipPortal. Existing WordPress accounts must sign in locally once before linking; the plugin never merges accounts by email automatically. Existing editor and administrator permissions are preserved.

= Are PDFs in my existing media library private? =
A page rule cannot hide an already-public upload URL. Upload a new file using Protected downloads in the page editor to store its bytes privately, or use the portal’s protected library. The private download feature supports files up to 8 MB, subject to the host’s upload limit.

= Can I use a page cache or CDN? =
Exclude member-status pages, protected pages, and signed-in traffic from full-page caches. The plugin sends private/no-store responses and DONOTCACHEPAGE when WordPress handles a request, but a cache serving a page before WordPress starts must be configured at the host. Public feed data is cached for one minute.

= What does disconnecting do? =
Local disconnect clears stored website credentials and imported catalog data. Existing access rules and private files remain, and protected content stays locked. Revoke the website in MembershipPortal to invalidate its server credentials and member sessions everywhere.

= What about other plugins? =
Standard WordPress page, REST, feed, search, excerpt, sitemap, comment and embed surfaces are covered. Plugins that query the database directly or implement their own GraphQL/search/export endpoints require a compatibility review. Page access rules do not change local WordPress editor capabilities.

== Shortcodes ==
[membership_portal_events types="show" topics="cartridge-shows" limit="6"]
[membership_portal_membership_options]
[membership_portal_publications limit="3"]
[membership_portal_member_access]
[membership_portal_protected_content mode="active"]Member text here.[/membership_portal_protected_content]
[membership_portal_download id="the-id-shown-after-upload"]

Use imported UUIDs in ids="..." for selected plans or benefits. Gutenberg provides searchable names so editors do not need to copy IDs.

== Privacy ==
The plugin sends OAuth authorization requests and current access checks to the connected MembershipPortal service. It stores the site credentials encrypted with WordPress salts, the imported membership catalog, local access rules, stable linked member identities and encrypted access and rotating refresh credentials (up to 14 days, bounded by the WordPress session). New member accounts contain the member’s verified name and email. It never receives portal passwords, card details, or Supabase member sessions.

Private resources are stored as database blobs. WordPress backups therefore include these files and must be protected accordingly. Deleting the parent post permanently removes its private files. Deactivation preserves configuration and content so access rules are not silently lost; remove data deliberately before uninstalling if desired.

== Changelog ==
= 0.2.0 =
* Native updates, safe access previews, contextual paywalls and membership-aware navigation.
* Interactive event calendars and iCalendar downloads.
* Rich member cards, rotating renewable sessions and shared block design controls.

= 0.1.1 =
Use approved public benefits in the benefits block picker, explain missing approvals and saved selections, and refresh public benefits without reopening the editor. Add editable sign-in button text to My membership.
= 0.1.0 =
Initial MembershipPortal integration for WordPress.
