<?php
/*
* Plugin Name: One WP Feed RSS Monitor
* Description: Monitor and auto-publish podcast episodes as wordpress posts
* Version: 1.1.0
* Author: Victor Andeloci
* Author URI: https://github.com/victorandeloci
*/
function one_wp_feed_rss_monitor_xml_attribute($object, $attribute) {
if (isset($object[$attribute]))
return (string) $object[$attribute];
}
if ( !function_exists('one_wp_feed_rss_monitor_page') ) {
function one_wp_feed_rss_monitor_page() {
// user permissions
if (!current_user_can('manage_options')) {
return;
}
wp_add_inline_script(
'map-scripts',
'const ajax_info = ' . json_encode(array(
'ajaxurl' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('one_wp_feed_rss_monitor_nonce_handler')
)),
'before'
);
wp_enqueue_script(
'one_wp_feed_rss_monitor_main_js',
plugin_dir_url(__FILE__) . 'js/main.js',
[],
'1.1.0',
true
);
$options = [
'feed_url_list' => get_option('one_wp_feed_rss_monitor_feed_url_list', ''),
'default_category_id' => get_option('one_wp_feed_rss_monitor_default_cat', ''),
'ids_to_terms' => get_option('one_wp_feed_rss_monitor_ids_to_terms', ''),
];
$categories = get_categories([
'hide_empty' => false
]);
// cron job exec
include_once('templates/cron_exec.php');
// form render
include_once('templates/settings_form.php');
}
}
function one_wp_feed_rss_monitor_save() {
try {
update_option('one_wp_feed_rss_monitor_feed_url_list', stripslashes($_POST['feed_url_list']));
update_option('one_wp_feed_rss_monitor_default_cat', sanitize_text_field($_POST['default_category_id']));
update_option('one_wp_feed_rss_monitor_ids_to_terms', stripslashes($_POST['ids_to_terms']));
echo 'Saved!';
} catch (\Throwable $th) {
echo 'Error during save... ' . $th;
}
die();
}
add_action('wp_ajax_one_wp_feed_rss_monitor_save', 'one_wp_feed_rss_monitor_save');
add_action('wp_ajax_nopriv_one_wp_feed_rss_monitor_save', 'one_wp_feed_rss_monitor_save');
if ( !function_exists('one_wp_feed_rss_monitor_menu') ) {
function one_wp_feed_rss_monitor_menu() {
add_menu_page(
'One WP Feed RSS Monitor',
'Feed RSS Monitor',
'manage_options',
'one_wp_feed_rss_monitor',
'one_wp_feed_rss_monitor_page',
'dashicons-media-code',
28
);
}
}
add_action( 'admin_menu', 'one_wp_feed_rss_monitor_menu' );
// get feed rss eps
function one_wp_feed_rss_monitor_get_podcast_episodes($feed_url) {
$rss = simplexml_load_file($feed_url);
$episodes = [];
foreach ($rss->channel->item as $item) {
$episode = [];
$episode['default_title'] = (string) $item->title;
// title tricky chars removal
$unwanted = [
'?' => '"',
'?' => '"',
'?' => "'",
'?' => '...',
'?' => "'",
'?' => '-'
];
$episode['title'] = strtr( $item->title, $unwanted );
$episode['description'] = (string) $item->description;
$episode['link'] = (string) $item->link;
$episode['mp3_url'] = (string) one_wp_feed_rss_monitor_xml_attribute($item->enclosure, 'url');
$episode['duration'] = (string) $item->children('itunes', true)->duration;
$episode['season'] = (string) $item->children('itunes', true)->season;
$episode['number'] = (string) $item->children('itunes', true)->episode;
$episode['type'] = (string) $item->children('itunes', true)->episodeType;
$episode['image_url'] = (string) $item->children('itunes', true)->image->attributes()->href;
$episode['pub_date'] = (string) $item->pubDate;
$episode['tags'] = [];
// verify if episode post exists
$existing_post = get_page_by_title($episode['default_title'], OBJECT, 'post');
if (!$existing_post)
$existing_post = get_page_by_title($episode['title'], OBJECT, 'post');
if (!$existing_post) {
// get episode description tags (#tag1, #tag2)
$description = $episode['description'];
$tags_start = strpos($description, '#');
if ($tags_start !== false) {
$tags_end = strpos($description, "\n", $tags_start);
if ($tags_end === false) {
$tags_end = strlen($description);
}
$tags_str = substr($description, $tags_start, $tags_end - $tags_start);
$tags = explode(' ', $tags_str);
foreach ($tags as $tag) {
$episode['tags'][] = iconv('UTF-8', 'ASCII//TRANSLIT', str_replace('#', '', $tag));
}
}
$episodes[] = $episode;
}
}
return $episodes;
}
function one_wp_feed_rss_monitor_create_podcast_post($episode) {
try {
$post_data = array(
'post_title' => $episode['title'],
'post_content' => $episode['description'],
'post_status' => 'publish',
'post_type' => 'post',
'post_date' => date('Y-m-d H:i:s', strtotime($episode['pub_date'])),
'post_author' => (get_current_user_id() ?? 1),
'meta_input' => array(
'episode_link' => $episode['link'],
'episode_mp3_url' => $episode['mp3_url'],
'episode_duration' => $episode['duration'],
'episode_season' => $episode['season'],
'episode_number' => $episode['number'],
'episode_type' => $episode['type'],
'episode_cover' => $episode['image_url']
)
);
$post_id = wp_insert_post($post_data, true);
if ($post_id && !is_wp_error($post_id)) {
// feat. image using "itunes:image"
$image_url = $episode['image_url'];
if ($image_url) {
$image_id = media_sideload_image($image_url, $post_id, null, 'id');
if (!is_wp_error($image_id)) {
set_post_thumbnail($post_id, $image_id);
}
}
// tags
$tags = $episode['tags'];
if (!empty($tags)) {
wp_set_post_tags($post_id, $tags);
}
// episode / post category based on title search by term (defined in settings)
$idsToTermsData = get_option('one_wp_feed_rss_monitor_ids_to_terms', '');
if ($idsToTermsData != null && $idsToTermsData != '') {
$idsToTerms = json_decode($idsToTermsData);
// default category defined in settings
$defaultCategory = get_option('one_wp_feed_rss_monitor_default_cat', '');
$postCategories = [];
if ($defaultCategory != null && $defaultCategory != '')
$postCategories[] = $defaultCategory;
foreach ($idsToTerms as $id => $term) {
if (strpos($episode['title'], $term) !== false) {
$postCategories[] = $id;
}
wp_set_post_categories($post_id, $postCategories);
}
} else {
echo 'Terms not defined!<br>';
}
return true;
} else {
echo 'Could not create post <strong>' . $episode['title'] . '</strong> - ' . $post_id->get_error_message() . '<br>';
}
} catch (\Throwable $th) {
echo 'Fatal error during post creation: ' . $th . '<br>';
}
}
function one_wp_feed_rss_monitor_update_posts_episodes() {
$feed_url_list = get_option('one_wp_feed_rss_monitor_feed_url_list', '');
if (!empty($feed_url_list)) {
foreach (json_decode($feed_url_list) as $i => $feed_url) {
// get feed RSS eps
$episodes = one_wp_feed_rss_monitor_get_podcast_episodes($feed_url);
if (!empty($episodes)) {
// create posts foreach ep
$podcastPostCount = 0;
foreach ($episodes as $episode) {
if (one_wp_feed_rss_monitor_create_podcast_post($episode))
$podcastPostCount++;
}
echo $podcastPostCount . ' post(s) created!';
} else {
echo 'Could not find new episodes on feed ' . ($i + 1) . '...<br>';
}
}
} else {
echo 'Feed RSS URL not defined!';
}
die();
}
add_action('wp_ajax_one_wp_feed_rss_monitor_update_posts_episodes', 'one_wp_feed_rss_monitor_update_posts_episodes');
add_action('wp_ajax_nopriv_one_wp_feed_rss_monitor_update_posts_episodes', 'one_wp_feed_rss_monitor_update_posts_episodes');
|