Changeset 3479200
- Timestamp:
- 03/10/2026 03:23:12 PM (3 weeks ago)
- Location:
- nota-ai-tools
- Files:
-
- 6 edited
- 1 copied
-
tags/0.20.2 (copied) (copied from nota-ai-tools/trunk)
-
tags/0.20.2/includes/class-nota-news-settings.php (modified) (8 diffs)
-
tags/0.20.2/nota-wordpress-plugin.php (modified) (3 diffs)
-
tags/0.20.2/readme.txt (modified) (1 diff)
-
trunk/includes/class-nota-news-settings.php (modified) (8 diffs)
-
trunk/nota-wordpress-plugin.php (modified) (3 diffs)
-
trunk/readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
nota-ai-tools/tags/0.20.2/includes/class-nota-news-settings.php
r3468882 r3479200 48 48 // Attach the Nota News settings section/fields to the existing Nota Tools settings page. 49 49 add_action( 'admin_init', array( $this, 'register_settings' ) ); 50 // Schedule recurring hourly display name refresh. 51 add_action( 'admin_init', array( $this, 'maybe_schedule_display_name_refresh' ) ); 52 // Handle the cron callback for refreshing the display name. 53 add_action( 'nota_refresh_news_display_name', array( $this, 'refresh_nota_news_display_name' ) ); 50 54 } 51 55 … … 54 58 */ 55 59 public function register_settings() { 56 // Only show Nota News settings for users with entitlement access.57 if ( ! $this->current_user_has_nota_news_access() ) {58 return;59 }60 61 // Nota News settings (rendered on the existing Nota Tools settings page).62 63 60 add_settings_section( 64 61 $this->news_settings_section_key, … … 80 77 81 78 /** 82 * Returns whether the current user has access to Nota News based on org entitlements.83 *84 * @return bool85 */86 private function current_user_has_nota_news_access() {87 $this->resolve_nota_news_entitlements();88 89 $user_id = get_current_user_id();90 $cache_key = 'nota_news_entitled_' . (string) $user_id;91 92 return '1' === get_transient( $cache_key );93 }94 95 /**96 79 * Returns the display name for Nota News. 97 * Reads from the WP option set during entitlement resolution. Falls back to " Nota News".80 * Reads from the WP option set during entitlement resolution. Falls back to "INTELLIGENCE". 98 81 * 99 82 * @return string 100 83 */ 101 84 public function get_nota_news_display_name() { 102 $this->resolve_nota_news_entitlements();103 104 85 $name = get_option( 'nota_news_display_name', '' ); 105 86 return ! empty( $name ) ? $name : __( 'INTELLIGENCE', 'nota' ); … … 107 88 108 89 /** 109 * Resolves and caches Nota News entitlement data from the API. 110 * Uses a transient for the access flag and a WP option for the display name. 111 * The display name is read from entitlements.settings.tools.notaNews.displayName. 112 */ 113 private function resolve_nota_news_entitlements() { 114 $user_id = get_current_user_id(); 115 if ( ! $user_id ) { 116 return; 117 } 118 119 $access_cache_key = 'nota_news_entitled_' . (string) $user_id; 120 121 // If access is already cached, nothing to do. 122 if ( false !== get_transient( $access_cache_key ) ) { 123 return; 124 } 125 90 * Schedules a recurring hourly cron job to refresh the display name. 91 * Called on admin_init so the schedule is created on first admin visit. 92 */ 93 public function maybe_schedule_display_name_refresh() { 94 if ( ! wp_next_scheduled( 'nota_refresh_news_display_name' ) ) { 95 wp_schedule_event( time(), 'hourly', 'nota_refresh_news_display_name' ); 96 } 97 } 98 99 /** 100 * Unschedules the display name refresh cron job. 101 * Should be called on plugin deactivation. 102 */ 103 public static function unschedule_display_name_refresh() { 104 $timestamp = wp_next_scheduled( 'nota_refresh_news_display_name' ); 105 if ( $timestamp ) { 106 wp_unschedule_event( $timestamp, 'nota_refresh_news_display_name' ); 107 } 108 } 109 110 /** 111 * Fetches the Nota News display name from the API and persists it to a WP option. 112 * Called by the hourly cron job. On error, the existing option value is preserved. 113 */ 114 public function refresh_nota_news_display_name() { 115 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Temporary debug logging to verify cron execution. 116 error_log( '[Nota] refresh_nota_news_display_name cron fired' ); 126 117 // If no API key is configured or the request fails, get_current_user() returns WP_Error. 127 118 $resp = $this->api instanceof Nota_Api ? $this->api->get_current_user() : new WP_Error( 'nota_missing_api', 'Missing Nota API instance' ); 128 119 129 120 if ( is_wp_error( $resp ) ) { 130 $error_code = $resp->get_error_code();131 $error_message = $resp->get_error_message();132 133 // Definite denial: auth failures or missing configuration should be cached for longer.134 $is_auth_error = 'nota_error' === $error_code && strpos( $error_message, 'Authentication error' ) !== false;135 $is_config_error = 'nota_error' === $error_code && strpos( $error_message, 'Missing API URL' ) !== false;136 $is_missing_api = 'nota_missing_api' === $error_code;137 138 if ( $is_auth_error || $is_config_error || $is_missing_api ) {139 set_transient( $access_cache_key, '0', 5 * MINUTE_IN_SECONDS );140 return;141 }142 143 // Transient errors (network issues, rate limits, server errors): short cache to allow quick recovery144 // while reducing API load during outages. 30 seconds balances responsiveness with protection.145 set_transient( $access_cache_key, '0', 30 );146 121 return; 147 122 } … … 149 124 // The API returns { result: { organizations, useOrganizationAuth, ... } }. 150 125 if ( ! isset( $resp->result ) || ! is_object( $resp->result ) ) { 151 set_transient( $access_cache_key, '0', 5 * MINUTE_IN_SECONDS );152 126 return; 153 127 } … … 158 132 // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase 159 133 if ( isset( $user->useOrganizationAuth ) && false === $user->useOrganizationAuth ) { 160 set_transient( $access_cache_key, '1', 5 * MINUTE_IN_SECONDS );161 134 return; 162 135 } 163 136 164 137 if ( ! isset( $user->organizations ) || ! is_array( $user->organizations ) ) { 165 set_transient( $access_cache_key, '0', 5 * MINUTE_IN_SECONDS );166 138 return; 167 139 } … … 183 155 true === $entitlements->applicationPermissions->wordpressPlugin->tools->notaNews->access 184 156 ) { 185 set_transient( $access_cache_key, '1', 5 * MINUTE_IN_SECONDS );186 187 157 // Read display name from entitlement settings and persist in WP option. 188 158 $display_name = ''; … … 207 177 } 208 178 // phpcs:enable 209 210 set_transient( $access_cache_key, '0', 5 * MINUTE_IN_SECONDS );211 179 } 212 180 -
nota-ai-tools/tags/0.20.2/nota-wordpress-plugin.php
r3473075 r3479200 3 3 * Plugin Name: Nota Tools 4 4 * Description: Nota’s assistive AI tools help publishers create headlines, summaries, SEO keywords and more. 5 * Version: 0.20. 15 * Version: 0.20.2 6 6 * Author: Nota 7 7 * Author URI: https://heynota.com … … 14 14 defined( 'ABSPATH' ) || exit; 15 15 16 define( 'NOTA_PLUGIN_VERSION', '0.20. 1' );16 define( 'NOTA_PLUGIN_VERSION', '0.20.2' ); 17 17 18 18 if ( ! defined( 'NOTA_PLUGIN_FILE' ) ) { … … 22 22 require_once __DIR__ . '/includes/class-nota-settings.php'; 23 23 require_once __DIR__ . '/includes/class-nota-migrations.php'; 24 require_once __DIR__ . '/includes/class-nota-news-settings.php'; 24 25 25 26 register_activation_hook( NOTA_PLUGIN_FILE, array( 'Nota_Migrations', 'activate' ) ); 27 register_deactivation_hook( NOTA_PLUGIN_FILE, array( 'Nota_News_Settings', 'unschedule_display_name_refresh' ) ); 26 28 27 29 add_action( 'plugins_loaded', 'nota_plugin_init' ); -
nota-ai-tools/tags/0.20.2/readme.txt
r3473075 r3479200 4 4 License URI: http://www.gnu.org/licenses/gpl.html 5 5 Requires PHP: 7.2.5 6 Stable tag: 0.20. 16 Stable tag: 0.20.2 7 7 Tested up to: 6.9.0 8 8 -
nota-ai-tools/trunk/includes/class-nota-news-settings.php
r3468882 r3479200 48 48 // Attach the Nota News settings section/fields to the existing Nota Tools settings page. 49 49 add_action( 'admin_init', array( $this, 'register_settings' ) ); 50 // Schedule recurring hourly display name refresh. 51 add_action( 'admin_init', array( $this, 'maybe_schedule_display_name_refresh' ) ); 52 // Handle the cron callback for refreshing the display name. 53 add_action( 'nota_refresh_news_display_name', array( $this, 'refresh_nota_news_display_name' ) ); 50 54 } 51 55 … … 54 58 */ 55 59 public function register_settings() { 56 // Only show Nota News settings for users with entitlement access.57 if ( ! $this->current_user_has_nota_news_access() ) {58 return;59 }60 61 // Nota News settings (rendered on the existing Nota Tools settings page).62 63 60 add_settings_section( 64 61 $this->news_settings_section_key, … … 80 77 81 78 /** 82 * Returns whether the current user has access to Nota News based on org entitlements.83 *84 * @return bool85 */86 private function current_user_has_nota_news_access() {87 $this->resolve_nota_news_entitlements();88 89 $user_id = get_current_user_id();90 $cache_key = 'nota_news_entitled_' . (string) $user_id;91 92 return '1' === get_transient( $cache_key );93 }94 95 /**96 79 * Returns the display name for Nota News. 97 * Reads from the WP option set during entitlement resolution. Falls back to " Nota News".80 * Reads from the WP option set during entitlement resolution. Falls back to "INTELLIGENCE". 98 81 * 99 82 * @return string 100 83 */ 101 84 public function get_nota_news_display_name() { 102 $this->resolve_nota_news_entitlements();103 104 85 $name = get_option( 'nota_news_display_name', '' ); 105 86 return ! empty( $name ) ? $name : __( 'INTELLIGENCE', 'nota' ); … … 107 88 108 89 /** 109 * Resolves and caches Nota News entitlement data from the API. 110 * Uses a transient for the access flag and a WP option for the display name. 111 * The display name is read from entitlements.settings.tools.notaNews.displayName. 112 */ 113 private function resolve_nota_news_entitlements() { 114 $user_id = get_current_user_id(); 115 if ( ! $user_id ) { 116 return; 117 } 118 119 $access_cache_key = 'nota_news_entitled_' . (string) $user_id; 120 121 // If access is already cached, nothing to do. 122 if ( false !== get_transient( $access_cache_key ) ) { 123 return; 124 } 125 90 * Schedules a recurring hourly cron job to refresh the display name. 91 * Called on admin_init so the schedule is created on first admin visit. 92 */ 93 public function maybe_schedule_display_name_refresh() { 94 if ( ! wp_next_scheduled( 'nota_refresh_news_display_name' ) ) { 95 wp_schedule_event( time(), 'hourly', 'nota_refresh_news_display_name' ); 96 } 97 } 98 99 /** 100 * Unschedules the display name refresh cron job. 101 * Should be called on plugin deactivation. 102 */ 103 public static function unschedule_display_name_refresh() { 104 $timestamp = wp_next_scheduled( 'nota_refresh_news_display_name' ); 105 if ( $timestamp ) { 106 wp_unschedule_event( $timestamp, 'nota_refresh_news_display_name' ); 107 } 108 } 109 110 /** 111 * Fetches the Nota News display name from the API and persists it to a WP option. 112 * Called by the hourly cron job. On error, the existing option value is preserved. 113 */ 114 public function refresh_nota_news_display_name() { 115 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Temporary debug logging to verify cron execution. 116 error_log( '[Nota] refresh_nota_news_display_name cron fired' ); 126 117 // If no API key is configured or the request fails, get_current_user() returns WP_Error. 127 118 $resp = $this->api instanceof Nota_Api ? $this->api->get_current_user() : new WP_Error( 'nota_missing_api', 'Missing Nota API instance' ); 128 119 129 120 if ( is_wp_error( $resp ) ) { 130 $error_code = $resp->get_error_code();131 $error_message = $resp->get_error_message();132 133 // Definite denial: auth failures or missing configuration should be cached for longer.134 $is_auth_error = 'nota_error' === $error_code && strpos( $error_message, 'Authentication error' ) !== false;135 $is_config_error = 'nota_error' === $error_code && strpos( $error_message, 'Missing API URL' ) !== false;136 $is_missing_api = 'nota_missing_api' === $error_code;137 138 if ( $is_auth_error || $is_config_error || $is_missing_api ) {139 set_transient( $access_cache_key, '0', 5 * MINUTE_IN_SECONDS );140 return;141 }142 143 // Transient errors (network issues, rate limits, server errors): short cache to allow quick recovery144 // while reducing API load during outages. 30 seconds balances responsiveness with protection.145 set_transient( $access_cache_key, '0', 30 );146 121 return; 147 122 } … … 149 124 // The API returns { result: { organizations, useOrganizationAuth, ... } }. 150 125 if ( ! isset( $resp->result ) || ! is_object( $resp->result ) ) { 151 set_transient( $access_cache_key, '0', 5 * MINUTE_IN_SECONDS );152 126 return; 153 127 } … … 158 132 // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase 159 133 if ( isset( $user->useOrganizationAuth ) && false === $user->useOrganizationAuth ) { 160 set_transient( $access_cache_key, '1', 5 * MINUTE_IN_SECONDS );161 134 return; 162 135 } 163 136 164 137 if ( ! isset( $user->organizations ) || ! is_array( $user->organizations ) ) { 165 set_transient( $access_cache_key, '0', 5 * MINUTE_IN_SECONDS );166 138 return; 167 139 } … … 183 155 true === $entitlements->applicationPermissions->wordpressPlugin->tools->notaNews->access 184 156 ) { 185 set_transient( $access_cache_key, '1', 5 * MINUTE_IN_SECONDS );186 187 157 // Read display name from entitlement settings and persist in WP option. 188 158 $display_name = ''; … … 207 177 } 208 178 // phpcs:enable 209 210 set_transient( $access_cache_key, '0', 5 * MINUTE_IN_SECONDS );211 179 } 212 180 -
nota-ai-tools/trunk/nota-wordpress-plugin.php
r3473075 r3479200 3 3 * Plugin Name: Nota Tools 4 4 * Description: Nota’s assistive AI tools help publishers create headlines, summaries, SEO keywords and more. 5 * Version: 0.20. 15 * Version: 0.20.2 6 6 * Author: Nota 7 7 * Author URI: https://heynota.com … … 14 14 defined( 'ABSPATH' ) || exit; 15 15 16 define( 'NOTA_PLUGIN_VERSION', '0.20. 1' );16 define( 'NOTA_PLUGIN_VERSION', '0.20.2' ); 17 17 18 18 if ( ! defined( 'NOTA_PLUGIN_FILE' ) ) { … … 22 22 require_once __DIR__ . '/includes/class-nota-settings.php'; 23 23 require_once __DIR__ . '/includes/class-nota-migrations.php'; 24 require_once __DIR__ . '/includes/class-nota-news-settings.php'; 24 25 25 26 register_activation_hook( NOTA_PLUGIN_FILE, array( 'Nota_Migrations', 'activate' ) ); 27 register_deactivation_hook( NOTA_PLUGIN_FILE, array( 'Nota_News_Settings', 'unschedule_display_name_refresh' ) ); 26 28 27 29 add_action( 'plugins_loaded', 'nota_plugin_init' ); -
nota-ai-tools/trunk/readme.txt
r3473075 r3479200 4 4 License URI: http://www.gnu.org/licenses/gpl.html 5 5 Requires PHP: 7.2.5 6 Stable tag: 0.20. 16 Stable tag: 0.20.2 7 7 Tested up to: 6.9.0 8 8
Note: See TracChangeset
for help on using the changeset viewer.