Changeset 3481905
- Timestamp:
- 03/13/2026 10:51:51 AM (3 weeks ago)
- Location:
- natural-text-to-speech/trunk
- Files:
-
- 7 added
- 7 deleted
- 9 edited
-
components/config.php (modified) (5 diffs)
-
components/implement-plugin.php (modified) (1 diff)
-
components/rest/podcast/bootstrap.php (modified) (4 diffs)
-
components/rest/podcast/generation.php (modified) (6 diffs)
-
components/rest/podcast/queue.php (modified) (1 diff)
-
components/rest/tts.php (modified) (3 diffs)
-
constants.php (modified) (1 diff)
-
natural-text-to-speech.php (modified) (3 diffs)
-
public/js/ntts-admin-v2.6.7-main.js (deleted)
-
public/js/ntts-admin-v2.6.7-vendor.js (deleted)
-
public/js/ntts-admin-v2.6.8-main.js (added)
-
public/js/ntts-admin-v2.6.8-vendor.js (added)
-
public/js/ntts-public-v2.6.7-main.js (deleted)
-
public/js/ntts-public-v2.6.7-vendor.js (deleted)
-
public/js/ntts-public-v2.6.8-main.js (added)
-
public/js/ntts-public-v2.6.8-vendor.js (added)
-
public/js/nttsa-18bf2853.js (added)
-
public/js/nttsa-4540ed88.js (added)
-
public/js/nttsa-62c495e8.js (deleted)
-
public/js/nttsa-d05ebe13.js (added)
-
public/js/nttsa-e5c3a17b.js (deleted)
-
public/js/nttsa-e8849ac2.js (deleted)
-
readme.txt (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
natural-text-to-speech/trunk/components/config.php
r3481657 r3481905 22 22 $data = get_option( NATUTETO_KV_STORAGE, NATUTETO_DEFAULT_CONFIG ); 23 23 24 if ( isset( $data['podcasts'] ) && is_array( $data['podcasts'] ) && ! empty( $data['podcasts'] ) ) { 25 $data['podcasts'] = array_values( 26 array_map( 27 function ( $feed_index, $feed ) { 28 return natuteto_sanitize_podcast_feed_settings( $feed, $feed_index ); 29 }, 30 array_keys( $data['podcasts'] ), 31 $data['podcasts'] 32 ) 33 ); 34 } else { 35 $legacy_podcast = natuteto_get_legacy_podcast_feed_settings( $data ); 36 if ( null !== $legacy_podcast ) { 37 $data['podcasts'] = array( $legacy_podcast ); 38 } 39 } 40 24 41 foreach ( $except as $key => $value ) { 25 42 unset( $data[ $value ] ); … … 36 53 37 54 /** 55 * Normalize a background check frequency from new or legacy values. 56 * 57 * @param mixed $frequency Raw frequency. 58 * @param string $fallback Fallback frequency. 59 * @return string 60 */ 61 function natuteto_normalize_podcast_background_check_frequency( $frequency, $fallback = 'daily' ) { 62 $frequency = sanitize_text_field( (string) $frequency ); 63 64 if ( in_array( $frequency, array( 'daily', 'weekly', 'monthly' ), true ) ) { 65 return $frequency; 66 } 67 68 if ( in_array( $frequency, array( 'every_15_minutes', 'hourly', 'twicedaily' ), true ) ) { 69 return 'daily'; 70 } 71 72 return in_array( $fallback, array( 'daily', 'weekly', 'monthly' ), true ) ? $fallback : 'daily'; 73 } 74 75 /** 76 * Normalize podcast generation flags from new or legacy fields. 77 * 78 * @param array $feed Raw feed config. 79 * @param array $defaults Podcast defaults. 80 * @return array 81 */ 82 function natuteto_normalize_podcast_feed_generation_settings( $feed, $defaults ) { 83 $feed = is_array( $feed ) ? $feed : array(); 84 $legacy = isset( $feed['generation_mode'] ) ? sanitize_text_field( (string) $feed['generation_mode'] ) : 'publish'; 85 86 $generate_on_publish = array_key_exists( 'generate_on_publish', $feed ) 87 ? rest_sanitize_boolean( $feed['generate_on_publish'] ) 88 : 'publish' === $legacy; 89 $regenerate_on_modify = array_key_exists( 'regenerate_on_modify', $feed ) 90 ? rest_sanitize_boolean( $feed['regenerate_on_modify'] ) 91 : $defaults['regenerate_on_modify']; 92 $background_check_enabled = array_key_exists( 'background_check_enabled', $feed ) 93 ? rest_sanitize_boolean( $feed['background_check_enabled'] ) 94 : 'schedule' === $legacy; 95 $background_check_frequency = natuteto_normalize_podcast_background_check_frequency( 96 $feed['background_check_frequency'] ?? ( $feed['scan_frequency'] ?? $defaults['background_check_frequency'] ), 97 $defaults['background_check_frequency'] 98 ); 99 100 return array( 101 'generate_on_publish' => $generate_on_publish, 102 'regenerate_on_modify' => $regenerate_on_modify, 103 'background_check_enabled' => $background_check_enabled, 104 'background_check_frequency' => $background_check_frequency, 105 ); 106 } 107 108 /** 109 * Build a normalized podcast feed from legacy top-level config keys. 110 * 111 * @param array $config Raw plugin config. 112 * @return array|null 113 */ 114 function natuteto_get_legacy_podcast_feed_settings( $config ) { 115 $config = is_array( $config ) ? $config : array(); 116 $legacy_keys = array( 117 'podcast_enabled', 118 'podcast_feed_slug', 119 'podcast_title', 120 'podcast_description', 121 'podcast_author', 122 'podcast_owner_name', 123 'podcast_owner_email', 124 'podcast_copyright', 125 'podcast_image_url', 126 'podcast_language', 127 'podcast_explicit', 128 'podcast_post_types', 129 'podcast_category_slugs', 130 'podcast_generation_mode', 131 'podcast_scan_frequency', 132 ); 133 $has_feed = false; 134 135 foreach ( $legacy_keys as $legacy_key ) { 136 if ( array_key_exists( $legacy_key, $config ) ) { 137 $has_feed = true; 138 break; 139 } 140 } 141 142 if ( ! $has_feed ) { 143 return null; 144 } 145 146 return natuteto_sanitize_podcast_feed_settings( 147 array( 148 'enabled' => $config['podcast_enabled'] ?? false, 149 'feed_slug' => $config['podcast_feed_slug'] ?? 'podcast', 150 'title' => $config['podcast_title'] ?? '', 151 'description' => $config['podcast_description'] ?? '', 152 'author' => $config['podcast_author'] ?? '', 153 'owner_name' => $config['podcast_owner_name'] ?? '', 154 'owner_email' => $config['podcast_owner_email'] ?? '', 155 'copyright' => $config['podcast_copyright'] ?? '', 156 'image_url' => $config['podcast_image_url'] ?? '', 157 'language' => $config['podcast_language'] ?? 'en-US', 158 'explicit' => $config['podcast_explicit'] ?? 'no', 159 'post_types' => $config['podcast_post_types'] ?? array( 'post' ), 160 'category_slugs' => $config['podcast_category_slugs'] ?? array(), 161 'generation_mode' => $config['podcast_generation_mode'] ?? 'publish', 162 'scan_frequency' => $config['podcast_scan_frequency'] ?? 'daily', 163 'podcast_type' => $config['podcast_type'] ?? 'episodic', 164 'apple_category' => $config['apple_category'] ?? 'Technology', 165 ), 166 0 167 ); 168 } 169 170 /** 38 171 * Return the default podcast feed config. 39 172 * … … 42 175 function natuteto_default_podcast_feed_config() { 43 176 return array( 44 'enabled' => false, 45 'feed_slug' => 'podcast', 46 'title' => '', 47 'description' => '', 48 'author' => '', 49 'owner_name' => '', 50 'owner_email' => '', 51 'copyright' => '', 52 'image_url' => '', 53 'language' => 'en-US', 54 'explicit' => 'no', 55 'post_types' => array( 'post' ), 56 'category_slugs' => array(), 57 'generation_mode' => 'publish', 58 'scan_frequency' => 'hourly', 177 'enabled' => false, 178 'feed_slug' => 'podcast', 179 'title' => '', 180 'description' => '', 181 'author' => '', 182 'owner_name' => '', 183 'owner_email' => '', 184 'copyright' => '', 185 'image_url' => '', 186 'language' => 'en-US', 187 'explicit' => 'no', 188 'podcast_type' => 'episodic', 189 'apple_category' => 'Technology', 190 'post_types' => array( 'post' ), 191 'category_slugs' => array(), 192 'generate_on_publish' => true, 193 'regenerate_on_modify' => true, 194 'background_check_enabled' => false, 195 'background_check_frequency' => 'daily', 59 196 ); 60 197 } … … 68 205 */ 69 206 function natuteto_sanitize_podcast_feed_settings( $feed, $index = 0 ) { 70 $defaults = natuteto_default_podcast_feed_config(); 71 $feed = is_array( $feed ) ? $feed : array(); 72 $slug = isset( $feed['feed_slug'] ) ? sanitize_title( $feed['feed_slug'] ) : ''; 207 $defaults = natuteto_default_podcast_feed_config(); 208 $feed = is_array( $feed ) ? $feed : array(); 209 $slug = isset( $feed['feed_slug'] ) ? sanitize_title( $feed['feed_slug'] ) : ''; 210 $generation_settings = natuteto_normalize_podcast_feed_generation_settings( $feed, $defaults ); 73 211 74 212 if ( '' === $slug ) { 75 213 $slug = 0 === $index ? 'podcast' : 'podcast-' . ( $index + 1 ); 76 }77 78 $generation_mode = isset( $feed['generation_mode'] ) ? sanitize_text_field( $feed['generation_mode'] ) : $defaults['generation_mode'];79 if ( ! in_array( $generation_mode, array( 'publish', 'schedule' ), true ) ) {80 $generation_mode = $defaults['generation_mode'];81 }82 83 $scan_frequency = isset( $feed['scan_frequency'] ) ? sanitize_text_field( $feed['scan_frequency'] ) : $defaults['scan_frequency'];84 if ( ! in_array( $scan_frequency, array( 'every_15_minutes', 'hourly', 'twicedaily', 'daily' ), true ) ) {85 $scan_frequency = $defaults['scan_frequency'];86 214 } 87 215 … … 91 219 } 92 220 221 $podcast_type = isset( $feed['podcast_type'] ) ? sanitize_text_field( $feed['podcast_type'] ) : $defaults['podcast_type']; 222 if ( ! in_array( $podcast_type, array( 'episodic', 'serial' ), true ) ) { 223 $podcast_type = $defaults['podcast_type']; 224 } 225 93 226 return array( 94 'enabled' => ! empty( $feed['enabled'] ), 95 'feed_slug' => $slug, 96 'title' => isset( $feed['title'] ) ? sanitize_text_field( $feed['title'] ) : $defaults['title'], 97 'description' => isset( $feed['description'] ) ? sanitize_textarea_field( $feed['description'] ) : $defaults['description'], 98 'author' => isset( $feed['author'] ) ? sanitize_text_field( $feed['author'] ) : $defaults['author'], 99 'owner_name' => isset( $feed['owner_name'] ) ? sanitize_text_field( $feed['owner_name'] ) : $defaults['owner_name'], 100 'owner_email' => isset( $feed['owner_email'] ) ? sanitize_text_field( $feed['owner_email'] ) : $defaults['owner_email'], 101 'copyright' => isset( $feed['copyright'] ) ? sanitize_text_field( $feed['copyright'] ) : $defaults['copyright'], 102 'image_url' => isset( $feed['image_url'] ) ? sanitize_text_field( $feed['image_url'] ) : $defaults['image_url'], 103 'language' => isset( $feed['language'] ) ? sanitize_text_field( $feed['language'] ) : $defaults['language'], 104 'explicit' => $explicit, 105 'post_types' => isset( $feed['post_types'] ) && is_array( $feed['post_types'] ) ? array_values( array_map( 'sanitize_text_field', $feed['post_types'] ) ) : $defaults['post_types'], 106 'category_slugs' => isset( $feed['category_slugs'] ) && is_array( $feed['category_slugs'] ) ? array_values( array_map( 'sanitize_title', $feed['category_slugs'] ) ) : $defaults['category_slugs'], 107 'generation_mode' => $generation_mode, 108 'scan_frequency' => $scan_frequency, 227 'enabled' => ! empty( $feed['enabled'] ), 228 'feed_slug' => $slug, 229 'title' => isset( $feed['title'] ) ? sanitize_text_field( $feed['title'] ) : $defaults['title'], 230 'description' => isset( $feed['description'] ) ? sanitize_textarea_field( $feed['description'] ) : $defaults['description'], 231 'author' => isset( $feed['author'] ) ? sanitize_text_field( $feed['author'] ) : $defaults['author'], 232 'owner_name' => isset( $feed['owner_name'] ) ? sanitize_text_field( $feed['owner_name'] ) : $defaults['owner_name'], 233 'owner_email' => isset( $feed['owner_email'] ) ? sanitize_text_field( $feed['owner_email'] ) : $defaults['owner_email'], 234 'copyright' => isset( $feed['copyright'] ) ? sanitize_text_field( $feed['copyright'] ) : $defaults['copyright'], 235 'image_url' => isset( $feed['image_url'] ) ? sanitize_text_field( $feed['image_url'] ) : $defaults['image_url'], 236 'language' => isset( $feed['language'] ) ? sanitize_text_field( $feed['language'] ) : $defaults['language'], 237 'explicit' => $explicit, 238 'podcast_type' => $podcast_type, 239 'apple_category' => isset( $feed['apple_category'] ) ? sanitize_text_field( $feed['apple_category'] ) : $defaults['apple_category'], 240 'post_types' => isset( $feed['post_types'] ) && is_array( $feed['post_types'] ) ? array_values( array_map( 'sanitize_text_field', $feed['post_types'] ) ) : $defaults['post_types'], 241 'category_slugs' => isset( $feed['category_slugs'] ) && is_array( $feed['category_slugs'] ) ? array_values( array_map( 'sanitize_title', $feed['category_slugs'] ) ) : $defaults['category_slugs'], 242 'generate_on_publish' => $generation_settings['generate_on_publish'], 243 'regenerate_on_modify' => $generation_settings['regenerate_on_modify'], 244 'background_check_enabled' => $generation_settings['background_check_enabled'], 245 'background_check_frequency' => $generation_settings['background_check_frequency'], 109 246 ); 110 247 } -
natural-text-to-speech/trunk/components/implement-plugin.php
r3481657 r3481905 236 236 'dateModified' => get_post_modified_time( 'c', true, $post ), 237 237 'isAccessibleForFree' => true, 238 ' associatedArticle'=> array(238 'encodesCreativeWork' => array( 239 239 '@type' => 'Article', 240 240 'url' => get_permalink( $post ), -
natural-text-to-speech/trunk/components/rest/podcast/bootstrap.php
r3481657 r3481905 20 20 21 21 /** 22 * Add a custom cron interval for 15 minute scans.22 * Add custom cron intervals used by podcast background checks. 23 23 * 24 24 * @param array $schedules Existing schedules. … … 26 26 */ 27 27 function natuteto_podcast_cron_schedules( $schedules ) { 28 if ( ! isset( $schedules['every_15_minutes'] ) ) { 29 $schedules['every_15_minutes'] = array( 30 'interval' => 15 * MINUTE_IN_SECONDS, 31 'display' => 'Every 15 Minutes', 28 if ( ! isset( $schedules['weekly'] ) ) { 29 $schedules['weekly'] = array( 30 'interval' => WEEK_IN_SECONDS, 31 'display' => 'Weekly', 32 ); 33 } 34 35 if ( ! isset( $schedules['monthly'] ) ) { 36 $schedules['monthly'] = array( 37 'interval' => 30 * DAY_IN_SECONDS, 38 'display' => 'Monthly', 32 39 ); 33 40 } … … 195 202 } 196 203 197 return isset( $config['podcasts'] ) && is_array( $config['podcasts'] ) ? $config['podcasts'] : array(); 204 if ( ! isset( $config['podcasts'] ) || ! is_array( $config['podcasts'] ) ) { 205 return array(); 206 } 207 208 return array_values( 209 array_map( 210 function ( $feed_index, $feed ) { 211 return natuteto_sanitize_podcast_feed_settings( $feed, $feed_index ); 212 }, 213 array_keys( $config['podcasts'] ), 214 $config['podcasts'] 215 ) 216 ); 198 217 } 199 218 … … 218 237 219 238 /** 220 * Filter enabled podcast feeds, optionally by generation mode.239 * Filter enabled podcast feeds, optionally by one automation flag. 221 240 * 222 241 * @param array $config Plugin config. 223 * @param string|null $ generation_mode Optional generation modefilter.224 * @return array 225 */ 226 function natuteto_get_enabled_podcast_feeds( $config, $ generation_mode= null ) {242 * @param string|null $requirement Optional feed flag filter. 243 * @return array 244 */ 245 function natuteto_get_enabled_podcast_feeds( $config, $requirement = null ) { 227 246 $feeds = array_filter( 228 247 natuteto_get_podcast_feeds( $config ), 229 function ( $feed ) use ( $ generation_mode) {248 function ( $feed ) use ( $requirement ) { 230 249 if ( empty( $feed['enabled'] ) ) { 231 250 return false; 232 251 } 233 252 234 if ( null !== $ generation_mode && ( $feed['generation_mode'] ?? 'publish' ) !== $generation_mode) {253 if ( null !== $requirement && '' !== $requirement && empty( $feed[ $requirement ] ) ) { 235 254 return false; 236 255 } -
natural-text-to-speech/trunk/components/rest/podcast/generation.php
r3480845 r3481905 83 83 } 84 84 85 $schedule_feeds = natuteto_get_enabled_podcast_feeds( $config, ' schedule' );85 $schedule_feeds = natuteto_get_enabled_podcast_feeds( $config, 'background_check_enabled' ); 86 86 87 87 if ( empty( $schedule_feeds ) ) { … … 95 95 96 96 $priority = array( 97 'every_15_minutes' => 1, 98 'hourly' => 2, 99 'twicedaily' => 3, 100 'daily' => 4, 97 'daily' => 1, 98 'weekly' => 2, 99 'monthly' => 3, 101 100 ); 102 101 $frequency = 'daily'; 103 102 104 103 foreach ( $schedule_feeds as $feed ) { 105 $feed_frequency = $feed[' scan_frequency'] ?? 'hourly';104 $feed_frequency = $feed['background_check_frequency'] ?? 'daily'; 106 105 if ( ! isset( $priority[ $feed_frequency ] ) ) { 107 $feed_frequency = ' hourly';106 $feed_frequency = 'daily'; 108 107 } 109 108 … … 126 125 127 126 /** 128 * Trigger generation after publish when the config uses publish mode.127 * Trigger generation after publish when the feed enables publish generation. 129 128 * 130 129 * @param string $new_status New status. … … 139 138 140 139 $config = natuteto_get_plugin_config(); 141 $publish_feeds = natuteto_get_enabled_podcast_feeds( $config, ' publish' );140 $publish_feeds = natuteto_get_enabled_podcast_feeds( $config, 'generate_on_publish' ); 142 141 143 142 if ( empty( $publish_feeds ) || ! natuteto_post_matches_any_podcast_feed( $post->ID, $publish_feeds ) ) { … … 146 145 147 146 natuteto_queue_podcast_generation( $post->ID, 20, natuteto_get_matching_podcast_feed_slugs( $post->ID, $publish_feeds ) ); 147 } 148 149 /** 150 * Trigger regeneration after a published post is updated. 151 * 152 * @param int $post_id Post ID. 153 * @param WP_Post $post_after Updated post object. 154 * @param WP_Post $post_before Previous post object. 155 * @return void 156 */ 157 function natuteto_handle_podcast_post_update( $post_id, $post_after, $post_before ) { 158 $post_id = absint( $post_id ); 159 160 if ( $post_id <= 0 || wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) { 161 return; 162 } 163 164 if ( ! $post_after instanceof WP_Post || ! $post_before instanceof WP_Post ) { 165 return; 166 } 167 168 if ( 'publish' !== $post_after->post_status || 'publish' !== $post_before->post_status ) { 169 return; 170 } 171 172 $config = natuteto_get_plugin_config(); 173 $modify_feeds = natuteto_get_enabled_podcast_feeds( $config, 'regenerate_on_modify' ); 174 175 if ( empty( $modify_feeds ) || ! natuteto_post_matches_any_podcast_feed( $post_id, $modify_feeds ) ) { 176 return; 177 } 178 179 if ( ! natuteto_podcast_generation_needed( $post_id ) ) { 180 return; 181 } 182 183 natuteto_queue_podcast_generation( $post_id, 20, natuteto_get_matching_podcast_feed_slugs( $post_id, $modify_feeds ) ); 148 184 } 149 185 … … 161 197 if ( '' !== $feed_slug ) { 162 198 $feed = natuteto_get_podcast_feed_by_slug( $config, $feed_slug ); 163 if ( $feed && ! empty( $feed['enabled'] ) ) {199 if ( $feed && ! empty( $feed['enabled'] ) && ! empty( $feed['background_check_enabled'] ) ) { 164 200 $feeds[] = $feed; 165 201 } 166 202 } else { 167 $feeds = natuteto_get_enabled_podcast_feeds( $config, ' schedule' );203 $feeds = natuteto_get_enabled_podcast_feeds( $config, 'background_check_enabled' ); 168 204 } 169 205 -
natural-text-to-speech/trunk/components/rest/podcast/queue.php
r3480845 r3481905 797 797 798 798 $snapshot_feeds[] = array( 799 'feed_slug' => $feed_slug, 800 'feed_label' => natuteto_get_podcast_feed_label( $feed, $index ), 801 'enabled' => ! empty( $feed['enabled'] ), 802 'generation_mode' => sanitize_text_field( (string) ( $feed['generation_mode'] ?? 'publish' ) ), 803 'total_count' => $total_count, 804 'completed_count' => $completed_count, 805 'failed_count' => $failed_count, 806 'queued_count' => $queued_count, 807 'processing_count' => $processing_count, 808 'queue_status' => $queue_status, 809 'progress_percent' => $overall_progress, 810 'current_post_id' => $current_post_id, 811 'current_post_title' => $current_post_title, 812 'current_post_progress' => $current_progress, 813 'current_message' => $current_message, 814 'estimated_seconds' => null === $estimated_seconds ? null : absint( $estimated_seconds ), 815 'estimated_type' => $estimated_type, 816 'updated_at' => absint( $queue_data['updated_at'] ?? 0 ), 799 'feed_slug' => $feed_slug, 800 'feed_label' => natuteto_get_podcast_feed_label( $feed, $index ), 801 'enabled' => ! empty( $feed['enabled'] ), 802 'generate_on_publish' => ! empty( $feed['generate_on_publish'] ), 803 'regenerate_on_modify' => ! empty( $feed['regenerate_on_modify'] ), 804 'background_check_enabled' => ! empty( $feed['background_check_enabled'] ), 805 'background_check_frequency' => sanitize_text_field( (string) ( $feed['background_check_frequency'] ?? 'daily' ) ), 806 'total_count' => $total_count, 807 'completed_count' => $completed_count, 808 'failed_count' => $failed_count, 809 'queued_count' => $queued_count, 810 'processing_count' => $processing_count, 811 'queue_status' => $queue_status, 812 'progress_percent' => $overall_progress, 813 'current_post_id' => $current_post_id, 814 'current_post_title' => $current_post_title, 815 'current_post_progress' => $current_progress, 816 'current_message' => $current_message, 817 'estimated_seconds' => null === $estimated_seconds ? null : absint( $estimated_seconds ), 818 'estimated_type' => $estimated_type, 819 'updated_at' => absint( $queue_data['updated_at'] ?? 0 ), 817 820 ); 818 821 } -
natural-text-to-speech/trunk/components/rest/tts.php
r3481657 r3481905 448 448 449 449 $file_request = new WP_REST_Request( 'GET', '/' . NATUTETO_REST_API . '/file' ); 450 $file_request->set_param( 'base', 'audio' );450 $file_request->set_param( 'base', isset( $file_info['storage_base'] ) ? $file_info['storage_base'] : 'audio' ); 451 451 $file_request->set_param( 'path', $file_info['relative_path'] ); 452 452 … … 490 490 if ( '' === $text ) { 491 491 return new WP_Error( 'schema_audio_empty', 'No readable text found for this post.', array( 'status' => 400 ) ); 492 } 493 494 $podcast_file_info = natuteto_get_schema_audio_podcast_file_info( $post ); 495 if ( is_array( $podcast_file_info ) ) { 496 return $podcast_file_info; 492 497 } 493 498 … … 573 578 574 579 return $file_info; 580 } 581 582 /** 583 * Reuse an existing podcast MP3 for schema audio when it is current for the post. 584 * 585 * @param WP_Post $post Current post. 586 * @return array|null 587 */ 588 function natuteto_get_schema_audio_podcast_file_info( WP_Post $post ) { 589 if ( ! function_exists( 'natuteto_load_podcast_module' ) ) { 590 return null; 591 } 592 593 natuteto_load_podcast_module(); 594 595 if ( ! function_exists( 'natuteto_get_podcast_content_hash' ) || ! defined( 'NATUTETO_PODCAST_META_HASH' ) || ! defined( 'NATUTETO_PODCAST_META_PATH' ) ) { 596 return null; 597 } 598 599 $current_hash = natuteto_get_podcast_content_hash( $post->ID ); 600 $stored_hash = get_post_meta( $post->ID, NATUTETO_PODCAST_META_HASH, true ); 601 $stored_path = get_post_meta( $post->ID, NATUTETO_PODCAST_META_PATH, true ); 602 603 $current_hash = is_string( $current_hash ) ? trim( $current_hash ) : ''; 604 $stored_hash = is_string( $stored_hash ) ? trim( $stored_hash ) : ''; 605 $stored_path = is_string( $stored_path ) ? trim( $stored_path ) : ''; 606 607 if ( '' === $current_hash || '' === $stored_hash || '' === $stored_path || $current_hash !== $stored_hash || ! file_exists( $stored_path ) ) { 608 return null; 609 } 610 611 if ( ! function_exists( 'natuteto_get_podcast_storage_info' ) ) { 612 return null; 613 } 614 615 $storage_info = natuteto_get_podcast_storage_info(); 616 $normalized_base = wp_normalize_path( trailingslashit( $storage_info['basedir'] ) ); 617 $normalized_path = wp_normalize_path( $stored_path ); 618 619 if ( 0 !== strpos( $normalized_path, $normalized_base ) ) { 620 return null; 621 } 622 623 $relative_path = ltrim( substr( $normalized_path, strlen( $normalized_base ) ), '/\\' ); 624 if ( '' === $relative_path ) { 625 return null; 626 } 627 628 return array( 629 'storage_base' => 'podcast', 630 'relative_path' => $relative_path, 631 'full_path' => $stored_path, 632 'filename' => basename( $stored_path ), 633 ); 575 634 } 576 635 -
natural-text-to-speech/trunk/constants.php
r3481657 r3481905 172 172 'podcasts' => array( 173 173 array( 174 'enabled' => false, 175 'feed_slug' => 'podcast', 176 'title' => '', 177 'description' => '', 178 'author' => '', 179 'owner_name' => '', 180 'owner_email' => '', 181 'copyright' => '', 182 'image_url' => '', 183 'language' => 'en-US', 184 'explicit' => 'no', 185 'post_types' => array( 'post' ), 186 'category_slugs' => array(), 187 'generation_mode' => 'publish', 188 'scan_frequency' => 'hourly', 174 'enabled' => false, 175 'feed_slug' => 'podcast', 176 'title' => '', 177 'description' => '', 178 'author' => '', 179 'owner_name' => '', 180 'owner_email' => '', 181 'copyright' => '', 182 'image_url' => '', 183 'language' => 'en-US', 184 'explicit' => 'no', 185 'podcast_type' => 'episodic', 186 'apple_category' => 'Technology', 187 'post_types' => array( 'post' ), 188 'category_slugs' => array(), 189 'generate_on_publish' => true, 190 'regenerate_on_modify' => true, 191 'background_check_enabled' => false, 192 'background_check_frequency' => 'daily', 189 193 ), 190 194 ), -
natural-text-to-speech/trunk/natural-text-to-speech.php
r3481657 r3481905 4 4 * Plugin URI: https://wordpress.org/plugins/natural-text-to-speech 5 5 * Description: Read aloud your posts using natural, human-like voices and highlights sentences and words as they are spoken. Available in Free and Pro versions! Start now with 20,000 free characters / month. 6 * Version: 2.6. 76 * Version: 2.6.8 7 7 * Author: Reinvent WP 8 8 * Author URI: https://reinventwp.com … … 20 20 * serious issues with the options, so no if ( ! defined() ).}} 21 21 */ 22 define( 'NATUTETO_VERSION', '2.6. 7' );22 define( 'NATUTETO_VERSION', '2.6.8' ); 23 23 24 24 if ( ! defined( 'NATUTETO_PLUGIN_DIR' ) ) { … … 202 202 203 203 add_action( 204 'post_updated', 205 function ( $post_id, $post_after, $post_before ) { 206 if ( ! natuteto_has_enabled_podcast_feeds() ) { 207 return; 208 } 209 210 natuteto_load_podcast_module(); 211 natuteto_handle_podcast_post_update( $post_id, $post_after, $post_before ); 212 }, 213 10, 214 3 215 ); 216 217 add_action( 204 218 'natuteto_podcast_scan', 205 219 function () { -
natural-text-to-speech/trunk/readme.txt
r3481657 r3481905 4 4 Requires at least: 5.0 5 5 Tested up to: 6.9 6 Stable tag: 2.6. 77 Version: 2.6. 76 Stable tag: 2.6.8 7 Version: 2.6.8 8 8 Requires PHP: 7.4 9 9 License: GPLv2 or later … … 419 419 * Bulk MP3 Generation 420 420 * Advanced Analytics: Completion Rate Metrics 421 * Audio Schema Markup (SEO) 421 422 * Any suggestion? [fill this form](https://reinventwp.com/feedback) 422 423 … … 484 485 == Changelog == 485 486 487 = 2.6.8 = 488 * Audio Schema Markup (SEO) 489 486 490 = 2.6.7 = 487 491 * Advanced Analytics: Completion Rate Metrics
Note: See TracChangeset
for help on using the changeset viewer.