Changeset 3380444
- Timestamp:
- 10/18/2025 09:12:47 AM (3 months ago)
- Location:
- kotaqx-poster/trunk
- Files:
-
- 7 edited
-
Readme.txt (modified) (2 diffs)
-
admin/tab-license.php (modified) (5 diffs)
-
admin/tab-repost.php (modified) (1 diff)
-
includes/Ajax.php (modified) (3 diffs)
-
includes/ProInstance.php (modified) (2 diffs)
-
includes/utils.php (modified) (3 diffs)
-
kotaqx-poster.php (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kotaqx-poster/trunk/Readme.txt
r3368850 r3380444 5 5 Tested up to: 6.8 6 6 Requires PHP: 7.2 7 Stable tag: 1.0. 67 Stable tag: 1.0.7 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 105 105 == Changelog == 106 106 107 = 1.0.7 = 108 * Improve: Republish platform handler code and add log event. 109 * Improve: Add plugin version to database, used to migrate plugin settings in future updates. 110 * Improve: License Info UI to provide clearer status display. 111 * Refactor: Internal code restructured for easier maintenance (no changes to functionality). 112 * Fix: Potential double execution on publish→update; added a 60-second cooldown to prevent duplicate reposts when `Repost on Update` is enabled. 113 * Fix: Custom delay of repost scheduling is not accurate. 114 107 115 = 1.0.6 = 108 116 * Update: Add default settings if not present. -
kotaqx-poster/trunk/admin/tab-license.php
r3364882 r3380444 12 12 $license_key = isset($license_data['key']) ? Utils::censor_string($license_data['key'], true) : ''; 13 13 $license_status = isset($license_data['status']) ? $license_data['status'] : ''; 14 $license_exp = isset($license_data['exp']) ? $license_data['exp']: '';14 $license_exp = isset($license_data['exp']) ? trim((string) $license_data['exp']) : ''; 15 15 16 $is_valid = $license_status === 'valid'; 16 $is_valid = ($license_status === 'valid'); 17 $now_ts = time(); 18 $is_lifetime = (strtolower((string)$license_exp) === 'lifetime'); 19 $exp_dt = (!$is_lifetime && !empty($license_exp)) 20 ? DateTimeImmutable::createFromFormat('Y-m-d H:i:s', $license_exp, new DateTimeZone('UTC')) 21 : null; 17 22 18 $button_text = $is_valid ? 'Deactivate' : 'Activate'; 19 $button_icon = $is_valid ? 'dashicons-no-alt' : 'dashicons-yes-alt'; 20 $button_class = $is_valid ? 'is-danger' : 'is-primary'; 21 $button_name = $is_valid ? 'deactivate_license' : 'activate_license'; 23 $exp_ts = $exp_dt ? $exp_dt->getTimestamp() : false; 24 $is_expired = (!$is_lifetime && $exp_ts) ? ($exp_ts <= $now_ts) : false; 25 $expired_label = $exp_dt ? $exp_dt->format('Y-m-d H:i:s') : '—'; 26 27 // Final effective state: valid-but-expired should be treated as expired/inactive in UI 28 $effective_valid = $is_valid && !$is_expired; 29 30 $button_text = $effective_valid ? 'Deactivate' : 'Activate'; 31 $button_icon = $effective_valid ? 'dashicons-no-alt' : 'dashicons-yes-alt'; 32 $button_class = $effective_valid ? 'is-danger' : 'is-primary'; 33 $button_name = $effective_valid ? 'deactivate_license' : 'activate_license'; 34 35 // Status chip data 36 if ($is_lifetime) { 37 $status_label = 'Lifetime'; 38 $status_icon = 'dashicons-infinity'; 39 $status_class = 'tag is-success is-light'; 40 } elseif ($is_expired) { 41 $status_label = 'Expired'; 42 $status_icon = 'dashicons-dismiss'; 43 $status_class = 'tag is-danger'; 44 } elseif ($exp_ts) { 45 $status_label = 'Active'; 46 $status_icon = 'dashicons-yes'; 47 $status_class = 'tag is-success'; 48 } else { 49 $status_label = $effective_valid ? 'Active' : 'Inactive'; 50 $status_icon = $effective_valid ? 'dashicons-yes' : 'dashicons-clock'; 51 $status_class = $effective_valid ? 'tag is-success' : 'tag is-warning is-light'; 52 } 53 54 // Expiration display text 55 $exp_display = ''; 56 if ($is_lifetime) { 57 $exp_display = 'Never (lifetime)'; 58 } elseif ($exp_ts) { 59 $exp_display = sprintf( 60 '%s (on %s)', 61 $is_expired 62 ? 'Expired' 63 : 'Expires', 64 esc_html( $expired_label ) 65 ); 66 } 67 68 // Remaining time (human) when still active and not lifetime 69 $human_left = (!$is_lifetime && $exp_ts && !$is_expired) 70 ? human_time_diff($now_ts, $exp_ts) 71 : ''; 22 72 ?> 23 73 … … 27 77 <div class="card"> 28 78 <header class="card-header"> 29 <p class="card-header-title is-size-5 is-flex is- align-items-center is-justify-content-center has-text-warning">79 <p class="card-header-title is-size-5 is-flex is-justify-content-center"> 30 80 <span class="dashicons dashicons-admin-network" style="margin-right: 8px;"></span> 31 81 License Activation 32 82 </p> 33 83 </header> 84 85 <?php if ($is_expired): ?> 86 <div class="notification is-danger m-4"> 87 <p class="is-flex is-align-items-center mb-1"> 88 <span class="dashicons dashicons-warning" style="margin-right:8px"></span> 89 <strong>Your license has expired.</strong> 90 </p> 91 <p>Click the button below to renew your license.</p> 92 <a class="button mt-5 is-warning is-flex is-align-items-center" href="https://kotakdigital.com/my-account/" target="_blank"> 93 <span class="dashicons dashicons-admin-network" style="margin-right:6px"></span> 94 Renew / Manage License 95 </a> 96 </div> 97 <?php endif; ?> 34 98 35 99 <div class="card-content"> … … 40 104 id="license_key" 41 105 name="license_key" 42 class="input "106 class="input <?php echo $is_expired ? 'is-danger' : ''; ?>" 43 107 placeholder="Enter your license key" 44 108 value="<?php echo esc_attr($license_key); ?>" 45 <?php echo esc_attr($ license_status? 'disabled' : ''); ?>109 <?php echo esc_attr($effective_valid ? 'disabled' : ''); ?> 46 110 > 47 111 <span class="icon is-left"> … … 54 118 </div> 55 119 56 <div class="field is-grouped is-grouped-centered mt-4"> 120 <?php if (!$is_lifetime): ?> 121 <div class="field is-grouped is-grouped-multiline"> 122 <?php if ($exp_ts): ?> 123 <div class="control"> 124 <div class="tags has-addons"> 125 <span class="tag is-dark">Status</span> 126 <span class="tag <?php echo $is_expired ? 'is-danger' : 'is-success'; ?>"><?php echo $is_expired ? 'Expired' : 'Active'; ?></span> 127 </div> 128 </div> 129 <div class="control"> 130 <div class="tags has-addons"> 131 <span class="tag is-dark">Expiry</span> 132 <span class="tag is-info"><?php echo esc_html($expired_label); ?></span> 133 </div> 134 </div> 135 <?php if ($human_left && !$is_expired): ?> 136 <div class="control"> 137 <div class="tags has-addons"> 138 <span class="tag is-dark">Time left</span> 139 <span class="tag is-warning"><?php echo esc_html($human_left); ?></span> 140 </div> 141 </div> 142 <?php endif; ?> 143 <?php endif; ?> 144 </div> 145 <?php else: ?> 146 <div class="field is-grouped is-grouped-multiline"> 147 <div class="control"> 148 <div class="tags has-addons"> 149 <span class="tag is-dark">Status</span> 150 <span class="tag is-success">Active</span> 151 </div> 152 </div> 153 <div class="control"> 154 <div class="tags has-addons"> 155 <span class="tag is-dark">Expiry</span> 156 <span class="tag is-info">Lifetime</span> 157 </div> 158 </div> 159 </div> 160 <?php endif; ?> 161 162 <div class="field is-grouped is-grouped-centered mt-5"> 57 163 <div class="control"> 58 164 <button id="license-submit-btn" 59 165 class="button <?php echo esc_attr($button_class); ?>" 166 name="<?php echo esc_attr($button_name); ?>" 60 167 data-action="<?php echo esc_html(strtolower($button_text)); ?>" 61 168 data-nonce="<?php echo wp_create_nonce('kotaqx_poster_handle_license'); ?>"> … … 67 174 </div> 68 175 69 <?php if ( $license_status): ?>176 <?php if (! $effective_valid): ?> 70 177 <footer class="card-footer"> 71 <div class="card-footer-item has-text-success">72 <span class="dashicons dashicons-yes" style="margin-right: 6px;"></span>73 License isactive74 </div>178 <div class="card-footer-item has-text-warning"> 179 <span class="dashicons dashicons-clock" style="margin-right: 6px;"></span> 180 License is inactive 181 </div> 75 182 </footer> 76 183 <?php endif; ?> 184 77 185 </div> 78 186 </div> -
kotaqx-poster/trunk/admin/tab-repost.php
r3364882 r3380444 251 251 </div> 252 252 </label> 253 <p class="help">Repost content when a published post is updated (published → save). </p>253 <p class="help">Repost content when a published post is updated (published → save). 60-second cooldown to prevents duplicates.</p> 254 254 </div> 255 255 </div> -
kotaqx-poster/trunk/includes/Ajax.php
r3351682 r3380444 12 12 13 13 class Ajax { 14 const LOGS = KOTAQX_POSTER_NAME . '_logs'; 15 14 16 private $functions; 15 17 private $kotaqx_poster; … … 155 157 156 158 global $wpdb; 157 $table_name = $wpdb->prefix . 'kotaqx_poster_logs';159 $table_name = $wpdb->prefix . self::LOGS; 158 160 159 161 if ( ! preg_match('/^[A-Za-z0-9_]+$/', $table_name) ) { … … 192 194 193 195 global $wpdb; 194 $table_name = $wpdb->prefix . 'kotaqx_poster_logs';196 $table_name = $wpdb->prefix . self::LOGS; 195 197 196 198 if ( ! preg_match('/^[A-Za-z0-9_]+$/', $table_name) ) { -
kotaqx-poster/trunk/includes/ProInstance.php
r3351682 r3380444 20 20 */ 21 21 public static function get() { 22 if (self::$instance === null) { 23 if (class_exists('\KotakDigital\PosterPro\Kotaqx_Poster_Pro')) { 24 self::$instance = new \KotakDigital\PosterPro\Kotaqx_Poster_Pro(); 25 } 22 if (self::$instance === null && class_exists('\KotakDigital\PosterPro\Kotaqx_Poster_Pro')) { 23 self::$instance = \KotakDigital\PosterPro\Kotaqx_Poster_Pro::instance(); 26 24 } 27 25 return self::$instance; … … 33 31 */ 34 32 public static function is_active() { 35 $transient = get_transient( 'kotaqx_poster_pro_active');33 $transient = get_transient(KOTAQX_POSTER_NAME . '_pro_active'); 36 34 37 35 if ($transient === true) { -
kotaqx-poster/trunk/includes/utils.php
r3368850 r3380444 5 5 6 6 class Utils { 7 // Option name for storing settings 8 const SETTINGS = 'kotaqx_poster_settings'; 7 // Option name for storing settings 8 const SETTINGS = KOTAQX_POSTER_NAME . '_settings'; 9 const LOGS = KOTAQX_POSTER_NAME . '_logs'; 9 10 10 11 // Load settings from the database … … 53 54 ) { 54 55 global $wpdb; 55 $table_name = $wpdb->prefix . 'kotaqx_poster_logs';56 $table_name = $wpdb->prefix . self::LOGS; 56 57 57 58 if ( ! preg_match('/^[A-Za-z0-9_]+$/', $table_name) ) { … … 136 137 public static function get_logs($limit = 25, $offset = 0) { 137 138 global $wpdb; 138 $table_name = $wpdb->prefix . 'kotaqx_poster_logs';139 $table_name = $wpdb->prefix . self::LOGS; 139 140 140 141 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Prepared, Sanitized, & no cache needed -
kotaqx-poster/trunk/kotaqx-poster.php
r3368850 r3380444 5 5 * Plugin URI: https://kotakdigital.com/downloads/kotaqx-poster/ 6 6 * Description: Automatically recover missed schedule posts, and share published content to other platforms. 7 * Version: 1.0. 67 * Version: 1.0.7 8 8 * Author: Kotak Digital 9 9 * Author URI: https://kotakdigital.com … … 20 20 21 21 if (!defined('KOTAQX_POSTER_VERSION')) { 22 define('KOTAQX_POSTER_VERSION', '1.0. 6');22 define('KOTAQX_POSTER_VERSION', '1.0.7'); 23 23 } 24 24 if (!defined('KOTAQX_POSTER_URL')) { … … 31 31 define('KOTAQX_POSTER_SLUG', 'kotaqx-poster'); 32 32 } 33 if (!defined('KOTAQX_POSTER_NAME')) { 34 define('KOTAQX_POSTER_NAME', 'kotaqx_poster'); 35 } 33 36 if (!defined('KOTAQX_POSTER_SETTING')) { 34 37 define('KOTAQX_POSTER_SETTING', 'kotaqx-poster-settings'); 35 38 } 36 39 37 // Some advanced features are available when Kotaqx Poster PRO is installed.38 // The free version works fine without it.39 // We conditionally check for Pro using defined()/function_exists()/class_exists() before calling anything from Pro.40 // This prevents fatal errors and keeps the free plugin fully functional on its own.41 40 if (!defined('KOTAQX_POSTER_PRO_DIR')) { 42 41 define('KOTAQX_POSTER_PRO_DIR', WP_PLUGIN_DIR . '/kotaqx-poster-pro/'); … … 92 91 } 93 92 93 /** 94 * Load plugin features. 95 */ 94 96 private function load_features() { 95 97 require_once plugin_dir_path(__FILE__) . 'admin/settings.php'; 96 98 } 97 99 100 /** 101 * Enqueue admin assets. 102 * 103 * @param string $hook The current admin page. 104 */ 98 105 public function admin_assets($hook) { 99 106 if ($hook !== 'toplevel_page_' . KOTAQX_POSTER_SETTING) { … … 103 110 wp_enqueue_script( 104 111 'kotaqx-poster-script', 105 plugin_dir_url(__FILE__). '/assets/js/script.min.js',112 KOTAQX_POSTER_URL. '/assets/js/script.min.js', 106 113 ['jquery'], 107 filemtime( plugin_dir_path(__FILE__). 'assets/js/script.min.js'),114 filemtime(KOTAQX_POSTER_DIR . 'assets/js/script.min.js'), 108 115 true 109 116 ); 110 wp_enqueue_script('sweetalert2', plugin_dir_url(__FILE__). '/assets/js/sweetalert2.min.js', ['jquery'], array('jquery'), '11.4.8', true);111 wp_enqueue_style('bulma-css', plugin_dir_url(__FILE__). '/assets/css/bulma.min.css', [], '1.0.4');112 wp_enqueue_style('kotaqx-poster-style', plugin_dir_url(__FILE__). '/assets/css/style.min.css', [], '1.0.0');113 wp_enqueue_style('sweetalert2-css', plugin_dir_url(__FILE__). '/assets/css/sweetalert2.min.css', [], '11.4.8');117 wp_enqueue_script('sweetalert2', KOTAQX_POSTER_URL . '/assets/js/sweetalert2.min.js', ['jquery'], array('jquery'), '11.4.8', true); 118 wp_enqueue_style('bulma-css', KOTAQX_POSTER_URL. '/assets/css/bulma.min.css', [], '1.0.4'); 119 wp_enqueue_style('kotaqx-poster-style', KOTAQX_POSTER_URL . '/assets/css/style.min.css', [], '1.0.0'); 120 wp_enqueue_style('sweetalert2-css', KOTAQX_POSTER_URL . '/assets/css/sweetalert2.min.css', [], '11.4.8'); 114 121 115 122 wp_localize_script('kotaqx-poster-script', 'kotaqx_poster_vars', [ … … 118 125 } 119 126 127 /** 128 * Plugin activation callback. 129 */ 120 130 public function activate() { 121 131 global $wpdb; … … 141 151 } 142 152 153 // Add plugin version 154 if (!get_option('kotaqx_poster_version')) { 155 // Set plugin version 156 // Used to migrate plugin settings in future updates 157 update_option('kotaqx_poster_version', KOTAQX_POSTER_VERSION); 158 } 159 143 160 //Run the cron 144 161 $this->schedule_cron(); 145 162 } 146 163 164 /** 165 * Plugin deactivation callback. 166 */ 147 167 public function deactivate() { 148 168 wp_clear_scheduled_hook('kotaqx_poster_schedule_cron'); 149 169 } 150 170 171 /** 172 * Handle manual trigger via AJAX. 173 */ 151 174 public function manual_trigger() { 152 175 if (!current_user_can('manage_options') || !check_ajax_referer('kotaqx_poster_manual_trigger', 'kotaqx_poster_manual_nonce', false)) { … … 167 190 } 168 191 192 /** 193 * Check and publish missed scheduled posts. 194 * 195 * @return int Number of posts published. 196 */ 169 197 public function check_and_publish_missed_scheduled_posts() { 170 198 global $wpdb; … … 209 237 } 210 238 239 /** 240 * Add custom cron schedules. 241 * 242 * @param array $schedules Existing cron schedules. 243 * @return array Modified cron schedules. 244 */ 211 245 public function add_cron_schedules($schedules) { 212 246 $options = Utils::load_settings(); … … 223 257 } 224 258 259 /** 260 * Schedule the cron event if not already scheduled. 261 */ 225 262 public function schedule_cron() { 226 263 if (!wp_next_scheduled('kotaqx_poster_schedule_cron')) { … … 229 266 } 230 267 268 /** 269 * Handle republishing of posts when their status changes to 'publish'. 270 * 271 * @param string $new_status The new post status. 272 * @param string $old_status The old post status. 273 * @param WP_Post $post The post object. 274 */ 231 275 public function handle_republish_post($new_status, $old_status, $post) { 232 276 if ($new_status !== 'publish') { 233 return; // Only handle when post is published 234 } 277 // Only handle when post is published 278 return; 279 } 280 281 $settings = Utils::load_settings(); 282 $repost_on_update = isset($settings['repost_on_update']) ? $settings['repost_on_update'] : false; 283 $is_update = ($old_status === 'publish' && $new_status === 'publish'); 284 285 // Recheck for post status 286 if ($is_update && !$repost_on_update) return; 235 287 236 288 $ID = $post->ID; … … 238 290 239 291 if (get_transient($lock_key)) { 240 return; // Skip if already locked 292 // Skip if already locked 293 return; 241 294 } 242 295 … … 244 297 set_transient($lock_key, true, 15); 245 298 246 if (!wp_next_scheduled('kotaqx_poster_do_republish_event', [$ID ])) {299 if (!wp_next_scheduled('kotaqx_poster_do_republish_event', [$ID, $new_status, $old_status])) { 247 300 // Schedule the event to run 248 $settings = Utils::load_settings();249 301 $repost_delay = isset($settings['schedule_repost_interval']) ? $settings['schedule_repost_interval'] : '0'; // Default to 'immediately' 302 $delay_seconds = 0; 250 303 251 304 if ($repost_delay === 'custom') { 252 $ custom_delay_value= isset($settings['schedule_repost_custom_delay_value']) ? intval($settings['schedule_repost_custom_delay_value']) : 1;253 $ custom_delay_unit = isset($settings['schedule_repost_custom_delay_unit']) ? $settings['schedule_repost_custom_delay_unit'] : 'minutes';305 $val = isset($settings['schedule_repost_custom_delay_value']) ? intval($settings['schedule_repost_custom_delay_value']) : 1; 306 $unit = isset($settings['schedule_repost_custom_delay_unit']) ? $settings['schedule_repost_custom_delay_unit'] : 'minutes'; 254 307 255 308 // Convert custom delay to seconds 256 switch ($custom_delay_unit) { 309 switch ($unit) { 310 case 'minute': 257 311 case 'minutes': 258 $ repost_delay = $custom_delay_value* 60;312 $delay_seconds = $val * 60; 259 313 break; 314 case 'hour': 260 315 case 'hours': 261 $ repost_delay = $custom_delay_value* 3600;316 $delay_seconds = $val * 3600; 262 317 break; 318 case 'day': 263 319 case 'days': 264 $ repost_delay = $custom_delay_value* 86400;320 $delay_seconds = $val * 86400; 265 321 break; 266 322 default: 267 $ repost_delay = 0; // Fallback to immediateif unit is invalid323 $delay_seconds = 0; // Fallback to 'immediately' if unit is invalid 268 324 break; 269 325 } 270 } 271 272 $repost_delay = intval($repost_delay);326 } else { 327 $delay_seconds = max(0, intval($repost_delay)) * 60; 328 } 273 329 274 330 // Schedule with a delay 5s to ensure the post is fully saved 275 wp_schedule_single_event(time() + ($repost_delay * 60) + 5, 'kotaqx_poster_do_republish_event', [$ID]); 276 } 277 } 278 279 public function do_republish_event($ID) { 331 wp_schedule_single_event(time() + $delay_seconds + 5, 'kotaqx_poster_do_republish_event', [$ID, $new_status, $old_status]); 332 } 333 } 334 335 /** 336 * Execute the republishing event for a given post ID. 337 * 338 * @param int $ID The post ID. 339 */ 340 public function do_republish_event($ID, $new_status = null, $old_status = null) { 341 // Cooldown to prevent double execution 342 $run_lock = 'kotaqx_poster_republish_run_' . $ID; 343 if (get_transient($run_lock)) return; 344 set_transient($run_lock, 1, 60); //60s cooldown 345 280 346 $settings = Utils::load_settings(); 281 347 $post = get_post($ID); 282 283 348 if (!$post) return; 349 350 $repost_on_update = !empty($settings['repost_on_update']); 351 $repost_on_republish = !empty($settings['repost_on_republish']); 352 353 $is_publish_transition = ($new_status === 'publish'); 354 $was_published = ($old_status === 'publish'); 355 $is_update = ($is_publish_transition && $was_published); // publish -> publish 356 $is_republish = ($is_publish_transition && !$was_published); // non-publish -> publish 357 358 // If there is no new status, use the post_date check as a fallback: 359 if ($new_status === null) { 360 $is_update = ($post->post_modified !== $post->post_date); 361 $is_republish = !$is_update && ($post->post_status === 'publish'); 362 } 284 363 285 364 foreach ($this->platforms as $platform) { … … 287 366 $post_types = $settings[$platform . '_post_type'] ?? []; 288 367 289 // Skip if the channelis not active or the post_type does not match368 // Skip if the platform is not active or the post_type does not match 290 369 if (!$enabled || !in_array($post->post_type, (array) $post_types)) { 291 370 continue; … … 293 372 294 373 $post_meta_key = "_{$platform}_post_sent"; 295 $post_sent = get_post_meta($ID, $post_meta_key, true); 296 297 $repost_on_update = !empty($settings['repost_on_update']); 298 $repost_on_republish = !empty($settings['repost_on_republish']); 299 300 // If update, only resend if allowed 301 if ($post_sent && !$repost_on_update && $post->post_modified !== $post->post_date) { 374 $raw_meta = get_post_meta($ID, $post_meta_key, true); 375 $post_sent = ($raw_meta === '1' || $raw_meta === 1 || $raw_meta === true); 376 377 // 1) If this is an UPDATE and the setting is off -> DO NOT send even if the meta doesn't exist yet 378 if ($is_update && !$repost_on_update) { 379 Utils::log_event(false, $ID, "[{$platform}] Error 1."); 302 380 continue; 303 381 } 304 382 305 // If republish (draft > publish), reset post_sent to allow resending 306 if ($post_sent && $repost_on_republish && $post->post_status === 'publish') { 383 // 2) If this is REPUBLISH and setting off -> DO NOT send even if meta does not exist 384 if ($is_republish && !$repost_on_republish) { 385 Utils::log_event(false, $ID, "[{$platform}] Error 2."); 386 continue; 387 } 388 389 // 3) If reupdate is allowed and has already been sent, reset the flag to allow sending again. 390 if ($is_update && $repost_on_update && $post_sent) { 307 391 update_post_meta($ID, $post_meta_key, false); 308 392 } 309 393 310 // Send to channel 394 // 4) If republishing is allowed and has already been sent, reset the flag to allow sending again. 395 if ($is_republish && $repost_on_republish && $post_sent) { 396 update_post_meta($ID, $post_meta_key, false); 397 } 398 399 // Reposting 311 400 Handler::repost_to($platform, $ID); 312 401 } 313 402 } 314 403 404 /** 405 * Handle republishing by the scheduled event for specific platform republishing. 406 * Currently used by Threads platform only. 407 * 408 * @param string $platform The platform identifier. 409 * @param array $data Data related to the post to be republished. 410 */ 315 411 public static function handle_republish_platform($platform, $data) { 316 $map = Handler::get_platform_map(); 412 // Get platforms class map 413 $map = Handler::get_platform_map(); 414 415 // Platform label and ID 416 $platform_label = ucfirst(sanitize_key($platform)); 417 $ID = isset($data['ID']) ? (int) $data['ID'] : 0; 317 418 318 419 if (!isset($map[$platform])) { 319 //Platform handler not found 420 // Platform handler not found 421 // Platform map not defined or platform name invalid 422 Utils::log_event(false, $ID, "[{$platform_label}] Handler not found."); 320 423 return; 321 424 } 322 425 426 // Get current platform class 323 427 $class = $map[$platform]; 324 428 325 429 if (!class_exists($class)) { 326 //Class $class not loaded 430 // Class $class not loaded 431 // Platform class is invalid 432 Utils::log_event(false, $ID, "[{$platform_label}] Class not loaded."); 327 433 return; 328 434 } … … 336 442 } 337 443 444 /** 445 * Show admin notice if any platform token is expiring soon. 446 */ 338 447 public function maybe_show_token_expiry_notice() { 339 448 if (!current_user_can('manage_options')) return; … … 361 470 } 362 471 472 /** 473 * Send email notification if any platform token is expiring soon. 474 */ 363 475 public function maybe_send_token_expiry_email() { 364 476 $settings = Utils::load_settings();
Note: See TracChangeset
for help on using the changeset viewer.