update
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array('wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-edit-post', 'wp-editor', 'wp-element', 'wp-i18n', 'wp-plugins', 'wp-url'), 'version' => '929f19f0796b8f796f89');
|
||||
@@ -0,0 +1 @@
|
||||
.components-panel__row.sppp{align-items:flex-start;flex-direction:column}.components-panel__row.sppp .sppp__link-copy{align-items:flex-end;display:flex;margin-bottom:16px 0}.components-panel__row.sppp .sppp__link-copy .components-base-control__field{margin-bottom:0}.components-panel__row.sppp .sppp__link-copy .sppp__link-field{flex:1}.components-panel__row.sppp .sppp__link-copy input[readonly]{background:#ddd;overflow:hidden;padding:10px;text-overflow:ellipsis}.components-panel__row.sppp .sppp__link-copy .sppp__copy-button{flex-shrink:0;height:38px;margin-left:8px}
|
||||
@@ -0,0 +1 @@
|
||||
!function(){"use strict";var e=window.wp.plugins,t=window.wp.element,s=window.wp.editPost,o=window.wp.components,n=window.wp.i18n,i=window.wp.data,p=window.wp.editor;function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var s=arguments[t];for(var o in s)Object.prototype.hasOwnProperty.call(s,o)&&(e[o]=s[o])}return e},r.apply(this,arguments)}var a=window.wp.url,l=window.wp.compose,c={META_ENABLED:"_sppp_enabled",META_KEY:"_sppp_key",QUERY_PARAM:"_sppp_key"};const{META_KEY:d,QUERY_PARAM:w}=c,m=e=>{let{text:s,onCopy:n,children:i,...p}=e;const a=(0,l.useCopyToClipboard)(s,n);return(0,t.createElement)(o.Button,r({variant:"secondary",ref:a},p),i)};class u extends t.Component{constructor(){super(...arguments),this.state={showCopyConfirmation:!1},this.onCopy=this.onCopy.bind(this),this.onSelectInput=this.onSelectInput.bind(this)}componentWillUnmount(){clearTimeout(this.dismissCopyConfirmation)}onCopy(){this.setState({showCopyConfirmation:!0}),clearTimeout(this.dismissCopyConfirmation),this.dismissCopyConfirmation=setTimeout((()=>{this.setState({showCopyConfirmation:!1})}),4e3)}onSelectInput(e){e.target.select()}render(){const e=(0,a.addQueryArgs)(this.props.postLink,{[w]:this.props.secretKey});return(0,t.createElement)("div",null,(0,t.createElement)("label",{htmlFor:"sppp-link-field",className:"screen-reader-text"},(0,n.__)("Share this URL","sharable-password-protected-posts")),(0,t.createElement)(o.Flex,{className:"sppp__link-copy"},(0,t.createElement)(o.TextControl,{id:"sppp-link-field",className:"sppp__link-field",readOnly:!0,label:(0,n.__)("Secret URL:","sharable-password-protected-posts"),value:(0,a.safeDecodeURIComponent)(e),onFocus:this.onSelectInput}),(0,t.createElement)(m,{text:e,onCopy:this.onCopy,className:"sppp__copy-button"},this.state.showCopyConfirmation?(0,n.__)("Copied!","sharable-password-protected-posts"):(0,n.__)("Copy","sharable-password-protected-posts"))))}}var h=(0,i.withSelect)((e=>{const{getEditedPostAttribute:t,getPermalink:s}=e(p.store);return{postLink:s(),secretKey:t("meta")[d]}}))(u),y=window.wp.coreData,_=e=>{let{children:t}=e;const{isPostTypeVisible:s,postType:o,isPostPrivate:n}=(0,i.useSelect)((e=>{let t=!1;const s=e(p.store).getCurrentPostType(),o=e(y.store).getPostType(s),n=e(p.store).getEditedPostAttribute("link"),i=e(p.store).getEditedPostVisibility();return null!=o&&o.viewable&&(t=!0),n&&(t=!0),e(p.store).getPermalinkParts()&&(t=!0),{isPostTypeVisible:t,postType:s,isPostPrivate:"private"===i||"password"===i}}),[]),r=window.sppp&&window.sppp.settings.postTypes.includes(o);return window.sppp&&window.sppp.settings.hasPermissions&&s&&r&&n?t:null};const{META_ENABLED:E,META_KEY:C}=c;(0,e.registerPlugin)("sharable-password-protected-posts",{render:()=>{const{sharingEnabled:e,existingKey:r}=(0,i.useSelect)((e=>{const{getEditedPostAttribute:t}=e(p.store),s=t("meta");return{sharingEnabled:s[E],existingKey:s[C]}})),{editPost:a}=(0,i.useDispatch)(p.store);return(0,t.createElement)(s.PluginPostStatusInfo,{className:"sppp"},(0,t.createElement)(_,null,(0,t.createElement)("div",{className:"sppp__checkbox"},(0,t.createElement)(o.CheckboxControl,{label:(0,n.__)("Share post via secret URL","sharable-password-protected-posts"),checked:e,onChange:e=>{a(e?{meta:{[E]:!0,[C]:r||window.sppp.newKey||""}}:{meta:{[E]:!1,[C]:""}})}})),e&&(0,t.createElement)("div",{className:"sppp__link"},(0,t.createElement)(h,null))))}})}();
|
||||
Binary file not shown.
@@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2022 Fabian Todt
|
||||
# This file is distributed under the GPL-2.0-or-later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Sharable Password Protected Posts 0.1.0\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/sharable-password-"
|
||||
"protected-posts\n"
|
||||
"POT-Creation-Date: 2022-10-29T08:32:09+00:00\n"
|
||||
"PO-Revision-Date: 2022-10-29 10:35+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: de_DE\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 3.2\n"
|
||||
"X-Domain: sharable-password-protected-posts\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Sharable Password Protected Posts"
|
||||
msgstr "Passwortgeschützte Posts teilen"
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Share password protected posts via secret URLs"
|
||||
msgstr "Teile passwortgeschützte Beiträge mit geheimen URLs"
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Fabian Todt"
|
||||
msgstr ""
|
||||
|
||||
#: src/PostStatusSettings/CopyUrl.js:63
|
||||
msgid "Share this URL"
|
||||
msgstr "Teile diese URL"
|
||||
|
||||
#: src/PostStatusSettings/CopyUrl.js:70
|
||||
msgid "Secret URL:"
|
||||
msgstr "Geheime URL:"
|
||||
|
||||
#: src/PostStatusSettings/CopyUrl.js:76
|
||||
msgid "Copied!"
|
||||
msgstr "Kopiert!"
|
||||
|
||||
#: src/PostStatusSettings/CopyUrl.js:77
|
||||
msgid "Copy"
|
||||
msgstr "Kopieren"
|
||||
|
||||
#: src/PostStatusSettings/index.js:41
|
||||
msgid "Share post via secret URL"
|
||||
msgstr "Beitrag mit geheimer URL teilen"
|
||||
@@ -0,0 +1,51 @@
|
||||
# Copyright (C) 2022 Fabian Todt
|
||||
# This file is distributed under the GPL-2.0-or-later.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Sharable Password Protected Posts 1.0.2\n"
|
||||
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/sharable-password-protected-posts\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"POT-Creation-Date: 2022-11-02T10:02:27+00:00\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"X-Generator: WP-CLI 2.7.1\n"
|
||||
"X-Domain: sharable-password-protected-posts\n"
|
||||
|
||||
#. Plugin Name of the plugin
|
||||
msgid "Sharable Password Protected Posts"
|
||||
msgstr ""
|
||||
|
||||
#. Description of the plugin
|
||||
msgid "Share password protected posts via secret URLs"
|
||||
msgstr ""
|
||||
|
||||
#. Author of the plugin
|
||||
msgid "Fabian Todt"
|
||||
msgstr ""
|
||||
|
||||
#. Author URI of the plugin
|
||||
msgid "https://fabiantodt.at/en/"
|
||||
msgstr ""
|
||||
|
||||
#: src/PostStatusSettings/CopyUrl.js:63
|
||||
msgid "Share this URL"
|
||||
msgstr ""
|
||||
|
||||
#: src/PostStatusSettings/CopyUrl.js:70
|
||||
msgid "Secret URL:"
|
||||
msgstr ""
|
||||
|
||||
#: src/PostStatusSettings/CopyUrl.js:76
|
||||
msgid "Copied!"
|
||||
msgstr ""
|
||||
|
||||
#: src/PostStatusSettings/CopyUrl.js:77
|
||||
msgid "Copy"
|
||||
msgstr ""
|
||||
|
||||
#: src/PostStatusSettings/index.js:41
|
||||
msgid "Share post via secret URL"
|
||||
msgstr ""
|
||||
@@ -0,0 +1,89 @@
|
||||
=== Sharable Password Protected Posts ===
|
||||
Contributors: gaambo
|
||||
Tags: password protected, secret links, share private
|
||||
Requires at least: 6.0
|
||||
Tested up to: 6.5
|
||||
Stable tag: 1.0.2
|
||||
License: GPL-2.0-or-later
|
||||
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
|
||||
Share password protected posts via secret URLs
|
||||
|
||||
== Description ==
|
||||
|
||||
Share a link to anonymous users to view private and password protected posts (or any other public post type).
|
||||
|
||||
This plugin generates secret URLs (similar to Google Docs and other cloud services) for posts so you can share them with not-logged in users without having to share an extra password with them.
|
||||
|
||||
== Installation ==
|
||||
|
||||
Note: There will be NO settings page.
|
||||
|
||||
For an automatic installation through WordPress:
|
||||
|
||||
1. Go to the 'Add New' plugins screen in your WordPress admin area
|
||||
1. Search for 'Public Post Preview'
|
||||
1. Click 'Install Now' and activate the plugin
|
||||
|
||||
|
||||
For a manual installation via FTP:
|
||||
|
||||
1. Upload the `public-post-preview` directory to the `/wp-content/plugins/` directory
|
||||
1. Activate the plugin through the 'Plugins' screen in your WordPress admin area
|
||||
|
||||
|
||||
To upload the plugin through WordPress, instead of FTP:
|
||||
|
||||
1. Upload the downloaded zip file on the 'Add New' plugins screen (see the 'Upload' tab) in your WordPress admin area and activate.
|
||||
|
||||
== Installation ==
|
||||
|
||||
This section describes how to install the plugin and get it working.
|
||||
|
||||
e.g.
|
||||
|
||||
1. Upload the plugin files to the `/wp-content/plugins/sharable-password-protected-posts` directory, or install the plugin through the WordPress plugins screen directly.
|
||||
1. Activate the plugin through the 'Plugins' screen in WordPress
|
||||
|
||||
== Screenshots ==
|
||||
|
||||
1. Edit Posts Page
|
||||
|
||||
== Usage ==
|
||||
|
||||
- To enable a sharable url check the box below the edit post box on a private or password protected post
|
||||
- The link will be displayed if the checkbox is checked, just copy and share the link.
|
||||
- To disable just uncheck the box.
|
||||
|
||||
By default it's enabled for all public post types, but that can be changed via the `sppp/postTypes` filter.
|
||||
|
||||
== Frequently Asked Questions ==
|
||||
|
||||
= I can’t find the option for to share the URL. Where is it? =
|
||||
|
||||
The checkbox is only available for private or password protected posts. Please make sure the status is set to "Private" or "Password protected" and you have entered a password.
|
||||
|
||||
= Is it available for classic editor? =
|
||||
|
||||
No, the plugin only works in the new block editor.
|
||||
|
||||
= Which permissions do I need? =
|
||||
|
||||
The editor has to have the `publish_posts` capability.
|
||||
|
||||
= Can I use it for custom post types? =
|
||||
|
||||
Yes, by default all public post types are enabled. You can filter them with the `sppp/postTypes` filter.
|
||||
|
||||
== Changelog ==
|
||||
|
||||
= 1.0.2 (2022-11-02): =
|
||||
* Update plugin file versions and author uri
|
||||
|
||||
= 1.0.1 (2022-11-02): =
|
||||
* Fix source code repo and deployment to WordPress.org plugin repo
|
||||
|
||||
= 1.0.0 (2022-11-02): =
|
||||
* The first public release of the plugin 🥳
|
||||
|
||||
For more see [CHANGELOG.md](https://github.com/gaambo/sharable-password-protected-posts/blob/main/CHANGELOG.md).
|
||||
@@ -0,0 +1,309 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Plugin Name: Sharable Password Protected Posts
|
||||
* Description: Share password protected posts via secret URLs
|
||||
* Requires at least: 6.0
|
||||
* Requires PHP: 7.4
|
||||
* Version: 1.0.2
|
||||
* Author: Fabian Todt
|
||||
* Author URI: https://fabiantodt.at/en/
|
||||
* License: GPL-2.0-or-later
|
||||
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
* Text Domain: sharable-password-protected-posts
|
||||
* Domain Path: /languages
|
||||
*
|
||||
* @package SPPP
|
||||
*/
|
||||
|
||||
namespace SPPP;
|
||||
|
||||
/**
|
||||
* Adds JS & CSS to editor
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function addEditorAssets()
|
||||
{
|
||||
$assetFile = plugin_dir_path(__FILE__) . 'build/index.asset.php';
|
||||
if (!file_exists($assetFile)) {
|
||||
throw new \Exception('You have to build the scripts before loading them');
|
||||
}
|
||||
$assetsConfig = require($assetFile);
|
||||
|
||||
$jsData = [
|
||||
'settings' => [
|
||||
'postTypes' => getEnabledPostTypes(),
|
||||
'hasPermissions' => current_user_can('publish_posts'),
|
||||
],
|
||||
'newKey' => generateKey(),
|
||||
];
|
||||
|
||||
wp_enqueue_script(
|
||||
'sppp',
|
||||
plugin_dir_url(__FILE__) . 'build/index.js',
|
||||
$assetsConfig['dependencies'],
|
||||
$assetsConfig['version']
|
||||
);
|
||||
|
||||
wp_enqueue_style(
|
||||
'sppp',
|
||||
plugin_dir_url(__FILE__) . 'build/index.css',
|
||||
[],
|
||||
$assetsConfig['version']
|
||||
);
|
||||
|
||||
wp_add_inline_script('sppp', 'window.sppp = ' . json_encode($jsData) . ';', 'before');
|
||||
}
|
||||
add_action('enqueue_block_editor_assets', __NAMESPACE__ . '\addEditorAssets');
|
||||
|
||||
function loadLanguages()
|
||||
{
|
||||
load_plugin_textdomain(
|
||||
'sharable-password-protected-posts',
|
||||
false,
|
||||
dirname(plugin_dir_path(__FILE__)) . 'languages'
|
||||
);
|
||||
}
|
||||
add_action('init', __NAMESPACE__ . '\loadLanguages');
|
||||
|
||||
/**
|
||||
* Registers the two meta fields
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function registerMeta()
|
||||
{
|
||||
$enabledMetaField = [
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'type' => 'boolean',
|
||||
'default' => false,
|
||||
'auth_callback' => function ($allowed, $meta_key, $objectId, $userId) {
|
||||
if ($userId) {
|
||||
return user_can($userId, 'publish_posts', $objectId);
|
||||
}
|
||||
return current_user_can('publish_posts', $objectId);
|
||||
},
|
||||
'sanitize_callback' => function ($value) {
|
||||
if ($value === true || $value === 1 || $value === '1' || $value === 'true') {
|
||||
$value = true;
|
||||
} else {
|
||||
$value = false;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
];
|
||||
|
||||
$keyMetaField = [
|
||||
'show_in_rest' => true,
|
||||
'single' => true,
|
||||
'type' => 'string',
|
||||
'default' => '',
|
||||
'auth_callback' => function ($allowed, $meta_key, $objectId, $userId) {
|
||||
if ($userId) {
|
||||
return user_can($userId, 'publish_posts', $objectId);
|
||||
}
|
||||
return current_user_can('publish_posts', $objectId);
|
||||
},
|
||||
'sanitize_callback' => function ($value) {
|
||||
$value = sanitize_text_field(trim($value));
|
||||
if (empty($value)) {
|
||||
return generateKey();
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
];
|
||||
|
||||
$postTypes = getEnabledPostTypes();
|
||||
|
||||
foreach ($postTypes as $postType) {
|
||||
register_post_meta($postType, '_sppp_enabled', $enabledMetaField);
|
||||
register_post_meta($postType, '_sppp_key', $keyMetaField);
|
||||
}
|
||||
}
|
||||
add_action('init', __NAMESPACE__ . '\registerMeta');
|
||||
|
||||
/**
|
||||
* Filters the main queries posts_results - for PRIVATE posts
|
||||
* Sets the post elements status to 'publish' if it can be viewed with the key
|
||||
* this will let the rest of WP_Query thandle the post as normal
|
||||
*
|
||||
* This only filters the main query's WP_Post instance, not all other objects
|
||||
* that may be get via get_post; but using get_queried_object will work
|
||||
*
|
||||
* @param \WP_Post[] $posts
|
||||
* @param \WP_Query $query
|
||||
* @return void
|
||||
*/
|
||||
function filterPostsQuery($posts, $query)
|
||||
{
|
||||
// only handle the main query
|
||||
if (!$query->is_main_query()) {
|
||||
return $posts;
|
||||
}
|
||||
|
||||
// only handle single views, don't handle not-found posts
|
||||
if (count($posts) !== 1) {
|
||||
return $posts;
|
||||
}
|
||||
|
||||
$mainPost = $posts[0];
|
||||
$enabledPostTypes = getEnabledPostTypes();
|
||||
|
||||
// if the main (single) post has a not-enabled post type, bail early
|
||||
if (!in_array($mainPost->post_type, $enabledPostTypes)) {
|
||||
return $posts;
|
||||
}
|
||||
|
||||
// if a post type was specifically queried, check if only allowed/enabled post types where queried
|
||||
$postTypes = $query->get('post_type');
|
||||
if (!empty($postTypes) && (is_array($postTypes) || is_string($postTypes))) {
|
||||
// if a post type is queried (maybe one of multiple), that is not enabled bail early
|
||||
if (
|
||||
!empty($postTypes) &&
|
||||
!empty(array_diff((array)$postTypes, $enabledPostTypes))
|
||||
) {
|
||||
return $posts;
|
||||
}
|
||||
}
|
||||
|
||||
// should only be 1 on singulars normally
|
||||
foreach ($posts as &$post) {
|
||||
if (canPostBeViewedWithKey($post)) {
|
||||
$post->post_status = 'publish';
|
||||
}
|
||||
}
|
||||
return $posts;
|
||||
}
|
||||
add_filter('posts_results', __NAMESPACE__ . '\filterPostsQuery', 10, 2);
|
||||
|
||||
/**
|
||||
* Filters whether a post password form is required - for PASSWORD protected posts
|
||||
*
|
||||
* @param bool $required
|
||||
* @param \WP_Post $post
|
||||
* @return bool
|
||||
*/
|
||||
function filterPostPasswordRequired($required, $post)
|
||||
{
|
||||
$enabledPostTypes = getEnabledPostTypes();
|
||||
|
||||
// if the post has a not-enabled post type, bail early
|
||||
if (!in_array($post->post_type, $enabledPostTypes)) {
|
||||
return $required;
|
||||
}
|
||||
|
||||
if (canPostBeViewedWithKey($post)) {
|
||||
return false;
|
||||
}
|
||||
return $required;
|
||||
}
|
||||
add_filter('post_password_required', __NAMESPACE__ . '\filterPostPasswordRequired', 10, 2);
|
||||
|
||||
/**
|
||||
* Removes the "Protected" from password protected/private posts
|
||||
* if they can be viewd with the current url key
|
||||
*
|
||||
* @param string $prefix
|
||||
* @param WP_Post|int $post
|
||||
* @return string
|
||||
*/
|
||||
function filterPostTitlePrefix($prefix, $post)
|
||||
{
|
||||
if (canPostBeViewedWithKey($post)) {
|
||||
return '%s';
|
||||
}
|
||||
return $prefix;
|
||||
}
|
||||
add_filter('protected_title_format', __NAMESPACE__ . '\filterPostTitlePrefix', 10, 2);
|
||||
add_filter('private_title_format', __NAMESPACE__ . '\filterPostTitlePrefix', 10, 2);
|
||||
|
||||
/**
|
||||
* Whether a given post can be viewed with a given key
|
||||
*
|
||||
* @param \WP_Post $post The post to check for
|
||||
* @param string $key A key to check against, defaults to the $_GET parameters
|
||||
* @return bool False if the post is not private/protected or if SPPP is not enabled;
|
||||
* True if key can be used to view the private post
|
||||
*/
|
||||
function canPostBeViewedWithKey($post, $key = null)
|
||||
{
|
||||
if (!$key) {
|
||||
if (empty($_GET['_sppp_key'])) {
|
||||
return false;
|
||||
}
|
||||
$key = sanitize_text_field($_GET['_sppp_key']);
|
||||
}
|
||||
|
||||
if (empty($key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (empty($post->post_password) && $post->post_status !== 'private') {
|
||||
return false;
|
||||
}
|
||||
|
||||
$isKeyValid = isKeyValid($key, $post);
|
||||
|
||||
if ($isKeyValid) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the given key by the user against the stored key
|
||||
*
|
||||
* @param string $userKey
|
||||
* @param WP_Post|int $post
|
||||
* @return bool False if key is not valid or SPPP is not enabled for this post
|
||||
*/
|
||||
function isKeyValid($userKey, $post)
|
||||
{
|
||||
if (empty($userKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$postId = is_a($post, 'WP_Post') ? $post->ID : $post;
|
||||
|
||||
$isEnabled = get_post_meta($postId, '_sppp_enabled', true);
|
||||
if (!$isEnabled) {
|
||||
return false;
|
||||
}
|
||||
$savedKey = get_post_meta($postId, '_sppp_key', true);
|
||||
|
||||
if (empty($savedKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $savedKey === $userKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enabled post types for SPPP
|
||||
*
|
||||
* @return string[] name of post types
|
||||
*/
|
||||
function getEnabledPostTypes()
|
||||
{
|
||||
/**
|
||||
* Allows filtering the post types for which SPPP is enabled
|
||||
* By default it's enabled for all public post types
|
||||
*
|
||||
* @param string[] $postTypes array of post type names (slugs)
|
||||
*/
|
||||
return apply_filters('sppp/postTypes', array_keys(get_post_types([
|
||||
'public' => true,
|
||||
], 'names')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new secret key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function generateKey()
|
||||
{
|
||||
return wp_generate_password(15, false);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { useSelect } from "@wordpress/data";
|
||||
import { store as coreStore } from "@wordpress/core-data";
|
||||
import { store as editorStore } from "@wordpress/editor";
|
||||
|
||||
/**
|
||||
* Taken from WordPress PostURLCheck (private)
|
||||
* @wordpress/editor
|
||||
* and adapted for post type config from sppp
|
||||
*
|
||||
*/
|
||||
const Check = ({ children }) => {
|
||||
const { isPostTypeVisible, postType, isPostPrivate } = useSelect((select) => {
|
||||
let isPostTypeVisible = false;
|
||||
const postTypeSlug = select(editorStore).getCurrentPostType();
|
||||
const postType = select(coreStore).getPostType(postTypeSlug);
|
||||
const link = select(editorStore).getEditedPostAttribute("link");
|
||||
const editedPostVisibility = select(editorStore).getEditedPostVisibility();
|
||||
|
||||
if (postType?.viewable) {
|
||||
isPostTypeVisible = true;
|
||||
}
|
||||
|
||||
if (link) {
|
||||
isPostTypeVisible = true;
|
||||
}
|
||||
|
||||
const permalinkParts = select(editorStore).getPermalinkParts();
|
||||
if (permalinkParts) {
|
||||
isPostTypeVisible = true;
|
||||
}
|
||||
|
||||
return {
|
||||
isPostTypeVisible,
|
||||
postType: postTypeSlug,
|
||||
isPostPrivate: editedPostVisibility === "private" || editedPostVisibility === "password",
|
||||
};
|
||||
}, []);
|
||||
|
||||
const isEnabledForPostType = window.sppp && window.sppp.settings.postTypes.includes(postType);
|
||||
const hasPermissions = window.sppp && window.sppp.settings.hasPermissions;
|
||||
|
||||
if (!hasPermissions || !isPostTypeVisible || !isEnabledForPostType || !isPostPrivate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
|
||||
export default Check;
|
||||
@@ -0,0 +1,92 @@
|
||||
import { Component } from "@wordpress/element";
|
||||
import { safeDecodeURIComponent, addQueryArgs } from "@wordpress/url";
|
||||
import { TextControl, Button, Flex } from "@wordpress/components";
|
||||
import { withSelect } from "@wordpress/data";
|
||||
import { useCopyToClipboard } from "@wordpress/compose";
|
||||
import { store as editorStore } from "@wordpress/editor";
|
||||
import { __ } from "@wordpress/i18n";
|
||||
|
||||
import CONSTANTS from "./constants";
|
||||
const { META_KEY, QUERY_PARAM } = CONSTANTS;
|
||||
|
||||
/**
|
||||
* Taken from PostPublishPanelPostpublish (@wordpress/editor)
|
||||
*/
|
||||
|
||||
const CopyButton = ({ text, onCopy, children, ...props }) => {
|
||||
const ref = useCopyToClipboard(text, onCopy);
|
||||
return (
|
||||
<Button variant="secondary" ref={ref} {...props}>
|
||||
{children}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
|
||||
class CopyUrl extends Component {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.state = {
|
||||
showCopyConfirmation: false,
|
||||
};
|
||||
this.onCopy = this.onCopy.bind(this);
|
||||
this.onSelectInput = this.onSelectInput.bind(this);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
clearTimeout(this.dismissCopyConfirmation);
|
||||
}
|
||||
|
||||
onCopy() {
|
||||
this.setState({
|
||||
showCopyConfirmation: true,
|
||||
});
|
||||
|
||||
clearTimeout(this.dismissCopyConfirmation);
|
||||
this.dismissCopyConfirmation = setTimeout(() => {
|
||||
this.setState({
|
||||
showCopyConfirmation: false,
|
||||
});
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
onSelectInput(event) {
|
||||
event.target.select();
|
||||
}
|
||||
|
||||
render() {
|
||||
const url = addQueryArgs(this.props.postLink, {
|
||||
[QUERY_PARAM]: this.props.secretKey,
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<label htmlFor="sppp-link-field" className="screen-reader-text">
|
||||
{__("Share this URL", "sharable-password-protected-posts")}
|
||||
</label>
|
||||
<Flex className="sppp__link-copy">
|
||||
<TextControl
|
||||
id="sppp-link-field"
|
||||
className="sppp__link-field"
|
||||
readOnly
|
||||
label={__("Secret URL:", "sharable-password-protected-posts")}
|
||||
value={safeDecodeURIComponent(url)}
|
||||
onFocus={this.onSelectInput}
|
||||
/>
|
||||
<CopyButton text={url} onCopy={this.onCopy} className="sppp__copy-button">
|
||||
{this.state.showCopyConfirmation
|
||||
? __("Copied!", "sharable-password-protected-posts")
|
||||
: __("Copy", "sharable-password-protected-posts")}
|
||||
</CopyButton>
|
||||
</Flex>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default withSelect((select) => {
|
||||
const { getEditedPostAttribute, getPermalink } = select(editorStore);
|
||||
|
||||
return {
|
||||
postLink: getPermalink(),
|
||||
secretKey: getEditedPostAttribute("meta")[META_KEY],
|
||||
};
|
||||
})(CopyUrl);
|
||||
@@ -0,0 +1,7 @@
|
||||
const CONSTANTS = {
|
||||
META_ENABLED: "_sppp_enabled",
|
||||
META_KEY: "_sppp_key",
|
||||
QUERY_PARAM: "_sppp_key",
|
||||
};
|
||||
|
||||
export default CONSTANTS;
|
||||
@@ -0,0 +1,57 @@
|
||||
import { PluginPostStatusInfo } from "@wordpress/edit-post";
|
||||
import { CheckboxControl } from "@wordpress/components";
|
||||
import { __ } from "@wordpress/i18n";
|
||||
import { useSelect, useDispatch } from "@wordpress/data";
|
||||
import { store as editorStore } from "@wordpress/editor";
|
||||
import CopyUrl from "./CopyUrl";
|
||||
import Check from "./Check";
|
||||
|
||||
import CONSTANTS from "./constants";
|
||||
const { META_ENABLED, META_KEY } = CONSTANTS;
|
||||
|
||||
import "./styles.scss";
|
||||
|
||||
const PostStatusSettings = () => {
|
||||
const { sharingEnabled, existingKey } = useSelect((select) => {
|
||||
const { getEditedPostAttribute } = select(editorStore);
|
||||
const meta = getEditedPostAttribute("meta");
|
||||
return {
|
||||
sharingEnabled: meta[META_ENABLED],
|
||||
existingKey: meta[META_KEY],
|
||||
};
|
||||
});
|
||||
const { editPost } = useDispatch(editorStore);
|
||||
const onChangeEnabled = (value) => {
|
||||
if (value) {
|
||||
editPost({
|
||||
meta: { [META_ENABLED]: true, [META_KEY]: existingKey || window.sppp.newKey || "" },
|
||||
});
|
||||
} else {
|
||||
editPost({
|
||||
meta: { [META_ENABLED]: false, [META_KEY]: "" },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<PluginPostStatusInfo className="sppp">
|
||||
<Check>
|
||||
<div className="sppp__checkbox">
|
||||
<CheckboxControl
|
||||
label={__("Share post via secret URL", "sharable-password-protected-posts")}
|
||||
checked={sharingEnabled}
|
||||
onChange={onChangeEnabled}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{sharingEnabled && (
|
||||
<div className="sppp__link">
|
||||
<CopyUrl />
|
||||
</div>
|
||||
)}
|
||||
</Check>
|
||||
</PluginPostStatusInfo>
|
||||
);
|
||||
};
|
||||
|
||||
export default PostStatusSettings;
|
||||
@@ -0,0 +1,32 @@
|
||||
.components-panel__row.sppp {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
.sppp__link-copy {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
margin-bottom: 16px 0; // $grid-unit-20
|
||||
.components-base-control__field {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.sppp__link-field {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
input[readonly] {
|
||||
padding: 10px;
|
||||
background: #ddd; // $gray-300
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.sppp__copy-button {
|
||||
flex-shrink: 0;
|
||||
margin-left: 8px; // margin left for copy button
|
||||
|
||||
// match copy button height to the link field height
|
||||
height: 38px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { registerPlugin } from "@wordpress/plugins";
|
||||
import PostStatusSettings from "./PostStatusSettings";
|
||||
|
||||
registerPlugin("sharable-password-protected-posts", {
|
||||
render: PostStatusSettings,
|
||||
});
|
||||
Reference in New Issue
Block a user