v1.3.0
This commit is contained in:
parent
30451228f7
commit
e3bfd7b6f2
12 changed files with 108 additions and 29 deletions
|
|
@ -72,6 +72,8 @@ class Robotstxt_Manager_Admin {
|
|||
// Admin notices for subscriptions needing attention.
|
||||
$manager_notices = $this->build_subscription_notices( $catalog, $subscriptions );
|
||||
$manager_subscriptions = $subscriptions;
|
||||
$manager_has_api_key = $client->has_api_key();
|
||||
$manager_store_url = $client->get_store_url();
|
||||
|
||||
require ROBOTSTXT_MANAGER_DIR . 'admin/views/page-catalog.php';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ class Robotstxt_Manager_Settings {
|
|||
}
|
||||
echo '</p>';
|
||||
} else {
|
||||
echo '<p class="description">' . esc_html__( 'Account-level API key issued by the ROBOTSTXT store. Required to authenticate catalog and subscription requests. The value is encrypted before storage.', 'robotstxt-manager' ) . '</p>';
|
||||
echo '<p class="description">' . esc_html__( 'Account-level API key from the ROBOTSTXT store (create your free account there to get one). Optional — the free catalog works without it — but required to link your subscriptions, install premium plugins, and receive their updates. Encrypted before storage.', 'robotstxt-manager' ) . '</p>';
|
||||
}
|
||||
|
||||
// Action buttons.
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
* @var array<string, array{installed:bool, active:bool, version:string}> $local
|
||||
* @var array<string, array<string,mixed>> $manager_subscriptions
|
||||
* @var list<array{type:string, message:string}> $manager_notices
|
||||
* @var bool $manager_has_api_key
|
||||
* @var string $manager_store_url
|
||||
*/
|
||||
|
||||
$client_configured = Robotstxt_Manager_Core_Client::from_options()->is_configured();
|
||||
|
|
@ -77,6 +79,22 @@ $compat_warnings = 0;
|
|||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<?php if ( empty( $manager_has_api_key ) && '' !== ( $manager_store_url ?? '' ) ) : ?>
|
||||
<div class="notice notice-info">
|
||||
<p>
|
||||
<?php
|
||||
echo wp_kses_post(
|
||||
sprintf(
|
||||
/* translators: %s: store registration URL. */
|
||||
__( 'Create your free account at the <a href="%s" target="_blank" rel="noopener noreferrer">ROBOTSTXT store</a> to get your personal API key. The key links your subscriptions to this site and unlocks premium plugins and updates.', 'robotstxt-manager' ),
|
||||
esc_url( $manager_store_url . '/wp-login.php?action=register' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( '' !== $notice_message && in_array( $notice_result, array( 'success', 'error' ), true ) ) : ?>
|
||||
<div class="notice notice-<?php echo esc_attr( $notice_result ); ?> is-dismissible"><p><?php echo esc_html( $notice_message ); ?></p></div>
|
||||
<?php endif; ?>
|
||||
|
|
@ -149,6 +167,14 @@ $compat_warnings = 0;
|
|||
$website_url = '' !== $page_url ? $page_url : $homepage;
|
||||
$has_detail = ( '' !== $website_url || '' !== $desc );
|
||||
|
||||
// Subscription state: premium plugins are only usable
|
||||
// (install/update) with an active or in-grace subscription.
|
||||
$is_premium = ( $cost > 0.0 || 'premium' === $kind );
|
||||
$sub_row = $manager_subscriptions[ $slug ] ?? null;
|
||||
$raw_status = is_array( $sub_row ) ? ( $sub_row['status'] ?? '' ) : '';
|
||||
$sub_status = is_string( $raw_status ) ? $raw_status : '';
|
||||
$subscribed = in_array( $sub_status, array( 'active', 'payment_failed' ), true );
|
||||
|
||||
$raw_reqs = $entry['requires_plugins'] ?? '';
|
||||
$req_slugs = array();
|
||||
if ( is_string( $raw_reqs ) && '' !== trim( $raw_reqs ) ) {
|
||||
|
|
@ -220,7 +246,7 @@ $compat_warnings = 0;
|
|||
</td>
|
||||
<td>
|
||||
<?php
|
||||
if ( $cost > 0.0 || 'premium' === $kind ) {
|
||||
if ( $is_premium ) {
|
||||
echo esc_html(
|
||||
sprintf(
|
||||
/* translators: %s: formatted price number. */
|
||||
|
|
@ -230,13 +256,10 @@ $compat_warnings = 0;
|
|||
);
|
||||
|
||||
// Subscription pill for premium plugins.
|
||||
$sub_row = $manager_subscriptions[ $slug ] ?? null;
|
||||
$sub_text = '';
|
||||
|
||||
if ( is_array( $sub_row ) ) {
|
||||
$raw_sub_status = $sub_row['status'] ?? '';
|
||||
$raw_sub_expiry = $sub_row['expires_at'] ?? '';
|
||||
$sub_status = is_string( $raw_sub_status ) ? $raw_sub_status : '';
|
||||
$sub_expiry = is_string( $raw_sub_expiry ) ? $raw_sub_expiry : '';
|
||||
|
||||
if ( 'active' === $sub_status && '' !== $sub_expiry ) {
|
||||
|
|
@ -261,11 +284,8 @@ $compat_warnings = 0;
|
|||
}
|
||||
|
||||
if ( '' !== $sub_text ) {
|
||||
$raw_pill_status = is_array( $sub_row ) ? ( $sub_row['status'] ?? '' ) : '';
|
||||
$pill_status = is_string( $raw_pill_status ) ? $raw_pill_status : '';
|
||||
|
||||
echo '<br /><span class="robotstxt-manager-subscription robotstxt-manager-subscription--'
|
||||
. esc_attr( $pill_status )
|
||||
. esc_attr( $sub_status )
|
||||
. '">' . esc_html( $sub_text ) . '</span>';
|
||||
}
|
||||
} else {
|
||||
|
|
@ -274,18 +294,16 @@ $compat_warnings = 0;
|
|||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ( ! $l_installed ) : ?>
|
||||
<?php if ( ! $wp_ok || ! $php_ok ) : ?>
|
||||
<span class="description"><?php esc_html_e( 'Incompatible', 'robotstxt-manager' ); ?></span>
|
||||
<?php elseif ( $is_premium && ! $subscribed ) : ?>
|
||||
<?php if ( '' !== $page_url ) : ?>
|
||||
<a class="button button-primary" href="<?php echo esc_url( $page_url ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Buy', 'robotstxt-manager' ); ?></a>
|
||||
<?php else : ?>
|
||||
<?php if ( $cost > 0.0 && '' !== $page_url ) : ?>
|
||||
<a class="button button-secondary" href="<?php echo esc_url( $page_url ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Buy', 'robotstxt-manager' ); ?></a>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
$install_class = ( $cost > 0.0 && '' !== $page_url ) ? 'button-secondary' : 'button-primary';
|
||||
?>
|
||||
<a class="button <?php echo esc_attr( $install_class ); ?>" href="<?php echo esc_url( Robotstxt_Manager_Admin::action_url( 'install', $slug ) ); ?>"><?php esc_html_e( 'Install', 'robotstxt-manager' ); ?></a>
|
||||
—
|
||||
<?php endif; ?>
|
||||
<?php elseif ( ! $l_installed ) : ?>
|
||||
<a class="button button-primary" href="<?php echo esc_url( Robotstxt_Manager_Admin::action_url( 'install', $slug ) ); ?>"><?php esc_html_e( 'Install', 'robotstxt-manager' ); ?></a>
|
||||
<?php elseif ( ! $l_active ) : ?>
|
||||
<a class="button button-primary" href="<?php echo esc_url( Robotstxt_Manager_Admin::action_url( 'activate', $slug ) ); ?>"><?php esc_html_e( 'Activate', 'robotstxt-manager' ); ?></a>
|
||||
<?php elseif ( $update_available ) : ?>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,24 @@
|
|||
== Changelog ==
|
||||
|
||||
= 1.3.0 =
|
||||
|
||||
_Release date: 2026-08-17_
|
||||
|
||||
**Highlights**
|
||||
|
||||
* The catalog now works **without an API key**: only the Store URL is required. The free catalog, prices, and product pages are public on Core, so a fresh install shows the store immediately. An info notice invites visitors to create their free account at the store to get a personal API key (linking subscriptions and unlocking premium plugins and updates).
|
||||
|
||||
**Changed**
|
||||
|
||||
* Action buttons follow subscription state: premium plugins without an active subscription show **Buy** only (Install/Update hidden — the download would be rejected); with an active or in-grace subscription (and for free plugins) they show **Install / Activate / Update** as usual. Previously premium rows always offered Install alongside Buy.
|
||||
* The API-key setting description clarifies the key is optional for browsing, required for subscriptions/premium.
|
||||
* Plugin version 1.2.1 → 1.3.0. No database schema changes (no custom tables).
|
||||
|
||||
**Compatibility**
|
||||
|
||||
* WordPress: 4.4 - 7.1 (scan-verified: wp-compat clean from 4.4)
|
||||
* PHP: 8.0 - 8.5 (scan-verified: PHPCompatibility + manual feature audit)
|
||||
|
||||
= 1.2.1 =
|
||||
|
||||
_Release date: 2026-08-17_
|
||||
|
|
|
|||
|
|
@ -91,12 +91,25 @@ class Robotstxt_Manager_Core_Client {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns whether the client has both a URL and a key configured.
|
||||
* Returns whether the client can talk to the store.
|
||||
*
|
||||
* Only the Store URL is required: the catalog (free plugins, prices,
|
||||
* product pages) is public on Core. The API key is optional — it is
|
||||
* needed for subscription data and premium downloads, not for listing.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_configured(): bool {
|
||||
return '' !== $this->store_url && '' !== $this->api_key;
|
||||
return '' !== $this->store_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an API key is configured.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_api_key(): bool {
|
||||
return '' !== $this->api_key;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -269,13 +282,16 @@ class Robotstxt_Manager_Core_Client {
|
|||
private function get( string $endpoint ) {
|
||||
$url = $this->store_url . '/wp-json/' . self::REST_NAMESPACE . $endpoint;
|
||||
|
||||
$headers = array( 'Accept' => 'application/json' );
|
||||
|
||||
if ( '' !== $this->api_key ) {
|
||||
$headers['Authorization'] = 'Bearer ' . $this->api_key;
|
||||
}
|
||||
|
||||
return wp_remote_get(
|
||||
$url,
|
||||
array(
|
||||
'headers' => array(
|
||||
'Authorization' => 'Bearer ' . $this->api_key,
|
||||
'Accept' => 'application/json',
|
||||
),
|
||||
'headers' => $headers,
|
||||
'timeout' => self::TIMEOUT,
|
||||
)
|
||||
);
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -293,3 +293,9 @@ msgid "The subscription for %1$s expires in %2$d day."
|
|||
msgid_plural "The subscription for %1$s expires in %2$d days."
|
||||
msgstr[0] "La subscripció de %1$s caduca en %2$d dia."
|
||||
msgstr[1] "La subscripció de %1$s caduca en %2$d dies."
|
||||
|
||||
msgid "Create your free account at the <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">ROBOTSTXT store</a> to get your personal API key. The key links your subscriptions to this site and unlocks premium plugins and updates."
|
||||
msgstr "Crea el teu compte gratuït a <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">la botiga de ROBOTSTXT</a> per obtenir la teva clau API personal. La clau vincula les teves subscripcions a aquest lloc i desbloqueja els plugins premium i les seves actualitzacions."
|
||||
|
||||
msgid "Account-level API key from the ROBOTSTXT store (create your free account there to get one). Optional — the free catalog works without it — but required to link your subscriptions, install premium plugins, and receive their updates. Encrypted before storage."
|
||||
msgstr "Clau API a nivell de compte de la botiga de ROBOTSTXT (crea allà el teu compte gratuït per obtenir-la). Opcional: el catàleg de plugins gratuïts funciona sense ella, però és necessària per vincular les teves subscripcions, instal·lar plugins premium i rebre les actualitzacions. Es xifra abans de desar-se."
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -293,3 +293,9 @@ msgid "The subscription for %1$s expires in %2$d day."
|
|||
msgid_plural "The subscription for %1$s expires in %2$d days."
|
||||
msgstr[0] "La suscripción de %1$s caduca en %2$d día."
|
||||
msgstr[1] "La suscripción de %1$s caduca en %2$d días."
|
||||
|
||||
msgid "Create your free account at the <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">ROBOTSTXT store</a> to get your personal API key. The key links your subscriptions to this site and unlocks premium plugins and updates."
|
||||
msgstr "Crea tu cuenta gratuita en <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">la tienda de ROBOTSTXT</a> para obtener tu clave API personal. La clave vincula tus suscripciones a este sitio y desbloquea los plugins premium y sus actualizaciones."
|
||||
|
||||
msgid "Account-level API key from the ROBOTSTXT store (create your free account there to get one). Optional — the free catalog works without it — but required to link your subscriptions, install premium plugins, and receive their updates. Encrypted before storage."
|
||||
msgstr "Clave API a nivel de cuenta de la tienda de ROBOTSTXT (crea allí tu cuenta gratuita para obtenerla). Opcional: el catálogo de plugins gratis funciona sin ella, pero es necesaria para vincular tus suscripciones, instalar plugins premium y recibir sus actualizaciones. Se cifra antes de guardarse."
|
||||
|
|
|
|||
|
|
@ -25,3 +25,9 @@ msgstr ""
|
|||
|
||||
msgid "Expired"
|
||||
msgstr ""
|
||||
|
||||
msgid "Create your free account at the <a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">ROBOTSTXT store</a> to get your personal API key. The key links your subscriptions to this site and unlocks premium plugins and updates."
|
||||
msgstr ""
|
||||
|
||||
msgid "Account-level API key from the ROBOTSTXT store (create your free account there to get one). Optional — the free catalog works without it — but required to link your subscriptions, install premium plugins, and receive their updates. Encrypted before storage."
|
||||
msgstr ""
|
||||
|
|
|
|||
10
readme.txt
10
readme.txt
|
|
@ -3,9 +3,9 @@ Contributors: javiercasares, robotstxt
|
|||
Tags: dashboard, catalog, updates, subscriptions, management
|
||||
Requires at least: 4.4
|
||||
Tested up to: 7.1
|
||||
Stable tag: 1.2.1
|
||||
Stable tag: 1.3.0
|
||||
Requires PHP: 8.0
|
||||
Version: 1.2.1
|
||||
Version: 1.3.0
|
||||
License: GPL-3.0-or-later
|
||||
License URI: https://www.gnu.org/licenses/gpl-3.0.txt
|
||||
|
||||
|
|
@ -92,6 +92,12 @@ Encrypted at rest using AES-256-CBC with a key derived from your site's WordPres
|
|||
|
||||
== Changelog ==
|
||||
|
||||
= 1.3.0 =
|
||||
|
||||
_Release date: 2026-08-17_
|
||||
|
||||
* Catalog works without an API key (only the Store URL is needed); free plugins are listed and installable, and an info notice links to the store to register and get a personal key. Premium plugins show Buy only until subscribed; with an active subscription they show Install/Update.
|
||||
|
||||
= 1.2.1 =
|
||||
|
||||
_Release date: 2026-08-17_
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
* Plugin Name: Manager (by ROBOTSTXT)
|
||||
* Plugin URI: https://git.robotstxt.es/ROBOTSTXT/robotstxt-manager
|
||||
* Description: Client-side dashboard for the ROBOTSTXT plugin ecosystem. Lists the catalog from a remote Plugins Core install, resolves local install/update state, and installs, activates, and updates plugins directly from the store.
|
||||
* Version: 1.2.1
|
||||
* Version: 1.3.0
|
||||
* Requires at least: 4.4
|
||||
* Requires PHP: 8.0
|
||||
* Author: ROBOTSTXT
|
||||
|
|
@ -21,7 +21,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
}
|
||||
|
||||
/** Plugin version. */
|
||||
define( 'ROBOTSTXT_MANAGER_VERSION', '1.2.1' );
|
||||
define( 'ROBOTSTXT_MANAGER_VERSION', '1.3.0' );
|
||||
|
||||
/** Absolute path to the plugin directory, with trailing slash. */
|
||||
define( 'ROBOTSTXT_MANAGER_DIR', plugin_dir_path( __FILE__ ) );
|
||||
|
|
|
|||
Loading…
Reference in a new issue