Plugin Directory

Changeset 3481905


Ignore:
Timestamp:
03/13/2026 10:51:51 AM (3 weeks ago)
Author:
reinventwp
Message:

Deploying version 2.6.8 - audio schema markup

Location:
natural-text-to-speech/trunk
Files:
7 added
7 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • natural-text-to-speech/trunk/components/config.php

    r3481657 r3481905  
    2222    $data = get_option( NATUTETO_KV_STORAGE, NATUTETO_DEFAULT_CONFIG );
    2323
     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
    2441    foreach ( $except as $key => $value ) {
    2542        unset( $data[ $value ] );
     
    3653
    3754/**
     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 */
     61function 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 */
     82function 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 */
     114function 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/**
    38171 * Return the default podcast feed config.
    39172 *
     
    42175function natuteto_default_podcast_feed_config() {
    43176    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',
    59196    );
    60197}
     
    68205 */
    69206function 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 );
    73211
    74212    if ( '' === $slug ) {
    75213        $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'];
    86214    }
    87215
     
    91219    }
    92220
     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
    93226    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'],
    109246    );
    110247}
  • natural-text-to-speech/trunk/components/implement-plugin.php

    r3481657 r3481905  
    236236        'dateModified'        => get_post_modified_time( 'c', true, $post ),
    237237        'isAccessibleForFree' => true,
    238         'associatedArticle'  => array(
     238        'encodesCreativeWork' => array(
    239239            '@type'    => 'Article',
    240240            'url'      => get_permalink( $post ),
  • natural-text-to-speech/trunk/components/rest/podcast/bootstrap.php

    r3481657 r3481905  
    2020
    2121/**
    22  * Add a custom cron interval for 15 minute scans.
     22 * Add custom cron intervals used by podcast background checks.
    2323 *
    2424 * @param array $schedules Existing schedules.
     
    2626 */
    2727function 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',
    3239        );
    3340    }
     
    195202    }
    196203
    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    );
    198217}
    199218
     
    218237
    219238/**
    220  * Filter enabled podcast feeds, optionally by generation mode.
     239 * Filter enabled podcast feeds, optionally by one automation flag.
    221240 *
    222241 * @param array       $config Plugin config.
    223  * @param string|null $generation_mode Optional generation mode filter.
    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 */
     245function natuteto_get_enabled_podcast_feeds( $config, $requirement = null ) {
    227246    $feeds = array_filter(
    228247        natuteto_get_podcast_feeds( $config ),
    229         function ( $feed ) use ( $generation_mode ) {
     248        function ( $feed ) use ( $requirement ) {
    230249            if ( empty( $feed['enabled'] ) ) {
    231250                return false;
    232251            }
    233252
    234             if ( null !== $generation_mode && ( $feed['generation_mode'] ?? 'publish' ) !== $generation_mode ) {
     253            if ( null !== $requirement && '' !== $requirement && empty( $feed[ $requirement ] ) ) {
    235254                return false;
    236255            }
  • natural-text-to-speech/trunk/components/rest/podcast/generation.php

    r3480845 r3481905  
    8383    }
    8484
    85     $schedule_feeds = natuteto_get_enabled_podcast_feeds( $config, 'schedule' );
     85    $schedule_feeds = natuteto_get_enabled_podcast_feeds( $config, 'background_check_enabled' );
    8686
    8787    if ( empty( $schedule_feeds ) ) {
     
    9595
    9696    $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,
    101100    );
    102101    $frequency = 'daily';
    103102
    104103    foreach ( $schedule_feeds as $feed ) {
    105         $feed_frequency = $feed['scan_frequency'] ?? 'hourly';
     104        $feed_frequency = $feed['background_check_frequency'] ?? 'daily';
    106105        if ( ! isset( $priority[ $feed_frequency ] ) ) {
    107             $feed_frequency = 'hourly';
     106            $feed_frequency = 'daily';
    108107        }
    109108
     
    126125
    127126/**
    128  * Trigger generation after publish when the config uses publish mode.
     127 * Trigger generation after publish when the feed enables publish generation.
    129128 *
    130129 * @param string  $new_status New status.
     
    139138
    140139    $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' );
    142141
    143142    if ( empty( $publish_feeds ) || ! natuteto_post_matches_any_podcast_feed( $post->ID, $publish_feeds ) ) {
     
    146145
    147146    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 */
     157function 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 ) );
    148184}
    149185
     
    161197    if ( '' !== $feed_slug ) {
    162198        $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'] ) ) {
    164200            $feeds[] = $feed;
    165201        }
    166202    } else {
    167         $feeds = natuteto_get_enabled_podcast_feeds( $config, 'schedule' );
     203        $feeds = natuteto_get_enabled_podcast_feeds( $config, 'background_check_enabled' );
    168204    }
    169205
  • natural-text-to-speech/trunk/components/rest/podcast/queue.php

    r3480845 r3481905  
    797797
    798798        $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 ),
    817820        );
    818821    }
  • natural-text-to-speech/trunk/components/rest/tts.php

    r3481657 r3481905  
    448448
    449449    $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' );
    451451    $file_request->set_param( 'path', $file_info['relative_path'] );
    452452
     
    490490    if ( '' === $text ) {
    491491        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;
    492497    }
    493498
     
    573578
    574579    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 */
     588function 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    );
    575634}
    576635
  • natural-text-to-speech/trunk/constants.php

    r3481657 r3481905  
    172172    'podcasts'                       => array(
    173173        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',
    189193        ),
    190194    ),
  • natural-text-to-speech/trunk/natural-text-to-speech.php

    r3481657 r3481905  
    44 * Plugin URI:  https://wordpress.org/plugins/natural-text-to-speech
    55 * 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.7
     6 * Version:     2.6.8
    77 * Author:      Reinvent WP
    88 * Author URI:  https://reinventwp.com
     
    2020 * serious issues with the options, so no if ( ! defined() ).}}
    2121 */
    22 define( 'NATUTETO_VERSION', '2.6.7' );
     22define( 'NATUTETO_VERSION', '2.6.8' );
    2323
    2424if ( ! defined( 'NATUTETO_PLUGIN_DIR' ) ) {
     
    202202
    203203add_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
     217add_action(
    204218    'natuteto_podcast_scan',
    205219    function () {
  • natural-text-to-speech/trunk/readme.txt

    r3481657 r3481905  
    44Requires at least: 5.0
    55Tested up to: 6.9
    6 Stable tag: 2.6.7
    7 Version: 2.6.7
     6Stable tag: 2.6.8
     7Version: 2.6.8
    88Requires PHP: 7.4
    99License: GPLv2 or later
     
    419419  * Bulk MP3 Generation
    420420  * Advanced Analytics: Completion Rate Metrics
     421  * Audio Schema Markup (SEO)
    421422  * Any suggestion? [fill this form](https://reinventwp.com/feedback)
    422423
     
    484485== Changelog ==
    485486
     487= 2.6.8 =
     488* Audio Schema Markup (SEO)
     489
    486490= 2.6.7 =
    487491* Advanced Analytics: Completion Rate Metrics
Note: See TracChangeset for help on using the changeset viewer.