=== Secure Role-Restricted Draft Previews ===
Contributors: pixypuala
Tags: preview, drafts, roles, access control, security
Requires at least: 6.4
Tested up to: 6.8
Requires PHP: 8.1
Stable tag: 1.0.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Generate secure, expiring preview URLs for drafts with role/user restrictions. Compatible with FSE, Block Themes, and Classic Themes.

== Description ==

**Why this plugin?**

WordPress core preview links work well for editors, and *Public Post Preview* shares via anonymous nonces.
This plugin adds a missing middle ground: **draft previews that are secured by authentication and access control
lists (ACLs)** — role-based, user-specific, or per-email tokens — plus analytics and a one-click revoke-all.

**Universal Compatibility**

Works seamlessly with:
* Full Site Editing (FSE) themes
* Block themes (modern WordPress)
* Classic PHP-based themes
* All page builders including Elementor, WPBakery, Divi, etc.
* WooCommerce product drafts
* Any CSS framework including Tailwind CSS v4+

**Key features**

* Create expiring preview links (default 72h; configurable).
* Restrict by **roles**, **specific users**, or **per-email tokens** (no login for recipients).
* Require HTTPS for previews (on by default).
* Per-link analytics: allowed/denied events, hashed IP, user agent (privacy-friendly).
* Meta box in the editor (Post/Page by default; filterable) to generate, copy, and revoke.
* "Revoke All" for a post.
* Everything prefixed (`srpl_`), sanitized, and aligned with WordPress coding standards.

**How it works**

Each generated link has a unique token, TTL, and ACL:

* **Role-based Access:** Requires login. Only users with allowed roles can view the preview.
* **User-based Access:** Requires login. Only specific user IDs can access the preview.
* **Email Token Access:** No login required. Recipients receive unique URLs with email verification tokens.

When a link is visited, SRPL validates the token, expiry, and ACL, then renders the draft with your theme's header/footer. Events are logged (when enabled) to a small custom table (`wp_srpl_events`) with **hashed IP** for privacy.

**Privacy**

* IPs are hashed using `hash_hmac(sha256, ip, wp_salt('auth'))`.
* You can disable analytics entirely under **Settings → Secure Previews**.

**Developer Friendly**

* Fully documented filters and actions
* Clean, object-oriented codebase
* PSR-4 autoloading
* Extensive inline documentation

== Installation ==

1. Upload the plugin folder to `/wp-content/plugins/` or install from WP.org.
2. Activate the plugin through the 'Plugins' menu in WordPress.
3. Go to any Post/Page editor → sidebar meta box "Secure Preview Links".
4. Generate a link (choose Mode + TTL). Copy the URL (for email mode, copy the per‑email URLs shown).
5. Optional: configure defaults in **Settings → Secure Previews**.

== Frequently Asked Questions ==

= Is this the same as Public Post Preview? =

No. That plugin makes anonymous, expiring links. SRPL requires login for role/user modes and supports per‑email tokens. It also offers per‑link analytics and revoke‑all functionality.

= Can I restrict by custom roles? =

Yes. All editable roles are available. You can also filter supported post types via `srpl_supported_post_types`.

= Does it support Custom Post Types? =

Yes. Add your CPT slug to the `srpl_supported_post_types` filter:
```
add_filter('srpl_supported_post_types', function($post_types) {
    $post_types[] = 'product'; // Add custom post type
    return $post_types;
});
```

= Is this plugin compatible with Full Site Editing (FSE), Block Themes, and Classic Themes? =

Yes! Our plugin works seamlessly with:
* Full Site Editing (FSE) themes
* Block themes (modern WordPress)
* Classic PHP-based themes
* All page builders including Elementor, WPBakery, Divi, etc.
* WooCommerce product drafts
* Any CSS framework including Tailwind CSS v4+

The preview functionality renders drafts exactly as they would appear on your live site, regardless of your theme or page builder.

= Will this leak draft content to search engines? =

No. Links are opaque tokens; access is gated and previews are not discoverable by search engines.

= How are analytics stored? =

A lightweight table `wp_srpl_events` stores link id, post id, hashed IP, UA, user id (if logged), outcome, and timestamp. You can disable this in settings.

= Can I change the default expiration time? =

Yes, use the `srpl_default_ttl_hours` filter:
```
add_filter('srpl_default_ttl_hours', function($hours) {
    return 168; // 1 week
});
```

= How secure are the preview links? =

Very secure. Links use cryptographically strong tokens that are non-guessable. Email tokens are deterministic but secure, using your site's nonce salt.

== Screenshots ==

1. Editor meta box: generate, copy, revoke.

== Changelog ==

= 1.0.1 =
* Updated plugin assets for WordPress.org directory.

= 1.0.0 =
* Initial release.

== Upgrade Notice ==

= 1.0.1 =
Updated plugin assets for WordPress.org directory. All persistent data is stored in the WordPress database or in a subfolder of the uploads directory. No plugin-folder writes. No code editing required.

= 1.0.0 =
Initial release. All persistent data is stored in the WordPress database or in a subfolder of the uploads directory. No plugin-folder writes. No code editing required.

== Developer Documentation ==

**Filters**

* `srpl_supported_post_types` - Modify post types that support preview links
* `srpl_default_ttl_hours` - Change default expiration time (in hours)
* `srpl_force_ssl` - Control whether previews are forced to use HTTPS
* `srpl_analytics_enabled` - Enable or disable analytics collection

**Functions**

* `LinkManager::create($post_id, $args)` - Create a new preview link
* `LinkManager::revoke($link_id)` - Revoke a specific link
* `LinkManager::revoke_all_for_post($post_id)` - Revoke all links for a post
* `LinkManager::find_by_token($token)` - Find a link by its token

**Database Structure**

* Post Meta for Links: _srpl_token, _srpl_mode, _srpl_roles, _srpl_users, _srpl_emails, _srpl_expires, _srpl_revoked, _srpl_hits, _srpl_last_access
* Analytics Table: wp_srpl_events (link_id, post_id, user_id, outcome, ip_hash, ua, created_at)

== License ==

This plugin is free software, licensed under the GPL v2 or later.