Changeset 3484580
- Timestamp:
- 03/17/2026 09:02:52 AM (11 days ago)
- Location:
- wpraiz-content-api-tool
- Files:
-
- 4 edited
- 11 copied
-
tags/2.0.2 (copied) (copied from wpraiz-content-api-tool/trunk)
-
tags/2.0.2/includes/admin/class-license-server.php (copied) (copied from wpraiz-content-api-tool/trunk/includes/admin/class-license-server.php)
-
tags/2.0.2/includes/admin/class-license.php (modified) (8 diffs)
-
tags/2.0.2/includes/ai/class-deepseek-provider.php (copied) (copied from wpraiz-content-api-tool/trunk/includes/ai/class-deepseek-provider.php)
-
tags/2.0.2/includes/ai/class-openrouter-provider.php (copied) (copied from wpraiz-content-api-tool/trunk/includes/ai/class-openrouter-provider.php)
-
tags/2.0.2/includes/class-auth.php (copied) (copied from wpraiz-content-api-tool/trunk/includes/class-auth.php)
-
tags/2.0.2/includes/class-content-manager.php (copied) (copied from wpraiz-content-api-tool/trunk/includes/class-content-manager.php)
-
tags/2.0.2/includes/class-media-handler.php (copied) (copied from wpraiz-content-api-tool/trunk/includes/class-media-handler.php)
-
tags/2.0.2/includes/mcp/class-mcp-server.php (copied) (copied from wpraiz-content-api-tool/trunk/includes/mcp/class-mcp-server.php)
-
tags/2.0.2/includes/mcp/class-mcp-tools.php (copied) (copied from wpraiz-content-api-tool/trunk/includes/mcp/class-mcp-tools.php)
-
tags/2.0.2/readme.txt (copied) (copied from wpraiz-content-api-tool/trunk/readme.txt) (2 diffs)
-
tags/2.0.2/wpraiz-content.php (copied) (copied from wpraiz-content-api-tool/trunk/wpraiz-content.php) (2 diffs)
-
trunk/includes/admin/class-license.php (modified) (8 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/wpraiz-content.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
wpraiz-content-api-tool/tags/2.0.2/includes/admin/class-license.php
r3482396 r3484580 5 5 6 6 /** 7 * License management via LemonSqueezy Licensing API.7 * License management via WPRaiz self-hosted license server. 8 8 * 9 * LemonSqueezy exposes public endpoints — no store API key needed in the plugin. 10 * The plugin only holds the customer's license key. 9 * The license server runs on wpraiz.com.br (class-license-server.php). 10 * Flow: 11 * 1. Buyer purchases on Hotmart 12 * 2. Hotmart webhook → license server generates key → emails buyer 13 * 3. Buyer enters key here → plugin calls wpraiz.com.br to activate 14 * 4. Background re-validation daily 11 15 * 12 * Endpoints used:13 * POST https://api.lemonsqueezy.com/v1/licenses/activate14 * POST https://api.lemonsqueezy.com/v1/licenses/validate15 * POST https://api.lemonsqueezy.com/v1/licenses/deactivate16 * Endpoints (on WPRAIZ_LICENSE_SERVER_URL): 17 * POST /wpraiz/v2/license/activate 18 * POST /wpraiz/v2/license/validate 19 * POST /wpraiz/v2/license/deactivate 16 20 */ 17 21 class License { 18 22 19 const LS_ACTIVATE = 'https://api.lemonsqueezy.com/v1/licenses/activate'; 20 const LS_VALIDATE = 'https://api.lemonsqueezy.com/v1/licenses/validate'; 21 const LS_DEACTIVATE = 'https://api.lemonsqueezy.com/v1/licenses/deactivate'; 23 /** License server base URL. Filterable via 'wpraiz_license_server_url'. */ 24 const DEFAULT_SERVER = 'https://wpraiz.com.br'; 22 25 23 26 /** How often to re-validate remotely (seconds). Default: 24h. */ … … 33 36 wp_schedule_event( time(), 'daily', 'wpraiz_revalidate_license' ); 34 37 } 38 } 39 40 /** 41 * Get license server URL (filterable). 42 */ 43 private static function server_url(): string { 44 return apply_filters( 'wpraiz_license_server_url', self::DEFAULT_SERVER ); 35 45 } 36 46 … … 68 78 } 69 79 70 $key = get_option( 'wpraiz_license_key', '' ); 71 $instance_id = get_option( 'wpraiz_license_instance_id', '' ); 80 $key = get_option( 'wpraiz_license_key', '' ); 72 81 73 if ( $key && $instance_id) {74 wp_remote_post( self:: LS_DEACTIVATE, [82 if ( $key ) { 83 wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/deactivate', [ 75 84 'timeout' => 15, 76 'body' => [ 85 'headers' => [ 'Content-Type' => 'application/json' ], 86 'body' => wp_json_encode( [ 77 87 'license_key' => $key, 78 ' instance_id' => $instance_id,79 ] ,88 'site_url' => get_site_url(), 89 ] ), 80 90 ] ); 81 91 } … … 83 93 delete_option( 'wpraiz_license_key' ); 84 94 delete_option( 'wpraiz_license_status' ); 85 delete_option( 'wpraiz_license_instance_id' );86 95 delete_option( 'wpraiz_license_activated_at' ); 87 96 delete_option( 'wpraiz_license_expires_at' ); 88 97 delete_option( 'wpraiz_license_last_check' ); 98 99 // Cleanup legacy LemonSqueezy option 100 delete_option( 'wpraiz_license_instance_id' ); 89 101 90 102 wp_send_json_success( [ 'message' => 'License deactivated.' ] ); … … 94 106 95 107 public function revalidate() { 96 $key = get_option( 'wpraiz_license_key', '' );97 $instance_id = get_option( 'wpraiz_license_instance_id', '' );108 $key = get_option( 'wpraiz_license_key', '' ); 109 if ( ! $key ) return; 98 110 99 if ( ! $key || ! $instance_id ) return; 100 101 $response = wp_remote_post( self::LS_VALIDATE, [ 111 $response = wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/validate', [ 102 112 'timeout' => 15, 103 'body' => [ 113 'headers' => [ 'Content-Type' => 'application/json' ], 114 'body' => wp_json_encode( [ 104 115 'license_key' => $key, 105 ' instance_id' => $instance_id,106 ] ,116 'site_url' => get_site_url(), 117 ] ), 107 118 ] ); 108 119 … … 111 122 $body = json_decode( wp_remote_retrieve_body( $response ), true ); 112 123 113 $valid = ! empty( $body['activated'] ) || ( isset( $body['valid'] ) && $body['valid'] === true );124 $valid = isset( $body['valid'] ) && $body['valid'] === true; 114 125 115 126 update_option( 'wpraiz_license_status', $valid ? 'active' : 'invalid' ); 116 127 update_option( 'wpraiz_license_last_check', time() ); 128 129 if ( ! empty( $body['expires_at'] ) ) { 130 update_option( 'wpraiz_license_expires_at', $body['expires_at'] ); 131 } 117 132 } 118 133 … … 126 141 127 142 private function remote_activate( string $key ) { 128 $response = wp_remote_post( self:: LS_ACTIVATE, [143 $response = wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/activate', [ 129 144 'timeout' => 15, 130 'body' => [ 131 'license_key' => $key, 132 'instance_name' => parse_url( get_site_url(), PHP_URL_HOST ), 133 ], 145 'headers' => [ 'Content-Type' => 'application/json' ], 146 'body' => wp_json_encode( [ 147 'license_key' => $key, 148 'site_url' => get_site_url(), 149 ] ), 134 150 ] ); 135 151 … … 141 157 $body = json_decode( wp_remote_retrieve_body( $response ), true ); 142 158 143 // 200 or 201 = activated 144 if ( in_array( $code, [ 200, 201 ], true ) && ! empty( $body['activated'] ) ) { 159 if ( $code === 200 && ! empty( $body['activated'] ) ) { 145 160 update_option( 'wpraiz_license_key', $key ); 146 161 update_option( 'wpraiz_license_status', 'active' ); 147 update_option( 'wpraiz_license_instance_id', $body['instance']['id'] ?? '' );148 162 update_option( 'wpraiz_license_activated_at', time() ); 149 update_option( 'wpraiz_license_expires_at', $body[' license_key']['expires_at'] ?? '' );163 update_option( 'wpraiz_license_expires_at', $body['expires_at'] ?? '' ); 150 164 update_option( 'wpraiz_license_last_check', time() ); 165 166 // Cleanup legacy LemonSqueezy option 167 delete_option( 'wpraiz_license_instance_id' ); 151 168 152 169 return $body; 153 170 } 154 171 155 // Already activated on this instance 156 if ( $code === 400 && str_contains( $body['error'] ?? '', 'already' ) ) { 157 update_option( 'wpraiz_license_key', $key ); 158 update_option( 'wpraiz_license_status', 'active' ); 159 update_option( 'wpraiz_license_last_check', time() ); 160 return $body; 161 } 162 163 $msg = $body['message'] ?? $body['error'] ?? 'Invalid or expired license key.'; 172 $msg = $body['error'] ?? $body['message'] ?? 'Invalid or expired license key.'; 164 173 return new \WP_Error( 'ls_invalid', $msg ); 165 174 } -
wpraiz-content-api-tool/tags/2.0.2/readme.txt
r3484578 r3484580 5 5 Tested up to: 6.7 6 6 Requires PHP: 7.4 7 Stable tag: 2.0. 17 Stable tag: 2.0.2 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 148 148 149 149 == Changelog == 150 151 = 2.0.2 = 152 * Fix: License client agora aponta para license server self-hosted (wpraiz.com.br/Hotmart) em vez de LemonSqueezy 153 * Cleanup: Removidas referências a api.lemonsqueezy.com 154 * Add: URL do license server filtrável via 'wpraiz_license_server_url' 150 155 151 156 = 2.0.1 = -
wpraiz-content-api-tool/tags/2.0.2/wpraiz-content.php
r3484578 r3484580 4 4 * Plugin URI: https://wpraiz.com.br 5 5 * Description: Create WordPress posts via REST API with SEO integration, AI content generation, and MCP server for AI agents. 6 * Version: 2.0. 16 * Version: 2.0.2 7 7 * Author: José Ícaro – WPRaiz 8 8 * Author URI: https://wpraiz.com.br … … 21 21 22 22 // Plugin constants 23 define( 'WPRAIZ_VERSION', '2.0. 1' );23 define( 'WPRAIZ_VERSION', '2.0.2' ); 24 24 define( 'WPRAIZ_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 25 25 define( 'WPRAIZ_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); -
wpraiz-content-api-tool/trunk/includes/admin/class-license.php
r3482396 r3484580 5 5 6 6 /** 7 * License management via LemonSqueezy Licensing API.7 * License management via WPRaiz self-hosted license server. 8 8 * 9 * LemonSqueezy exposes public endpoints — no store API key needed in the plugin. 10 * The plugin only holds the customer's license key. 9 * The license server runs on wpraiz.com.br (class-license-server.php). 10 * Flow: 11 * 1. Buyer purchases on Hotmart 12 * 2. Hotmart webhook → license server generates key → emails buyer 13 * 3. Buyer enters key here → plugin calls wpraiz.com.br to activate 14 * 4. Background re-validation daily 11 15 * 12 * Endpoints used:13 * POST https://api.lemonsqueezy.com/v1/licenses/activate14 * POST https://api.lemonsqueezy.com/v1/licenses/validate15 * POST https://api.lemonsqueezy.com/v1/licenses/deactivate16 * Endpoints (on WPRAIZ_LICENSE_SERVER_URL): 17 * POST /wpraiz/v2/license/activate 18 * POST /wpraiz/v2/license/validate 19 * POST /wpraiz/v2/license/deactivate 16 20 */ 17 21 class License { 18 22 19 const LS_ACTIVATE = 'https://api.lemonsqueezy.com/v1/licenses/activate'; 20 const LS_VALIDATE = 'https://api.lemonsqueezy.com/v1/licenses/validate'; 21 const LS_DEACTIVATE = 'https://api.lemonsqueezy.com/v1/licenses/deactivate'; 23 /** License server base URL. Filterable via 'wpraiz_license_server_url'. */ 24 const DEFAULT_SERVER = 'https://wpraiz.com.br'; 22 25 23 26 /** How often to re-validate remotely (seconds). Default: 24h. */ … … 33 36 wp_schedule_event( time(), 'daily', 'wpraiz_revalidate_license' ); 34 37 } 38 } 39 40 /** 41 * Get license server URL (filterable). 42 */ 43 private static function server_url(): string { 44 return apply_filters( 'wpraiz_license_server_url', self::DEFAULT_SERVER ); 35 45 } 36 46 … … 68 78 } 69 79 70 $key = get_option( 'wpraiz_license_key', '' ); 71 $instance_id = get_option( 'wpraiz_license_instance_id', '' ); 80 $key = get_option( 'wpraiz_license_key', '' ); 72 81 73 if ( $key && $instance_id) {74 wp_remote_post( self:: LS_DEACTIVATE, [82 if ( $key ) { 83 wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/deactivate', [ 75 84 'timeout' => 15, 76 'body' => [ 85 'headers' => [ 'Content-Type' => 'application/json' ], 86 'body' => wp_json_encode( [ 77 87 'license_key' => $key, 78 ' instance_id' => $instance_id,79 ] ,88 'site_url' => get_site_url(), 89 ] ), 80 90 ] ); 81 91 } … … 83 93 delete_option( 'wpraiz_license_key' ); 84 94 delete_option( 'wpraiz_license_status' ); 85 delete_option( 'wpraiz_license_instance_id' );86 95 delete_option( 'wpraiz_license_activated_at' ); 87 96 delete_option( 'wpraiz_license_expires_at' ); 88 97 delete_option( 'wpraiz_license_last_check' ); 98 99 // Cleanup legacy LemonSqueezy option 100 delete_option( 'wpraiz_license_instance_id' ); 89 101 90 102 wp_send_json_success( [ 'message' => 'License deactivated.' ] ); … … 94 106 95 107 public function revalidate() { 96 $key = get_option( 'wpraiz_license_key', '' );97 $instance_id = get_option( 'wpraiz_license_instance_id', '' );108 $key = get_option( 'wpraiz_license_key', '' ); 109 if ( ! $key ) return; 98 110 99 if ( ! $key || ! $instance_id ) return; 100 101 $response = wp_remote_post( self::LS_VALIDATE, [ 111 $response = wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/validate', [ 102 112 'timeout' => 15, 103 'body' => [ 113 'headers' => [ 'Content-Type' => 'application/json' ], 114 'body' => wp_json_encode( [ 104 115 'license_key' => $key, 105 ' instance_id' => $instance_id,106 ] ,116 'site_url' => get_site_url(), 117 ] ), 107 118 ] ); 108 119 … … 111 122 $body = json_decode( wp_remote_retrieve_body( $response ), true ); 112 123 113 $valid = ! empty( $body['activated'] ) || ( isset( $body['valid'] ) && $body['valid'] === true );124 $valid = isset( $body['valid'] ) && $body['valid'] === true; 114 125 115 126 update_option( 'wpraiz_license_status', $valid ? 'active' : 'invalid' ); 116 127 update_option( 'wpraiz_license_last_check', time() ); 128 129 if ( ! empty( $body['expires_at'] ) ) { 130 update_option( 'wpraiz_license_expires_at', $body['expires_at'] ); 131 } 117 132 } 118 133 … … 126 141 127 142 private function remote_activate( string $key ) { 128 $response = wp_remote_post( self:: LS_ACTIVATE, [143 $response = wp_remote_post( self::server_url() . '/wp-json/wpraiz/v2/license/activate', [ 129 144 'timeout' => 15, 130 'body' => [ 131 'license_key' => $key, 132 'instance_name' => parse_url( get_site_url(), PHP_URL_HOST ), 133 ], 145 'headers' => [ 'Content-Type' => 'application/json' ], 146 'body' => wp_json_encode( [ 147 'license_key' => $key, 148 'site_url' => get_site_url(), 149 ] ), 134 150 ] ); 135 151 … … 141 157 $body = json_decode( wp_remote_retrieve_body( $response ), true ); 142 158 143 // 200 or 201 = activated 144 if ( in_array( $code, [ 200, 201 ], true ) && ! empty( $body['activated'] ) ) { 159 if ( $code === 200 && ! empty( $body['activated'] ) ) { 145 160 update_option( 'wpraiz_license_key', $key ); 146 161 update_option( 'wpraiz_license_status', 'active' ); 147 update_option( 'wpraiz_license_instance_id', $body['instance']['id'] ?? '' );148 162 update_option( 'wpraiz_license_activated_at', time() ); 149 update_option( 'wpraiz_license_expires_at', $body[' license_key']['expires_at'] ?? '' );163 update_option( 'wpraiz_license_expires_at', $body['expires_at'] ?? '' ); 150 164 update_option( 'wpraiz_license_last_check', time() ); 165 166 // Cleanup legacy LemonSqueezy option 167 delete_option( 'wpraiz_license_instance_id' ); 151 168 152 169 return $body; 153 170 } 154 171 155 // Already activated on this instance 156 if ( $code === 400 && str_contains( $body['error'] ?? '', 'already' ) ) { 157 update_option( 'wpraiz_license_key', $key ); 158 update_option( 'wpraiz_license_status', 'active' ); 159 update_option( 'wpraiz_license_last_check', time() ); 160 return $body; 161 } 162 163 $msg = $body['message'] ?? $body['error'] ?? 'Invalid or expired license key.'; 172 $msg = $body['error'] ?? $body['message'] ?? 'Invalid or expired license key.'; 164 173 return new \WP_Error( 'ls_invalid', $msg ); 165 174 } -
wpraiz-content-api-tool/trunk/readme.txt
r3484578 r3484580 5 5 Tested up to: 6.7 6 6 Requires PHP: 7.4 7 Stable tag: 2.0. 17 Stable tag: 2.0.2 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 148 148 149 149 == Changelog == 150 151 = 2.0.2 = 152 * Fix: License client agora aponta para license server self-hosted (wpraiz.com.br/Hotmart) em vez de LemonSqueezy 153 * Cleanup: Removidas referências a api.lemonsqueezy.com 154 * Add: URL do license server filtrável via 'wpraiz_license_server_url' 150 155 151 156 = 2.0.1 = -
wpraiz-content-api-tool/trunk/wpraiz-content.php
r3484578 r3484580 4 4 * Plugin URI: https://wpraiz.com.br 5 5 * Description: Create WordPress posts via REST API with SEO integration, AI content generation, and MCP server for AI agents. 6 * Version: 2.0. 16 * Version: 2.0.2 7 7 * Author: José Ícaro – WPRaiz 8 8 * Author URI: https://wpraiz.com.br … … 21 21 22 22 // Plugin constants 23 define( 'WPRAIZ_VERSION', '2.0. 1' );23 define( 'WPRAIZ_VERSION', '2.0.2' ); 24 24 define( 'WPRAIZ_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 25 25 define( 'WPRAIZ_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
Note: See TracChangeset
for help on using the changeset viewer.