From 77c3b2e444d80b9bd4a579f89e5822e50fd99101 Mon Sep 17 00:00:00 2001 From: mehrshaddarzi Date: Mon, 26 Jul 2021 18:36:18 +0430 Subject: [PATCH 1/4] init --- .gitignore | 1 + LICENSE | 21 - README.md | 1 - asset/admin/css/admin.css | 162 +++ asset/admin/js/admin.js | 34 + assets/css/admin.css | 31 - assets/img/loading.gif | Bin 5831 -> 0 bytes assets/js/admin.js | 34 - class-podcast-importer.php | 1129 ----------------- inc/admin/admin.php | 240 ++++ inc/admin/views/settings.php | 127 ++ inc/admin/views/tools.php | 22 + inc/config/i18n.php | 52 + inc/config/install.php | 12 + inc/config/uninstall.php | 12 + inc/helper.php | 288 +++++ inc/process.php | 255 ++++ includes/class-podcast-importer-activator.php | 23 - .../class-podcast-importer-deactivator.php | 24 - includes/dismiss-notices/dismiss-notice.js | 33 - includes/dismiss-notices/dismiss-notices.php | 159 --- includes/index.php | 1 - languages/podcast-importer.pot | 182 --- podcast-importer.php | 360 ++++-- readme.txt | 52 - 25 files changed, 1452 insertions(+), 1803 deletions(-) create mode 100644 .gitignore delete mode 100644 LICENSE delete mode 100644 README.md create mode 100644 asset/admin/css/admin.css create mode 100644 asset/admin/js/admin.js delete mode 100644 assets/css/admin.css delete mode 100644 assets/img/loading.gif delete mode 100644 assets/js/admin.js delete mode 100644 class-podcast-importer.php create mode 100644 inc/admin/admin.php create mode 100644 inc/admin/views/settings.php create mode 100644 inc/admin/views/tools.php create mode 100644 inc/config/i18n.php create mode 100644 inc/config/install.php create mode 100644 inc/config/uninstall.php create mode 100644 inc/helper.php create mode 100644 inc/process.php delete mode 100644 includes/class-podcast-importer-activator.php delete mode 100644 includes/class-podcast-importer-deactivator.php delete mode 100644 includes/dismiss-notices/dismiss-notice.js delete mode 100644 includes/dismiss-notices/dismiss-notices.php delete mode 100644 includes/index.php delete mode 100644 languages/podcast-importer.pot delete mode 100644 readme.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9f11b75 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/LICENSE b/LICENSE deleted file mode 100644 index a74e438..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 VeronaLabs - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 0e183ad..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# podcast-importer \ No newline at end of file diff --git a/asset/admin/css/admin.css b/asset/admin/css/admin.css new file mode 100644 index 0000000..6bd89b3 --- /dev/null +++ b/asset/admin/css/admin.css @@ -0,0 +1,162 @@ +.clearfix-ver:after, .clearfix-ver:before { + content: ""; + display: table +} + +.clearfix-ver:after { + clear: both +} + +#ver-form-container { + width: 100% +} + +.podcast_importer_form input[type=text] { + max-width: 70%; + width: 450px +} + +em.ver-notice { + float: right; + font-size: .8em +} + +.podcast_importer_form .ver-checkbox-container { + margin: 20px 0 10px 0 +} + +.podcast_importer_form .ver-checkbox-container span { + margin-left: 8px +} + +.podcast_importer_form input[type=submit] { + margin-top: 40px +} + +.podcast_importer_form select { + max-width: 70%; + min-width: 225px +} + +input.podcast_feed { + min-width: 400px; + max-width: 90% +} + +.podcast_importer_form select.post_type_select { + text-transform: capitalize +} + +.ver-plugin-container label.ver-form-label { + margin-bottom: 5px; + margin-top: 20px; + display: block +} + +h2.ver-importer-header { + margin: 0 0 40px 0 +} + +.ver-plugin-container { + padding: 40px; + margin: 10px 20px 10px 0; + background-color: #fff; + border: 1px solid #e3e3e3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px +} + +.existing-import-container .import-process-item { + padding: 6px 14px 4px 14px; + color: #848484; + background-color: #f9f9f9; + border: 1px solid #cfcfcf; + border-radius: 4px; + display: inline-block; + position: relative; + top: 0; + margin: 0 25px 0 0; + width: 65% +} + +.existing-import-container ul li { + margin: 20px 0; + padding-bottom: 20px; + border-bottom: 1px solid #ddd +} + +.existing-import-container ul li:last-child { + border: 0 +} + +.existing-import-container .delete-button { + margin-left: 10px; + float: right; + position: relative; + top: 1px +} + +.wp-core-ui .ver-plugin-container .button-link-delete { + border-color: #a00 +} + +.wp-core-ui .ver-plugin-container .button-link-delete:hover { + border-color: #dc3232 +} + +.wp-core-ui .ver-plugin-container .button-link-delete:focus { + box-shadow: none +} + +.wp-core-ui .ver-plugin-container .button-link-edit { + top: 1px; + float: right; + position: relative +} + +span.ver-existing-post-notice { + font-style: italic; + font-size: 11px +} + +span.ver-importer-notice { + margin: -30px 0 40px 0; + display: block; + font-style: italic +} + +.tools_page_podcastimport.wp-core-ui .notice.is-dismissible { + padding-right: 0; + margin: 12px 20px 12px 0 +} + +.advanced-settings-wrapper, .edit-import-form { + max-height: 0; + overflow: hidden; + transition: .3s max-height +} + +.edit-import-form.expanded, .expanded .advanced-settings-wrapper { + max-height: 9999px +} + +.ver-importer-header.advanced-options { + margin-top: 2em; + cursor: pointer +} + +h3.ver-importer-header.advanced-options:before { + content: "+"; + font-size: 1.2em; + font-weight: 900; + margin-right: 15px +} + +.expanded h3.ver-importer-header.advanced-options:before { + content: "–" +} + +.existing-import-container .advanced-options:before { + display: none !important +} \ No newline at end of file diff --git a/asset/admin/js/admin.js b/asset/admin/js/admin.js new file mode 100644 index 0000000..78cacf7 --- /dev/null +++ b/asset/admin/js/admin.js @@ -0,0 +1,34 @@ +(function () { + const editButtons = document.querySelectorAll(".button-link-edit"); + + Array.from(editButtons).forEach((button) => { + button.addEventListener("click", (event) => { + event.preventDefault(); + + const importID = button.getAttribute("data-import-id"); + const importForm = document.getElementById( + `edit-import-form--${importID}` + ); + + if (importForm.classList.contains("expanded")) { + importForm.classList.remove("expanded"); + } else { + editButtons.forEach((button) => button.classList.remove("expanded")); + + importForm.classList.add("expanded"); + } + }); + }); +}()) + +jQuery(document).ready(function ($) { + 'use strict'; + $(".settings-wrapper").each(function () { + var $heading = $(this).find("h3"); + var $wrapper = $(this); + $heading.click(function () { + $wrapper.toggleClass("expanded") + }); + }); +}) + diff --git a/assets/css/admin.css b/assets/css/admin.css deleted file mode 100644 index 6cb7552..0000000 --- a/assets/css/admin.css +++ /dev/null @@ -1,31 +0,0 @@ -.clearfix-slt:after,.clearfix-slt:before{content:"";display:table} -.clearfix-slt:after{clear:both} -#slt-form-container{width:100%} -.podcast_importer_form input[type=text]{max-width:70%;width:450px} -em.slt-notice{float:right;font-size:.8em} -.podcast_importer_form .slt-checkbox-container{margin:20px 0 10px 0} -.podcast_importer_form .slt-checkbox-container span{margin-left:8px} -.podcast_importer_form input[type=submit]{margin-top:40px} -.podcast_importer_form select{max-width:70%;min-width:225px} -input.podcast_feed{min-width:400px;max-width:90%} -.podcast_importer_form select.post_type_select{text-transform:capitalize} -.slt-plugin-container label.slt-form-label{margin-bottom:5px;margin-top:20px;display:block} -h2.slt-importer-header{margin:0 0 40px 0} -.slt-plugin-container{padding:40px;margin:10px 20px 10px 0;background-color:#fff;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px} -.existing-import-container .import-process-item{padding:6px 14px 4px 14px;color:#848484;background-color:#f9f9f9;border:1px solid #cfcfcf;border-radius:4px;display:inline-block;position:relative;top:0;margin:0 25px 0 0;width:65%} -.existing-import-container ul li{margin:20px 0;padding-bottom:20px;border-bottom:1px solid #ddd} -.existing-import-container ul li:last-child{border:0} -.existing-import-container .delete-button{margin-left:10px;float:right;position:relative;top:1px} -.wp-core-ui .slt-plugin-container .button-link-delete{border-color:#a00} -.wp-core-ui .slt-plugin-container .button-link-delete:hover{border-color:#dc3232} -.wp-core-ui .slt-plugin-container .button-link-delete:focus{box-shadow:none} -.wp-core-ui .slt-plugin-container .button-link-edit{top:1px;float:right;position:relative} -span.slt-existing-post-notice{font-style:italic;font-size:11px} -span.slt-importer-notice{margin:-30px 0 40px 0;display:block;font-style:italic} -.tools_page_podcastimport.wp-core-ui .notice.is-dismissible{padding-right:0;margin:12px 20px 12px 0} -.advanced-settings-wrapper,.edit-import-form{max-height:0;overflow:hidden;transition:.3s max-height} -.edit-import-form.expanded,.expanded .advanced-settings-wrapper{max-height:9999px} -.slt-importer-header.advanced-options{margin-top:2em;cursor:pointer} -h3.slt-importer-header.advanced-options:before{content:"+";font-size:1.2em;font-weight:900;margin-right:15px} -.expanded h3.slt-importer-header.advanced-options:before{content:"–"} -.existing-import-container .advanced-options:before{display:none!important} \ No newline at end of file diff --git a/assets/img/loading.gif b/assets/img/loading.gif deleted file mode 100644 index b1d3d977c4223a4474888ddc43ffe65cad162893..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5831 zcmbW5iCdFry2jtEgpfc2*~mr+B#?y=&^pMmUXXl=fIyKTB1MNyYZXxu6|Gt}*-@Z? z8(KuL6_G_zsZxp-lqyzK)K2U4pkix#>=doj#d_*_K0ajZbk0nze*o8Ie)sRbpZA*; zY7Lm4R z8JRafzZnx7Gj-b3#)ihUrD-=my%`f7)7{gZUy%Rk;Umn7wY0Vjo*%5Ps($jzld1kw z>-N?SUmp&S4DUYKou8Y3|8Ms(6V}q)(s#D6Y-`z*$4@qH*f{#dXu`sT8G$p>($k(k zeTrWEpZimXNK1^(92{lwHy9}-_zUhoQSBMXfb{rZ!~dIz{!7sIl_7dZ2T$zuKw4m_ zodER)&S!De|)E>w1~8*CjT_#~+9}WN)EH$2@1yULP5~`$fa4QLaMyRjs3{3)6CJ z|K06`=oX=866O7P6g4-sH=$f80GcW}!+gpwH39Vv7yl}DZUZH)i;ZMIAVU~%f;$Ab_6 zKo1!JUVu9xK7oh<1OSjh1|Sa*0Kf|9@ff710eZ*)galARiXa0(zq+=X2ms^+&sAhN z(8ps?kUx4GCyuA3xdk!+X~|rh39*3;;E9TjdC?dE+Z{OD;9}|poGputRyNOQ>t|m$ zqbP~L8k?y3m%4+Vv zFnICfOG8Etn@729TJLS6o*$&S3yor1&1L1t6|GKjz zUUwGx-B0ZHlZ(+0rlxz-lEc^^uH(iBWqlP%-8CopS@@^?7I5+eU_x(T3}}JDq}YV# z1Yp8&0`sKaokuz+jU^-pYy{@i#pCr68BTZ(fxuO7Z2`16@Aw2lcrYI@L#;q=0QT=B zP5-5LCk}Y-&fzmS;5}^AyX56I>$SeXv;_ye>@HUYtn9#CMr|7P%(qd8ipCr27j?x9 zFA2o7Hst$S7T4ySJx@Tjk+U$FS|rHwr?Kgkb$j;ik*P{CB~A2pgaeP`UTao)+2rq9 zHF+6kI>+YJX>rceTfBArf*yk}^3wKXiRBwVzB+vE`i)2*BY*ZMRs(XA?7!jYY@9NJ z$fMW4xF@q`U;O;<-~aIAPmjZ0_=X$%$~r|Pl%rc}TsXMvX!6b-OPxdm#$*NQ{Y|1N z(_UXSxR=Ic&__Brd42DYYyl&|_9Kan0#DBb-W3w1B*jNr-*xukpB-jWsD>qHiK;Q+1fiOS=tq6q)yzuh_Ti^f|gTFu?d<1`iFt|zhJIVHWg&_+B zTc8SfAxglOu$W+rr|EZtCCVP~j{B>VULOFw2B!`8999V0C}h zg*A%whP{`%LT<3{&GpDkaOBEV>;vf?|**szn69&ud7r(Bxl=)ot7trBzg+B zosYFQJfgY%yyTo~!(NU-CbKojqu9 z%LqjBWU*T`X%oh97H9Bz`q@SJ?)uT3l4>m)fst1>%P8}z+->4TqqJF6zbd07~HJRD2&gaGPl0>&BD+M&tgu4F!c5`uipOFQogu~CP`%k@$+q-pQc7Ydwd!Fy} zn+s?2BwwflVs^n{;7d6C2dWv=#ZM|{2mbzyk75cGMcC>vnE|1yRs9FW(+@}QkJB8B z?avAEd+4l+TRwNoU%Lv~7d`JRdM})|E*ImcYSA~|-N9un!#Xn$(G?v(a^gMbwV{D`^P)H9xza*&PLyLva zN!(d~SYYQsV|p@~9ZW@w*qEL)Y=Q6J!O{g6evAy`}ju$gP1>0ZL*l}rl@u#k{M2n*} zgi+0awhGCj*8CiuRfW}j*{3ngR2qL+1O@(CiKJ)qs&M-Y*XJfr{W{ykUX-(?ps*<0 zK^|>U@VLch0Rw6BWA)4`lZPI;FExAYsPg2;*EJt%Io#UTZgNnj`jXt>Xs(Ar+;ZO6MTPV|RazPkbWcYXLMh=^gV^w<}f_exyUqpKCIHWji*$5tK<9xic| zX&rAxAqV>)c4SD!jjzOr+!Vta8VIE^NmUoroyOCvBRCUu^}nVIUpt6OhN*>CCO%F~ zRC03*a0Sdjlz8TXnxH9=10KK?h7xD?>{y;0TzKOGS|Ezg?)VoGqK_diKop_?EMaXS zB7dNUC;OPFgx7Hpt;wl`n7I=sX|n|4*iM>K7=N z*$P^;nc1VO)=CinpxVyEMIF>XRS=a%_c$T ztHX?-{Fin2_6$ww6Ol8_0ga*u5s@O^4}m6QE-9s+v?4O<=XPZ_^`iFQOf6VTe8d3r zfG)g)fGg3)U@eft>1JdCQJ{;T$m3ryh+B%VmZ)N|7Jva=phXPsWFbRb05j+dfQdE+ zaUm{%8FB-a0GMC&N+!7Ck09~3fyRsh&C9hz-f5PikhWd@m8pKy;&(2a6BHM!L)+%- z8`D}nXO%{@efB@ni;v~1Jqm98MvUzswfLYCeI6!4B#ToCax6D1(JPpSiVT$PCXL4e zi>Eui0k?LZfL_>!X@v&W8!c>ap3%3ur&T5A(Ctg)xrg6k2q;Rm&(Xs=k6hh>&d+ZC zwOl7=e=Z<%e488ic4y2U)ou-*2BbWxeH}3y;5p?rYzzp=dJuG@p65EW{?&oSG$!rS z+LiSc4Ur9D=&eln9zoqR3o(j3j+{}jDxB}}vPbrrE7?LU%hUf%-+O@?R{8wVeowYr zGD=vxtX`3KNi_-hpK2NZO!@qGhUaS;>UaEe6#ypa615C~|3xiB*?uv82#Fzmi(wgUJH|ngm@Gq|PdrGk-L z8X7}>@~DqvKSo)mKFVewxy4~A@;G`AF_K1+gYfj?4%4jGeRTpmk(TRz$f+r3zO_Z+ z{)%IPf#>XaOOX*$Wcc(kOVN?+Qfco!tx@csjVPg;^dXXm+-y$MJXNsfUh)cQA;Txv zWKTx_6%Y`zEEo%2n`B%R9=(3KDa^Ed%9PmYDYgjP)bO>T>y`%lt%=6Mrp}$7zAR { - button.addEventListener("click", (event) => { - event.preventDefault(); - - const importID = button.getAttribute("data-import-id"); - const importForm = document.getElementById( - `edit-import-form--${importID}` - ); - - if (importForm.classList.contains("expanded")) { - importForm.classList.remove("expanded"); - } else { - editButtons.forEach((button) => button.classList.remove("expanded")); - - importForm.classList.add("expanded"); - } - }); - }); -}()) - -jQuery(document).ready(function ($) { - 'use strict'; - $(".settings-wrapper").each(function () { - var $heading = $(this).find("h3"); - var $wrapper = $(this); - $heading.click(function () { - $wrapper.toggleClass("expanded") - }); - }); -}) - diff --git a/class-podcast-importer.php b/class-podcast-importer.php deleted file mode 100644 index 824cabc..0000000 --- a/class-podcast-importer.php +++ /dev/null @@ -1,1129 +0,0 @@ - array( - 'name' => esc_html__('Podcast Imports', 'podcast-importer'), - 'singular_name' => esc_html__('Podcast Import', 'podcast-importer') - ), - 'public' => true, - 'has_archive' => false, - 'supports' => array('title'), - 'can_export' => false, - 'exclude_from_search' => true, - 'show_in_admin_bar' => false, - 'show_in_nav_menus' => false, - 'publicly_queryable' => false, - ) - ); - } - - // Add a new menu link under Tools - public function add_page() - { - add_management_page(esc_attr__('Podcast Importer', 'podcast-importer'), esc_attr__('Podcast Importer', 'podcast-importer'), 'manage_options', 'podcast-imprter', array($this, 'front_init')); - } - - // Load admin scripts - public function admin_scripts() - { - wp_register_style('podcast_importer_admin_styles', esc_url(plugins_url('/assets/css/admin.css', __FILE__)), false, '1.0.0'); - wp_enqueue_style('podcast_importer_admin_styles'); - - wp_register_script('podcast_importer_admin_scripts', esc_url(plugins_url('/assets/js/admin.js', __FILE__)), false, '1.0.0', true); - wp_enqueue_script('podcast_importer_admin_scripts'); - } - - public function settings_form($post_id_to_update = false) - { - if ($post_id_to_update) : - $post_meta = get_post_meta($post_id_to_update); - endif; ?> - -
- - - - - - -
- - - - -
- - - - 'podcast_importer_author', - 'selected' => get_post_meta($post_id_to_update, 'podcast_importer_author', true) - )); ?> - -
- - - - -
- - -
- - -
- - -
- - - type="checkbox" id="_podcast_importer_images" name="podcast_importer_images"/> - -
- - -
- - - type="checkbox" id="_podcast_importer_embed_player" name="podcast_importer_embed_player"/> - -
- -
-

-
- - - - - - -
- - type="checkbox" id="_podcast_importer_episode_number" name="podcast_importer_episode_number"/> - -
- - - -
-
- -
- - - - - - - - - - - - -
- -
-
-

- -

- - update($post_id); - endif; - - if (!isset($_POST['submit'])) : - $this->settings_form(); - else : - if (isset($this)) { - $this->podcast_import(); - } - endif; - ?> -
- -
- - - 'podcast_importer', - 'posts_per_page' => 99, - ); - - $blogloop = new \WP_Query($args); - if ($blogloop->have_posts()) : - - ?> - -
-

- -
    - have_posts()): $blogloop->the_post(); ?> -
  • - - - ID, 'podcast_importer_rss_feed', true); ?> - - - - - - - - - - -
    - settings_form($post->ID); ?> -
    - -
    -
  • - -
-
- 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0', - ]); - $result = wp_remote_retrieve_body($response); - if (substr($result, 0, 5) == "channel->item); - - for ($i = 0; $i < $episode_count; $i++) { - - $item = $podcast_importer_rss_feed->channel->item[$i]; - $itunes = $item->children('http://www.itunes.com/dtds/podcast-1.0.dtd'); - $guid = $this->sanitize_data($item->guid); - $episode_number = $this->sanitize_data($itunes->episode); - $season_number = $this->sanitize_data($itunes->season); - - // Get episode duration (in seconds or text) and file size (in bytes) - $filesize = 0; // default value - $filesize = $item->enclosure['length']; - $filesize = '' . number_format($filesize / 1048576, 2) . 'M'; - $duration = $this->sanitize_data($itunes->duration); - if ((!empty($duration)) && (strpos($duration, ':') !== false)) - $duration = $duration; - elseif (!empty($duration)) { - $duration = gmdate("H:i:s", $duration); - } else { - $duration = ''; - } - - // Ensure posts are published right away (for server/feed timezone conflicts) - if (strtotime((string)$item->pubDate) < current_time('timestamp')) { - $timestamp_post_date = strtotime((string)$item->pubDate); - } else { - $timestamp_post_date = current_time('timestamp'); - } - - $post_date = date('Y-m-d H:i:s', $timestamp_post_date); - - if (($podcast_importer_episode_number == 'on') && ($this->sanitize_data($itunes->episode) != '')) { - $post_title = $this->sanitize_data($itunes->episode) . ': ' . $this->sanitize_data($item->title); - } else { - $post_title = $this->sanitize_data($item->title); - } - - if (isset($podcast_importer_prepend_title)) { - $podcast_importer_prepend_title = str_replace('[podcast_title]', $this->sanitize_data($podcast_importer_rss_feed->channel->title), $podcast_importer_prepend_title); - - $post_title = $podcast_importer_prepend_title . ' ' . $post_title; - } - - // Set up audio as a shortcode and remove query variables - $audio_url = (string)$item->enclosure['url']; - $audio_url = preg_replace('/(?s:.*)(https?:\/\/(?:[\w\-\.]+[^#?\s]+)(?:\.mp3))(?s:.*)/', '$1', $audio_url); - $audio_url = preg_replace('/(?s:.*)(https?:\/\/(?:[\w\-\.]+[^#?\s]+)(?:\.m4a))(?s:.*)/', '$1', $audio_url); - $feed_link_url = (string)$item->link; - $host_checker = false; - $match_image_filenames = $this->match_image_names($podcast_importer_rss_feed_url); - if (!empty($feed_link_url)) { - $parsed_feed_url = parse_url($feed_link_url); - $parsed_feed_host = $parsed_feed_url['host']; - } else { - $parsed_feed_host = ''; - } - - if (($podcast_importer_embed_player == 'on') && (isset($parsed_feed_host) || isset($podcast_importer_rss_feed_url))) { - if (preg_match('/fireside.fm/i', $podcast_importer_rss_feed_url)) { - $feed_link_url = (string)$item->children('fireside', true)->playerEmbedCode; - } - if (preg_match('/omny.fm/i', $podcast_importer_rss_feed_url) || preg_match('/omnycontent.com/i', $podcast_importer_rss_feed_url)) { - $feed_link_url = (string)$item->children('media', true)->content->children('media', true)->player->attributes()->url; - } - if (preg_match('/libsyn.com/i', $podcast_importer_rss_feed_url) || preg_match('/omnycontent.com/i', $podcast_importer_rss_feed_url)) { - $feed_link_url = (string)$item->children('libsyn', true)->itemId; - } - $audio_shortcode = $this->embed_validator($parsed_feed_host, $feed_link_url, $audio_url, $podcast_importer_rss_feed_url, $guid); - $host_checker = $this->embed_host_checker($parsed_feed_host, $podcast_importer_rss_feed_url); - } else { - $audio_shortcode = '[audio src="' . esc_url($audio_url) . '"][/audio]'; - } - - // Grab the content - if (!empty($item->children('itunes', true)->summary) && $podcast_importer_content_tag === 'itunes:summary') { - $parsed_content = $this->sanitize_data($item->children('itunes', true)->summary); - } elseif (!empty($item->children('itunes', true)->encoded) && $podcast_importer_content_tag === 'content:encoded') { - $parsed_content = $this->sanitize_data($item->children('content', true)->encoded); - } elseif (!empty($item->description) && $podcast_importer_content_tag === 'description') { - $parsed_content = $this->sanitize_data($item->description); - // If no preference cuts the mustard, try all the defaults - } elseif (!empty($item->children('content', true)->encoded)) { - $parsed_content = $this->sanitize_data($item->children('content', true)->encoded); - } elseif (!empty($item->description)) { - $parsed_content = $this->sanitize_data($item->description); - } else { - $parsed_content = $this->sanitize_data($itunes->summary); - } - - if ($podcast_importer_truncate_post) { - $parsed_content = substr($parsed_content, 0, intval($podcast_importer_truncate_post)); - } - - $post_content = $parsed_content; - - // Create post data - $post = array( - 'post_author' => $podcast_importer_author, - 'post_content' => $post_content, - 'post_date' => $post_date, - 'post_excerpt' => $this->sanitize_data($itunes->subtitle), - 'post_status' => $podcast_importer_publish, - 'post_type' => $podcast_importer_post_type, - 'post_title' => $post_title, - ); - - - // Create the post - global $wpdb; - $post_id; - // Check if post already exists, if so - skip. First we'll look for the GUID, then at the title. - if (!empty($guid) && $guid != '') { - $query = "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE (meta_key = 'podcast_importer_imported_guid' AND meta_value LIKE '%$guid%')"; - $guid_count = intval($wpdb->get_var($query)); - } else { - $guid_count = 0; - } - if ($guid_count == 0) { - - if (0 === post_exists($post_title, "", "", $podcast_importer_post_type)) { - - $post_id = wp_insert_post($post); - - // Continue if the import generate errors - if (is_wp_error($post_id)) { - continue; - } - - // Add GUID for each post - add_post_meta($post_id, 'podcast_importer_imported_guid', $guid, true); - add_post_meta($post_id, 'podcast_importer_episode_number', $episode_number, true); - add_post_meta($post_id, 'podcast_importer_season_number', $season_number, true); - add_post_meta($post_id, 'podcast_importer_external_embed', $audio_shortcode, true); - add_post_meta($post_id, 'podcast_audio_file', $audio_url, true); - add_post_meta($post_id, 'podcast_audio_url', $audio_url, true); - add_post_meta($post_id, 'podcast_duration', $duration, true); - add_post_meta($post_id, 'podcast_filesize', $filesize, true); - add_post_meta($post_id, 'podcast_enclosure', $audio_url, true); - add_post_meta($post_id, 'podcast_author', $this->sanitize_data($itunes->author), true); - add_post_meta($post_id, 'podcast_publish_date', $post_date, true); - add_post_meta($post_id, '_castpress_audio_url', $audio_url, true); - - // Add episode categories - if (!empty($podcast_importer_category)) { - if ($podcast_importer_post_type == 'podcast') { - wp_set_post_terms($post_id, $podcast_importer_category, 'series', false); - } else { - wp_set_post_terms($post_id, $podcast_importer_category, 'category', false); - } - } - - // Add episode image - if (isset($itunes) && isset($item)) { // Check again that feed is not empty - if ($podcast_importer_images == 'on') { - - // Grab image URL and file name - if ($itunes && $itunes->image && $itunes->image->attributes() && $itunes->image->attributes()->href) { - - $filename = basename(parse_url($itunes->image->attributes()->href)['path']); - $filename = (string)$filename; - - // Check if image does not exist in the database and upload it. Otherwise attach the existing image to the post - $query = "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_value LIKE '%$filename%'"; - $filename_count = intval($wpdb->get_var($query)); - - if ($filename_count == 0 || $match_image_filenames == false) { - $img_to_import = (string)$itunes->image->attributes()->href; - if (!post_exists($post_title, '', '', 'attachment') || $match_image_filenames == false) { - $attachment = get_page_by_title($post_title, OBJECT, 'attachment'); - if (empty($attachment) || $match_image_filenames == false) { - add_action('add_attachment', array($this, 'import_itunes_image')); - media_sideload_image($img_to_import, $post_id, $item->title); - remove_action('add_attachment', array($this, 'import_itunes_image')); - } - } - } else { - $get_upload_dir = wp_upload_dir()['baseurl'] . '/'; - $filename = pathinfo($filename, PATHINFO_FILENAME); // returns $filename with no extension - $query_path_to_file = "SELECT meta_value FROM {$wpdb->postmeta} WHERE (meta_key = '_wp_attached_file' AND meta_value LIKE '%$filename%')"; - $filename_path = $wpdb->get_var($query_path_to_file); - $filename_path = str_replace('-scaled', '', $filename_path); - $image_src = $get_upload_dir . $filename_path; - $image_id = $this->get_image_id($image_src); - set_post_thumbnail($post_id, $image_id); - } - } - } - } - - do_action('podcast_importer_after_post_import', $post_id, $podcast_importer_rss_feed, $item); - - $posts_added_count++; // Count successfully imported episodes - - } - } - } - - // Return success/error messages - if ($posts_added_count == 0 && $episode_count != 0) { // No episodes imported due to duplicated titles. - echo esc_html__('No new episodes imported, all episodes already existing in WordPress!', 'podcast-importer'); - echo '

' . esc_html__('If you have existing draft, private or trashed posts with the same title as your episodes, delete those and run the importer again', 'podcast-importer') . ''; - } elseif ($episode_count == 0) { // No episodes existing within feed. - echo esc_html__('Error! Your feed does not contain any episodes.', 'podcast-importer'); - } else { - echo '' . esc_html__('Success! Imported ', 'podcast-importer') . $posts_added_count . esc_html__(' out of ', 'podcast-importer') . $episode_count . esc_html__(' episodes', 'podcast-importer') . ''; - } - - // Check if scheduled import checked and already exists - if ($podcast_importer_continuous == 'on') { - if (0 === post_exists($this->sanitize_data($podcast_importer_rss_feed->channel->title), "", "", 'podcast_importer')) { - // Create new entry for the scheduled/ongoing import. - $import_post = array( - 'post_title' => $this->sanitize_data($podcast_importer_rss_feed->channel->title), - 'post_type' => 'podcast_importer', - 'post_status' => 'publish', - ); - $post_import_id = wp_insert_post($import_post); - add_post_meta($post_import_id, 'podcast_importer_rss_feed', $podcast_importer_rss_feed_url, true); - add_post_meta($post_import_id, 'podcast_importer_post_type', $podcast_importer_post_type, true); - add_post_meta($post_import_id, 'podcast_importer_publish', $podcast_importer_publish, true); - add_post_meta($post_import_id, 'podcast_importer_category', $podcast_importer_category, true); - add_post_meta($post_import_id, 'podcast_importer_images', $podcast_importer_images, true); - add_post_meta($post_import_id, 'podcast_importer_episode_number', $podcast_importer_episode_number, true); - add_post_meta($post_import_id, 'podcast_importer_author', $podcast_importer_author, true); - add_post_meta($post_import_id, 'podcast_importer_embed_player', $podcast_importer_embed_player, true); - add_post_meta($post_import_id, 'podcast_importer_content_tag', $podcast_importer_content_tag, true); - add_post_meta($post_import_id, 'podcast_importer_truncate_post', $podcast_importer_truncate_post, true); - add_post_meta($post_import_id, 'podcast_importer_prepend_title', $podcast_importer_prepend_title, true); - - } else { - echo '

' . esc_html__('This podcast is already being scheduled for import. Delete the previous schedule to create a new one.', 'podcast-importer') . '

'; - } - - // Set up cron job for imports - add_action('podcast_importer_cron', array($this, 'scheduled_podcast_import')); - - if (!wp_next_scheduled('podcast_importer_cron')) { - wp_schedule_event(current_time('timestamp'), 'hourly', 'podcast_importer_cron'); - } - } - } else { - echo '' . esc_html__('Podcast Feed Error! Please use a valid RSS feed URL.', 'podcast-importer') . ''; - } - } - } - - - function scheduled_podcast_import() - { - - // Load post.php class for post manipulations during cron - if ((!is_admin()) || (!function_exists('post_exists'))) { - require_once(ABSPATH . 'wp-admin/includes/post.php'); - } - - // Increase the time limit - set_time_limit(360); - - // Require relevant WordPress core files for processing images - require_once(ABSPATH . 'wp-admin/includes/media.php'); - require_once(ABSPATH . 'wp-admin/includes/file.php'); - require_once(ABSPATH . 'wp-admin/includes/image.php'); - - // Query all existing shceduled imports - global $wpdb; - global $blogloop; - global $post; - $args = array( - 'post_type' => 'podcast_importer', - 'post_status' => 'publish', - 'posts_per_page' => 999, - ); - - $blogloop = new \WP_Query($args); - - if ($blogloop->have_posts()) { - - while ($blogloop->have_posts()) { - - $blogloop->the_post(); - - // Grab pre-saved vars per post - $podcast_importer_rss_feed_url = get_post_meta($post->ID, 'podcast_importer_rss_feed', true); - $podcast_importer_post_type = get_post_meta($post->ID, 'podcast_importer_post_type', true); - $podcast_importer_publish = get_post_meta($post->ID, 'podcast_importer_publish', true); - $podcast_importer_category = get_post_meta($post->ID, 'podcast_importer_category', true); - $podcast_importer_images = get_post_meta($post->ID, 'podcast_importer_images', true); - $podcast_importer_episode_number = get_post_meta($post->ID, 'podcast_importer_episode_number', true); - $podcast_importer_author = get_post_meta($post->ID, 'podcast_importer_author', true); - $podcast_importer_embed_player = get_post_meta($post->ID, 'podcast_importer_embed_player', true); - $podcast_importer_content_tag = get_post_meta($post->ID, 'podcast_importer_content_tag', true); - $podcast_importer_truncate_post = get_post_meta($post->ID, 'podcast_importer_truncate_post', true); - $podcast_importer_prepend_title = get_post_meta($post->ID, 'podcast_importer_prepend_title', true); - - $podcast_importer_rss_feed = @simplexml_load_file($podcast_importer_rss_feed_url); - if (empty($podcast_importer_rss_feed) && !empty($podcast_importer_rss_feed_url)) { - $response = wp_remote_get($podcast_importer_rss_feed_url, [ - 'user-agent' => 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0', - ]); - $result = wp_remote_retrieve_body($response); - if (substr($result, 0, 5) == "channel->item); - - for ($i = 0; $i < $episode_count; $i++) { - - $item = $podcast_importer_rss_feed->channel->item[$i]; - $itunes = $item->children('http://www.itunes.com/dtds/podcast-1.0.dtd'); - $post_author = $podcast_importer_author; - $guid = $this->sanitize_data($item->guid); - $episode_number = $this->sanitize_data($itunes->episode); - $season_number = $this->sanitize_data($itunes->season); - - // Get episode duration (in seconds or text) and file size (in bytes) - $filesize = 0; // default value - $filesize = $item->enclosure['length']; - $filesize = '' . number_format($filesize / 1048576, 2) . 'M'; - $duration = $this->sanitize_data($itunes->duration); - if ((!empty($duration)) && (strpos($duration, ':') !== false)) - $duration = $duration; - elseif (!empty($duration)) { - $duration = gmdate("H:i:s", $duration); - } else { - $duration = ''; - } - - // Ensure posts are published right away (for server/feed timezone conflicts) - if (strtotime((string)$item->pubDate) < current_time('timestamp')) { - $timestamp_post_date = strtotime((string)$item->pubDate); - } else { - $timestamp_post_date = current_time('timestamp'); - } - - $post_date = date('Y-m-d H:i:s', $timestamp_post_date); - - - if (($podcast_importer_episode_number == 'on') && ($this->sanitize_data($itunes->episode) != '')) { - $post_title = $this->sanitize_data($itunes->episode) . ': ' . $this->sanitize_data($item->title); - } else { - $post_title = $this->sanitize_data($item->title); - } - - if (isset($podcast_importer_prepend_title)) { - $podcast_importer_prepend_title = str_replace('[podcast_title]', $this->sanitize_data($podcast_importer_rss_feed->channel->title), $podcast_importer_prepend_title); - - $post_title = $podcast_importer_prepend_title . ' ' . $post_title; - } - - // Set up audio as a shortcode and remove query variables - $audio_url = (string)$item->enclosure['url']; - $audio_url = preg_replace('/(?s:.*)(https?:\/\/(?:[\w\-\.]+[^#?\s]+)(?:\.mp3))(?s:.*)/', '$1', $audio_url); - $audio_url = preg_replace('/(?s:.*)(https?:\/\/(?:[\w\-\.]+[^#?\s]+)(?:\.m4a))(?s:.*)/', '$1', $audio_url); - $feed_link_url = (string)$item->link; - $host_checker = false; - $match_image_filenames = $this->match_image_names($podcast_importer_rss_feed_url); - if (!empty($feed_link_url)) { - $parsed_feed_url = parse_url($feed_link_url); - $parsed_feed_host = $parsed_feed_url['host']; - } else { - $parsed_feed_host = ''; - } - - if (($podcast_importer_embed_player == 'on') && (isset($parsed_feed_host) || isset($podcast_importer_rss_feed_url))) { - if (preg_match('/fireside.fm/i', $podcast_importer_rss_feed_url)) { - $feed_link_url = (string)$item->children('fireside', true)->playerEmbedCode; - } - if (preg_match('/omny.fm/i', $podcast_importer_rss_feed_url) || preg_match('/omnycontent.com/i', $podcast_importer_rss_feed_url)) { - $feed_link_url = (string)$item->children('media', true)->content->children('media', true)->player->attributes()->url; - } - $audio_shortcode = $this->embed_validator($parsed_feed_host, $feed_link_url, $audio_url, $podcast_importer_rss_feed_url, $guid); - $host_checker = $this->embed_host_checker($parsed_feed_host, $podcast_importer_rss_feed_url); - } else { - $audio_shortcode = '[audio src="' . esc_url($audio_url) . '"][/audio]'; - } - - // Set up the post content - if (!empty($item->children('itunes', true)->summary) && $podcast_importer_content_tag === 'itunes:summary') { - $parsed_content = $this->sanitize_data($item->children('itunes', true)->summary); - } elseif (!empty($item->children('itunes', true)->encoded) && $podcast_importer_content_tag === 'content:encoded') { - $parsed_content = $this->sanitize_data($item->children('content', true)->encoded); - } elseif (!empty($item->description) && $podcast_importer_content_tag === 'description') { - $parsed_content = $this->sanitize_data($item->description); - // If no preference cuts the mustard, try all the defaults - } elseif (!empty($item->children('content', true)->encoded)) { - $parsed_content = $this->sanitize_data($item->children('content', true)->encoded); - } elseif (!empty($item->description)) { - $parsed_content = $this->sanitize_data($item->description); - } else { - $parsed_content = $this->sanitize_data($itunes->summary); - } - - if ($podcast_importer_truncate_post) { - $parsed_content = substr($parsed_content, 0, intval($podcast_importer_truncate_post)); - } - - $post_content = $parsed_content; - - // Create the post content - $post = array( - 'post_author' => $post_author, - 'post_content' => $post_content, - 'post_date' => $post_date, - 'post_excerpt' => $this->sanitize_data($itunes->subtitle), - 'post_status' => $podcast_importer_publish, - 'post_title' => $post_title, - 'post_type' => $podcast_importer_post_type, - ); - - // Create the post - global $wpdb; - $post_id; - - // Check if post already exists, if so - skip. First we'll look for the GUID, then at the title. - if (!empty($guid) && $guid != '') { - $query = "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE (meta_key = 'podcast_importer_imported_guid' AND meta_value LIKE '%$guid%')"; - $guid_count = intval($wpdb->get_var($query)); - } else { - $guid_count = 0; - } - if ($guid_count == 0) { - - if (0 === post_exists($post_title, "", "", $podcast_importer_post_type)) { - - $post_id = wp_insert_post($post); - - // Continue if the import process errors - if (is_wp_error($post_id)) { - //continue; - } - - // Add GUID for each post - add_post_meta($post_id, 'podcast_importer_imported_guid', $guid, true); - add_post_meta($post_id, 'podcast_importer_episode_number', $episode_number, true); - add_post_meta($post_id, 'podcast_importer_season_number', $season_number, true); - add_post_meta($post_id, 'podcast_importer_external_embed', $audio_shortcode, true); - add_post_meta($post_id, 'podcast_audio_file', $audio_url, true); - add_post_meta($post_id, 'podcast_audio_url', $audio_url, true); - add_post_meta($post_id, 'podcast_duration', $duration, true); - add_post_meta($post_id, 'podcast_filesize', $filesize, true); - add_post_meta($post_id, 'podcast_enclosure', $audio_url, true); - add_post_meta($post_id, 'podcast_author', $this->sanitize_data($itunes->author), true); - add_post_meta($post_id, 'podcast_publish_date', $post_date, true); - add_post_meta($post_id, '_castpress_audio_url', $audio_url, true); - - // Add episode categories - if (!empty($podcast_importer_category)) { - if ($podcast_importer_post_type == 'podcast') { - wp_set_post_terms($post_id, $podcast_importer_category, 'series', false); - } else { - wp_set_post_terms($post_id, $podcast_importer_category, 'category', false); - } - } - - // Add episode image - if (isset($itunes) && isset($item)) { // Workaround for "Node no longer exists" error - if ($podcast_importer_images == 'on') { - - if ($itunes && $itunes->image && $itunes->image->attributes() && $itunes->image->attributes()->href) { - - $filename = basename(parse_url($itunes->image->attributes()->href)['path']); - $filename = (string)$filename; - - // Check if image does not exist in the database and upload it. Otherwise attach the existing image to the post - $query = "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_value LIKE '%$filename%'"; - $filename_count = intval($wpdb->get_var($query)); - if ($filename_count == 0 || $match_image_filenames == false) { - $img_to_import = (string)$itunes->image->attributes()->href; - if (!post_exists($post_title, '', '', 'attachment') || $match_image_filenames == false) { - $attachment = get_page_by_title($post_title, OBJECT, 'attachment'); - if (empty($attachment) || $match_image_filenames == false) { - add_action('add_attachment', array($this, 'import_itunes_image')); - media_sideload_image($img_to_import, $post_id, $item->title); - remove_action('add_attachment', array($this, 'import_itunes_image')); - } - } - } else { - $get_upload_dir = wp_upload_dir()['baseurl'] . '/'; - $filename = pathinfo($filename, PATHINFO_FILENAME); // returns $filename with no extension - $query_path_to_file = "SELECT meta_value FROM {$wpdb->postmeta} WHERE (meta_key = '_wp_attached_file' AND meta_value LIKE '%$filename%')"; - $filename_path = $wpdb->get_var($query_path_to_file); - $filename_path = str_replace('-scaled', '', $filename_path); - $image_src = $get_upload_dir . $filename_path; - $image_id = $this->get_image_id($image_src); - set_post_thumbnail($post_id, $image_id); - } - } - } - } - - do_action('podcast_importer_after_post_scheduled_import', $post_id, $podcast_importer_rss_feed, $item); - } - } - } - } - } - } - } - - - // Grab the images and save the image id with the post - function import_itunes_image($att_id) - { - $post_img = get_post($att_id); - update_post_meta($post_img->post_parent, '_thumbnail_id', $att_id); - } - - // Get image ID by URL - function get_image_id($image_url) - { - global $wpdb; - $attachment = $wpdb->get_col($wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE guid='%s';", $image_url)); - if (!empty($attachment)) { - return $attachment[0]; - } - } - - // Query post types and list as options - function post_type_control($value) - { - $cpts = get_post_types(array('public' => true, 'show_in_nav_menus' => true)); - $exclude_cpts = array('elementor_library', 'podcast_importer', 'attachment', 'product', 'page'); - - foreach ($exclude_cpts as $exclude_cpt) { - unset($cpts[$exclude_cpt]); - } - - foreach ($cpts as $cpt) { - $selected = $value === $cpt ? ' selected' : ''; - echo '' . esc_html($cpt) . ''; - } - } - - // Query categories and list as options - function list_categories($values) - { - if (function_exists('ssp_episodes')) { - $args = array('taxonomy' => 'series', 'hide_empty' => false,); - } else { - $args = array('taxonomy' => 'category', 'hide_empty' => false,); - } - - $cats = get_categories($args); - foreach ($cats as $cat) { - if (is_array($values)) { - $selected = in_array($cat->term_id, $values) ? ' selected' : ''; - } else { - $selected = ''; - } - echo '' . esc_html($cat->name) . ''; - } - } - - // Return an embed audio player depending on the podcast hosting provider - function embed_validator($parsed_feed_host, $embed_url, $audio_url, $rss_feed_url, $guid) - { - if (strpos($parsed_feed_host, 'transistor.fm') !== false) { - - $fixed_share_url = str_replace('/s/', '/e/', $embed_url); - $audio_shortcode = ''; - - } elseif (strpos($parsed_feed_host, 'anchor.fm') !== false) { - - $fixed_share_url = str_replace('/episodes/', '/embed/episodes/', $embed_url); - $audio_shortcode = ''; - - } elseif (strpos($parsed_feed_host, 'simplecast.com') !== false) { - - $simplecast_response = wp_remote_get('https://api.simplecast.com/oembed?url=' . rawurlencode($embed_url)); - $simplecast_json = json_decode($simplecast_response['body'], true); - $simplecast_html = $simplecast_json['html']; - preg_match('/src="([^"]+)"/', $simplecast_html, $match); - $fixed_share_url = $match[1]; - $audio_shortcode = ''; - - } elseif (strpos($parsed_feed_host, 'whooshkaa.com') !== false) { - - $whooshkaa_audio_id = substr($embed_url, strpos($embed_url, "?id=") + 4); - $fixed_share_url = 'https://webplayer.whooshkaa.com/player/episode/id/' . $whooshkaa_audio_id . '?theme=light'; - $audio_shortcode = ''; - - } elseif ((strpos($rss_feed_url, 'omny.fm') !== false) || (strpos($rss_feed_url, 'omnycontent.com') !== false)) { - - $audio_shortcode = ''; - - } elseif (strpos($parsed_feed_host, 'podbean.com') !== false) { - - $audio_shortcode = wp_oembed_get(esc_url($embed_url)); // oEmbed - - } elseif (strpos($rss_feed_url, 'megaphone.fm') !== false) { - $megaphone_audio_link = explode('megaphone.fm/', $audio_url); - $megaphone_audio_id = explode('.', $megaphone_audio_link[1]); - $fixed_share_url = 'https://playlist.megaphone.fm/?e=' . $megaphone_audio_id[0]; - $audio_shortcode = ''; - - } elseif (strpos($rss_feed_url, 'captivate.fm') !== false) { - $captivate_audio_link = explode('media/', $audio_url); - $captivate_audio_id = explode('/', $captivate_audio_link[1]); - $fixed_share_url = 'https://player.captivate.fm/episode/' . $captivate_audio_id[0]; - $audio_shortcode = ''; - - } elseif (strpos($audio_url, 'buzzsprout.com') !== false) { - $buzzsprout_audio_url = explode('.mp3', $audio_url); - $fixed_share_url = $buzzsprout_audio_url[0] . '?iframe=true'; - $audio_shortcode = ''; - - } elseif (strpos($audio_url, 'pinecast.com') !== false) { - $pinecast_audio_url = explode('.mp3', $audio_url); - $pinecast_episode_url = str_replace('/listen/', '/player/', $pinecast_audio_url[0]); - $fixed_share_url = $pinecast_episode_url . '?theme=flat'; - $audio_shortcode = ''; - - } elseif (strpos($rss_feed_url, 'feed.ausha.co') !== false) { - $ausha_audio_link = explode('audio.ausha.co/', $audio_url); - $ausha_audio_id = explode('.mp3', $ausha_audio_link[1]); - $podcastId = $ausha_audio_id[0]; - $fixed_share_url = 'https://widget.ausha.co/index.html?podcastId=' . $podcastId . '&display=horizontal&v=2'; - $audio_shortcode = ''; - - } elseif (strpos($rss_feed_url, 'spreaker.com') !== false) { - $fixed_share_url = explode('/episode/', $guid); - if (isset($fixed_share_url[1])) { - $fixed_share_url = 'https://widget.spreaker.com/player?episode_id=' . $fixed_share_url[1]; - $audio_shortcode = ''; - } else { - $audio_shortcode = '[audio src="' . esc_url($audio_url) . '"][/audio]'; - } - - } elseif (strpos($rss_feed_url, 'fireside.fm') !== false) { - $audio_shortcode = $embed_url . ''; - - } elseif (strpos($rss_feed_url, 'libsyn.com') !== false) { - $fixed_share_url = 'https://html5-player.libsyn.com/embed/episode/id/' . $embed_url; - $audio_shortcode = ''; - - } elseif (strpos($rss_feed_url, 'audioboom.com') !== false) { - $fixed_share_url = str_replace('/posts/', '/boos/', $embed_url); - $audio_shortcode = ''; - - } else { - - $audio_shortcode = '[audio src="' . esc_url($audio_url) . '"][/audio]'; - - } - - return $audio_shortcode; - } - - function embed_host_checker($parsed_feed_host, $rss_feed_url) - { - if ((preg_match('/transistor.fm|anchor.fm|fireside.fm|simplecast.com|spreaker.com|whooshkaa.com|omny.fm|omnycontent.com|megaphone.fm|podbean.com/i', $parsed_feed_host)) || (preg_match('/megaphone.fm|captivate.fm|ausha.co|omny.fm|omnycontent.com|pinecast.com|audioboom.com|buzzsprout.com/i', $rss_feed_url))) { - $host_checker = true; - } else { - $host_checker = false; - } - return $host_checker; - } - - function match_image_names($rss_feed_url) - { - if (preg_match('/buzzsprout.com|omny.fm|omnycontent.com/i', $rss_feed_url)) { - $match_image_filenames = false; - } else { - $match_image_filenames = true; - } - return $match_image_filenames; - } - - // Parse and sanitize data from RSS/XML - function sanitize_data($data) - { - $content = array(); - - trim((string)$data); - $data = str_replace(" ", "", $data); - if (preg_match('/^$/is', $data, $content)) { - $data = $content[1]; - } else { - $data = html_entity_decode($data); - } - - return $data; - } - -} \ No newline at end of file diff --git a/inc/admin/admin.php b/inc/admin/admin.php new file mode 100644 index 0000000..18f3ad1 --- /dev/null +++ b/inc/admin/admin.php @@ -0,0 +1,240 @@ +' . esc_attr__('Settings', 'podcast-importer') . ''; + array_push($links, $settings_link); + return $links; + } + + /** + * Add Iframe Tags in Kse Update WordPress Content + * + * @see https://developer.wordpress.org/reference/functions/wp_kses_allowed_html/ + * @param $tags + * @param $context + * @return mixed + */ + public function podcastImporterAllowIframe($tags, $context) + { + if ('post' === $context) { + $tags['iframe'] = array( + 'src' => true, + 'height' => true, + 'width' => true, + 'style' => true, + 'frameborder' => true, + 'allowfullscreen' => true, + 'scrolling' => true, + 'seamless' => true, + ); + } + return $tags; + } + + /** + * oEmbed discovery is enabled for all users and allows embedding of sanitized iframes + * @see https://developer.wordpress.org/reference/hooks/oembed_providers/ + * @param $providers + * @return mixed + */ + public function podcastImporterOembedProviders($providers) + { + $providers['#https?://(.+).podbean.com/e/.+#i'] = array('https://api.podbean.com/v1/oembed', true); + return $providers; + } +} + +new Admin(); \ No newline at end of file diff --git a/inc/admin/views/settings.php b/inc/admin/views/settings.php new file mode 100644 index 0000000..ead662a --- /dev/null +++ b/inc/admin/views/settings.php @@ -0,0 +1,127 @@ +
+ + + + + +
+ + + + +
+ + + + 'podcast_importer_author', + 'selected' => get_post_meta($post_id_to_update, 'podcast_importer_author', true) + )); ?> + +
+ + + + +
+ +
+ + + type="checkbox" + id="_podcast_importer_images" + name="podcast_importer_images"/> + +
+ +
+ + type="checkbox" + id="_podcast_importer_embed_player" + name="podcast_importer_embed_player"/> + +
+ +
+

+
+ + + + + + +
+ + + type="checkbox" + id="_podcast_importer_episode_number" + name="podcast_importer_episode_number"/> + +
+ + + +
+
+ +
+ + + + + + + + + + + + +
\ No newline at end of file diff --git a/inc/admin/views/tools.php b/inc/admin/views/tools.php new file mode 100644 index 0000000..7909c26 --- /dev/null +++ b/inc/admin/views/tools.php @@ -0,0 +1,22 @@ +
+
+

+ +

+ + +
+ +
+text_domain = $text_domain; + + /* + * Load Plugin Text Domain + */ + add_action('init', array($this, 'i18n')); + } + + /** + * Loads translation file. + * + * Accessible to other classes to load different language files (admin and + * front-end for example). + * + * @wp-hook init + * @return void + */ + public function i18n() + { + load_plugin_textdomain($this->text_domain, false, wp_normalize_path(\WP_PODCAST_IMPORTER::$plugin_path . '/languages')); + } + +} \ No newline at end of file diff --git a/inc/config/install.php b/inc/config/install.php new file mode 100644 index 0000000..7a00405 --- /dev/null +++ b/inc/config/install.php @@ -0,0 +1,12 @@ + 'post', + 'post_status' => 'publish', + 'posts_per_page' => '-1', + 'order' => 'ASC', + 'fields' => 'ids', + 'cache_results' => false, + 'no_found_rows' => true, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'suppress_filters' => true + ); + $args = wp_parse_args($arg, $default); + + // Get Data + $query = new \WP_Query($args); + + // Added To List + foreach ($query->posts as $ID) { + $list[] = $ID; + } + + return $list; + } + + public static function LoadMediaCoreWordPressHelper() + { + require_once(ABSPATH . 'wp-admin/includes/post.php'); + require_once(ABSPATH . 'wp-admin/includes/media.php'); + require_once(ABSPATH . 'wp-admin/includes/file.php'); + require_once(ABSPATH . 'wp-admin/includes/image.php'); + } + + public static function getUploadDir() + { + return wp_upload_dir(); + } + + public static function getRssFeedPodCast($podcast_importer_rss_feed_url) + { + $podcast_importer_rss_feed = @simplexml_load_file($podcast_importer_rss_feed_url); + if (empty($podcast_importer_rss_feed) && !empty($podcast_importer_rss_feed_url)) { + $response = wp_remote_get($podcast_importer_rss_feed_url, [ + 'user-agent' => 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20100101 Firefox/17.0', + ]); + $result = wp_remote_retrieve_body($response); + if (substr($result, 0, 5) == "postmeta} WHERE (meta_key = '_wp_attached_file' AND meta_value LIKE '%$filename%')"; + $filename_path = $wpdb->get_var($query_path_to_file); + $filename_path = str_replace('-scaled', '', $filename_path); + $image_src = $get_upload_dir . $filename_path; + $image_id = Helper::getImageIDByUrl($image_src); + if (!is_null($image_id)) { + set_post_thumbnail($post_id, $image_id); + } + } + + public static function parseContent($item, $podcast_importer_content_tag, $itunes) + { + if (!empty($item->children('itunes', true)->summary) && $podcast_importer_content_tag === 'itunes:summary') { + $parsed_content = Helper::sanitizeData($item->children('itunes', true)->summary); + } elseif (!empty($item->children('itunes', true)->encoded) && $podcast_importer_content_tag === 'content:encoded') { + $parsed_content = Helper::sanitizeData($item->children('content', true)->encoded); + } elseif (!empty($item->description) && $podcast_importer_content_tag === 'description') { + $parsed_content = Helper::sanitizeData($item->description); + // If no preference cuts the mustard, try all the defaults + } elseif (!empty($item->children('content', true)->encoded)) { + $parsed_content = Helper::sanitizeData($item->children('content', true)->encoded); + } elseif (!empty($item->description)) { + $parsed_content = Helper::sanitizeData($item->description); + } else { + $parsed_content = Helper::sanitizeData($itunes->summary); + } + + return $parsed_content; + } + + public static function sanitizeAudioUrl($audio_url) + { + $audio_url = preg_replace('/(?s:.*)(https?:\/\/(?:[\w\-\.]+[^#?\s]+)(?:\.mp3))(?s:.*)/', '$1', $audio_url); + $audio_url = preg_replace('/(?s:.*)(https?:\/\/(?:[\w\-\.]+[^#?\s]+)(?:\.m4a))(?s:.*)/', '$1', $audio_url); + return $audio_url; + } + + public static function getImageIDByUrl($image_url) + { + global $wpdb; + $attachment = $wpdb->get_col( + $wpdb->prepare("SELECT ID FROM $wpdb->posts WHERE guid='%s';", $image_url) + ); + if (!empty($attachment)) { + return $attachment[0]; + } + + return null; + } + + public static function postTypeControl($value) + { + $cpts = get_post_types( + array( + 'public' => true, + 'show_in_nav_menus' => true + ) + ); + $exclude_cpts = array('elementor_library', 'podcast_importer', 'attachment', 'product', 'page'); + foreach ($exclude_cpts as $exclude_cpt) { + unset($cpts[$exclude_cpt]); + } + foreach ($cpts as $cpt) { + $selected = $value === $cpt ? ' selected' : ''; + echo '' . esc_html($cpt) . ''; + } + } + + public static function listTerms($values) + { + $args = array('taxonomy' => 'category', 'hide_empty' => false,); + $cats = get_categories($args); + foreach ($cats as $cat) { + if (is_array($values)) { + $selected = in_array($cat->term_id, $values) ? ' selected' : ''; + } else { + $selected = ''; + } + echo '' . esc_html($cat->name) . ''; + } + } + + public static function embedValidator($parsed_feed_host, $embed_url, $audio_url, $rss_feed_url, $guid) + { + if (strpos($parsed_feed_host, 'transistor.fm') !== false) { + + $fixed_share_url = str_replace('/s/', '/e/', $embed_url); + $audio_shortcode = ''; + + } elseif (strpos($parsed_feed_host, 'anchor.fm') !== false) { + + $fixed_share_url = str_replace('/episodes/', '/embed/episodes/', $embed_url); + $audio_shortcode = ''; + + } elseif (strpos($parsed_feed_host, 'simplecast.com') !== false) { + + $simplecast_response = wp_remote_get('https://api.simplecast.com/oembed?url=' . rawurlencode($embed_url)); + $simplecast_json = json_decode($simplecast_response['body'], true); + $simplecast_html = $simplecast_json['html']; + preg_match('/src="([^"]+)"/', $simplecast_html, $match); + $fixed_share_url = $match[1]; + $audio_shortcode = ''; + + } elseif (strpos($parsed_feed_host, 'whooshkaa.com') !== false) { + + $whooshkaa_audio_id = substr($embed_url, strpos($embed_url, "?id=") + 4); + $fixed_share_url = 'https://webplayer.whooshkaa.com/player/episode/id/' . $whooshkaa_audio_id . '?theme=light'; + $audio_shortcode = ''; + + } elseif ((strpos($rss_feed_url, 'omny.fm') !== false) || (strpos($rss_feed_url, 'omnycontent.com') !== false)) { + + $audio_shortcode = ''; + + } elseif (strpos($parsed_feed_host, 'podbean.com') !== false) { + + $audio_shortcode = wp_oembed_get(esc_url($embed_url)); // oEmbed + + } elseif (strpos($rss_feed_url, 'megaphone.fm') !== false) { + $megaphone_audio_link = explode('megaphone.fm/', $audio_url); + $megaphone_audio_id = explode('.', $megaphone_audio_link[1]); + $fixed_share_url = 'https://playlist.megaphone.fm/?e=' . $megaphone_audio_id[0]; + $audio_shortcode = ''; + + } elseif (strpos($rss_feed_url, 'captivate.fm') !== false) { + $captivate_audio_link = explode('media/', $audio_url); + $captivate_audio_id = explode('/', $captivate_audio_link[1]); + $fixed_share_url = 'https://player.captivate.fm/episode/' . $captivate_audio_id[0]; + $audio_shortcode = ''; + + } elseif (strpos($audio_url, 'buzzsprout.com') !== false) { + $buzzsprout_audio_url = explode('.mp3', $audio_url); + $fixed_share_url = $buzzsprout_audio_url[0] . '?iframe=true'; + $audio_shortcode = ''; + + } elseif (strpos($audio_url, 'pinecast.com') !== false) { + $pinecast_audio_url = explode('.mp3', $audio_url); + $pinecast_episode_url = str_replace('/listen/', '/player/', $pinecast_audio_url[0]); + $fixed_share_url = $pinecast_episode_url . '?theme=flat'; + $audio_shortcode = ''; + + } elseif (strpos($rss_feed_url, 'feed.ausha.co') !== false) { + $ausha_audio_link = explode('audio.ausha.co/', $audio_url); + $ausha_audio_id = explode('.mp3', $ausha_audio_link[1]); + $podcastId = $ausha_audio_id[0]; + $fixed_share_url = 'https://widget.ausha.co/index.html?podcastId=' . $podcastId . '&display=horizontal&v=2'; + $audio_shortcode = ''; + + } elseif (strpos($rss_feed_url, 'spreaker.com') !== false) { + $fixed_share_url = explode('/episode/', $guid); + if (isset($fixed_share_url[1])) { + $fixed_share_url = 'https://widget.spreaker.com/player?episode_id=' . $fixed_share_url[1]; + $audio_shortcode = ''; + } else { + $audio_shortcode = '[audio src="' . esc_url($audio_url) . '"][/audio]'; + } + + } elseif (strpos($rss_feed_url, 'fireside.fm') !== false) { + $audio_shortcode = $embed_url . ''; + + } elseif (strpos($rss_feed_url, 'libsyn.com') !== false) { + $fixed_share_url = 'https://html5-player.libsyn.com/embed/episode/id/' . $embed_url; + $audio_shortcode = ''; + + } elseif (strpos($rss_feed_url, 'audioboom.com') !== false) { + $fixed_share_url = str_replace('/posts/', '/boos/', $embed_url); + $audio_shortcode = ''; + + } else { + + $audio_shortcode = '[audio src="' . esc_url($audio_url) . '"][/audio]'; + + } + + return $audio_shortcode; + } + + public static function embedHostChecker($parsed_feed_host, $rss_feed_url) + { + if ((preg_match('/transistor.fm|anchor.fm|fireside.fm|simplecast.com|spreaker.com|whooshkaa.com|omny.fm|omnycontent.com|megaphone.fm|podbean.com/i', $parsed_feed_host)) || (preg_match('/megaphone.fm|captivate.fm|ausha.co|omny.fm|omnycontent.com|pinecast.com|audioboom.com|buzzsprout.com/i', $rss_feed_url))) { + $host_checker = true; + } else { + $host_checker = false; + } + return $host_checker; + } + + public static function matchImageNames($rss_feed_url) + { + if (preg_match('/buzzsprout.com|omny.fm|omnycontent.com/i', $rss_feed_url)) { + $match_image_filenames = false; + } else { + $match_image_filenames = true; + } + return $match_image_filenames; + } + + public static function sanitizeData($data) + { + $content = array(); + + trim((string)$data); + $data = str_replace(" ", "", $data); + if (preg_match('/^$/is', $data, $content)) { + $data = $content[1]; + } else { + $data = html_entity_decode($data); + } + + return $data; + } +} + +new Helper(); diff --git a/inc/process.php b/inc/process.php new file mode 100644 index 0000000..3c56efc --- /dev/null +++ b/inc/process.php @@ -0,0 +1,255 @@ +channel->item); + for ($i = 0; $i < $episode_count; $i++) { + + $item = $podcast_importer_rss_feed->channel->item[$i]; + $itunes = $item->children('http://www.itunes.com/dtds/podcast-1.0.dtd'); + $guid = Helper::sanitizeData($item->guid); + $episode_number = Helper::sanitizeData($itunes->episode); + $season_number = Helper::sanitizeData($itunes->season); + + // Get episode duration (in seconds or text) and file size (in bytes) + $filesize = 0; + $filesize = $item->enclosure['length']; + $filesize = '' . number_format($filesize / 1048576, 2) . 'M'; + $duration = Helper::sanitizeData($itunes->duration); + if ((!empty($duration)) && (strpos($duration, ':') !== false)) + $duration = $duration; + elseif (!empty($duration)) { + $duration = gmdate("H:i:s", $duration); + } else { + $duration = ''; + } + + // Ensure posts are published right away (for server/feed timezone conflicts) + if (strtotime((string)$item->pubDate) < current_time('timestamp')) { + $timestamp_post_date = strtotime((string)$item->pubDate); + } else { + $timestamp_post_date = current_time('timestamp'); + } + $post_date = date('Y-m-d H:i:s', $timestamp_post_date); + + if (($podcast_importer_episode_number == 'on') && (Helper::sanitizeData($itunes->episode) != '')) { + $post_title = Helper::sanitizeData($itunes->episode) . ': ' . Helper::sanitizeData($item->title); + } else { + $post_title = Helper::sanitizeData($item->title); + } + + if (isset($podcast_importer_prepend_title)) { + $podcast_importer_prepend_title = str_replace('[podcast_title]', Helper::sanitizeData($podcast_importer_rss_feed->channel->title), $podcast_importer_prepend_title); + $post_title = $podcast_importer_prepend_title . ' ' . $post_title; + } + + // Set up audio as a shortcode and remove query variables + $audio_url = Helper::sanitizeAudioUrl((string)$item->enclosure['url']); + $feed_link_url = (string)$item->link; + $host_checker = false; + $match_image_filenames = Helper::matchImageNames($podcast_importer_rss_feed_url); + if (!empty($feed_link_url)) { + $parsed_feed_url = parse_url($feed_link_url); + $parsed_feed_host = $parsed_feed_url['host']; + } else { + $parsed_feed_host = ''; + } + + if (($podcast_importer_embed_player == 'on') && (isset($parsed_feed_host) || isset($podcast_importer_rss_feed_url))) { + if (preg_match('/fireside.fm/i', $podcast_importer_rss_feed_url)) { + $feed_link_url = (string)$item->children('fireside', true)->playerEmbedCode; + } + if (preg_match('/omny.fm/i', $podcast_importer_rss_feed_url) || preg_match('/omnycontent.com/i', $podcast_importer_rss_feed_url)) { + $feed_link_url = (string)$item->children('media', true)->content->children('media', true)->player->attributes()->url; + } + if (preg_match('/libsyn.com/i', $podcast_importer_rss_feed_url) || preg_match('/omnycontent.com/i', $podcast_importer_rss_feed_url)) { + $feed_link_url = (string)$item->children('libsyn', true)->itemId; + } + $audio_shortcode = Helper::embedValidator($parsed_feed_host, $feed_link_url, $audio_url, $podcast_importer_rss_feed_url, $guid); + $host_checker = Helper::embedHostChecker($parsed_feed_host, $podcast_importer_rss_feed_url); + } else { + $audio_shortcode = '[audio src="' . esc_url($audio_url) . '"][/audio]'; + } + + // Grab the content + $parsed_content = Helper::parseContent($item, $podcast_importer_content_tag, $itunes); + if ($podcast_importer_truncate_post) { + $parsed_content = substr($parsed_content, 0, intval($podcast_importer_truncate_post)); + } + $post_content = $parsed_content; + + // Check if post already exists, if so - skip. First we'll look for the GUID, then at the title. + if (!empty($guid) && $guid != '') { + $query = "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE (meta_key = 'podcast_importer_imported_guid' AND meta_value LIKE '%$guid%')"; + $guid_count = intval($wpdb->get_var($query)); + } else { + $guid_count = 0; + } + if ($guid_count == 0) { + if (0 === post_exists($post_title, "", "", $podcast_importer_post_type)) { + + // Create Post + $post_id = wp_insert_post(array( + 'post_author' => $podcast_importer_author, + 'post_content' => $post_content, + 'post_date' => $post_date, + 'post_excerpt' => Helper::sanitizeData($itunes->subtitle), + 'post_status' => $podcast_importer_publish, + 'post_type' => $podcast_importer_post_type, + 'post_title' => $post_title, + )); + + // Continue if the import generate errors + if (is_wp_error($post_id)) { + continue; + } + + // Add GUID for each post + update_post_meta($post_id, 'podcast_importer_imported_guid', $guid, true); + update_post_meta($post_id, 'podcast_importer_episode_number', $episode_number, true); + update_post_meta($post_id, 'podcast_importer_season_number', $season_number, true); + update_post_meta($post_id, 'podcast_importer_external_embed', $audio_shortcode, true); + update_post_meta($post_id, 'podcast_audio_file', $audio_url, true); + update_post_meta($post_id, 'podcast_audio_url', $audio_url, true); + update_post_meta($post_id, 'podcast_duration', $duration, true); + update_post_meta($post_id, 'podcast_filesize', $filesize, true); + update_post_meta($post_id, 'podcast_enclosure', $audio_url, true); + update_post_meta($post_id, 'podcast_author', Helper::sanitizeData($itunes->author), true); + update_post_meta($post_id, 'podcast_publish_date', $post_date, true); + update_post_meta($post_id, '_castpress_audio_url', $audio_url, true); + + // Add episode categories + if (!empty($podcast_importer_category)) { + if ($podcast_importer_post_type == 'podcast') { + wp_set_post_terms($post_id, $podcast_importer_category, 'series', false); + } else { + wp_set_post_terms($post_id, $podcast_importer_category, 'category', false); + } + } + + // Add episode image + if (isset($itunes) && isset($item)) { // Check again that feed is not empty + if ($podcast_importer_images == 'on') { + + // Grab image URL and file name + if ($itunes && $itunes->image && $itunes->image->attributes() && $itunes->image->attributes()->href) { + + $filename = basename(parse_url($itunes->image->attributes()->href)['path']); + $filename = (string)$filename; + + // Check if image does not exist in the database and upload it. Otherwise attach the existing image to the post + $query = "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_value LIKE '%$filename%'"; + $filename_count = intval($wpdb->get_var($query)); + + if ($filename_count == 0 || $match_image_filenames == false) { + $img_to_import = (string)$itunes->image->attributes()->href; + if (!post_exists($post_title, '', '', 'attachment') || $match_image_filenames == false) { + $attachment = get_page_by_title($post_title, OBJECT, 'attachment'); + if (empty($attachment) || $match_image_filenames == false) { + add_action('add_attachment', array(__CLASS__, 'importItunesImage')); + media_sideload_image($img_to_import, $post_id, $item->title); + remove_action('add_attachment', array(__CLASS__, 'importItunesImage')); + } + } + } else { + + // Set Post Thumbnail + Helper::setPostThumbnail($filename, $post_id); + } + } + } + } + + do_action('action_after_podcast_import', $post_id, $podcast_importer_rss_feed, $item); + $posts_added_count++; + } + } + } + + // Return success/error messages + if ($posts_added_count == 0 && $episode_count != 0) { // No episodes imported due to duplicated titles. + echo esc_html__('No new episodes imported, all episodes already existing in WordPress!', 'podcast-importer'); + echo '

' . esc_html__('If you have existing draft, private or trashed posts with the same title as your episodes, delete those and run the importer again', 'podcast-importer') . ''; + } elseif ($episode_count == 0) { // No episodes existing within feed. + echo esc_html__('Error! Your feed does not contain any episodes.', 'podcast-importer'); + } else { + echo '' . esc_html__('Success! Imported ', 'podcast-importer') . $posts_added_count . esc_html__(' out of ', 'podcast-importer') . $episode_count . esc_html__(' episodes', 'podcast-importer') . ''; + } + + } else { + echo '' . esc_html__('Podcast Feed Error! Please use a valid RSS feed URL.', 'podcast-importer') . ''; + } + } + + public static function importItunesImage($att_id) + { + $post_img = get_post($att_id); + update_post_meta($post_img->post_parent, '_thumbnail_id', $att_id); + } +} + +new Process(); \ No newline at end of file diff --git a/includes/class-podcast-importer-activator.php b/includes/class-podcast-importer-activator.php deleted file mode 100644 index 2b1b179..0000000 --- a/includes/class-podcast-importer-activator.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * @package Persist Admin notices Dismissal - * @author Collins Agbonghama - * @author Andy Fragen - * @license http://www.gnu.org/licenses GNU General Public License - * @version 1.4.1 - */ - -/** - * Exit if called directly. - */ -if ( ! defined( 'ABSPATH' ) ) { - die; -} - -if ( ! class_exists( 'PAnD' ) ) { - - /** - * Class PAnD - */ - class PAnD { - - /** - * Init hooks. - */ - public static function init() { - add_action( 'admin_enqueue_scripts', array( __CLASS__, 'load_script' ) ); - add_action( 'wp_ajax_dismiss_admin_notice', array( __CLASS__, 'dismiss_admin_notice' ) ); - } - - /** - * Enqueue javascript and variables. - */ - public static function load_script() { - - if ( is_customize_preview() ) { - return; - } - - wp_enqueue_script( - 'dismissible-notices', - plugins_url( 'dismiss-notice.js', __FILE__ ), - array( 'jquery', 'common' ), - false, - true - ); - - wp_localize_script( - 'dismissible-notices', - 'dismissible_notice', - array( - 'nonce' => wp_create_nonce( 'dismissible-notice' ), - ) - ); - } - - /** - * Handles Ajax request to persist notices dismissal. - * Uses check_ajax_referer to verify nonce. - */ - public static function dismiss_admin_notice() { - $option_name = sanitize_text_field( $_POST['option_name'] ); - $dismissible_length = sanitize_text_field( $_POST['dismissible_length'] ); - - if ( 'forever' != $dismissible_length ) { - // If $dismissible_length is not an integer default to 1 - $dismissible_length = ( 0 == absint( $dismissible_length ) ) ? 1 : $dismissible_length; - $dismissible_length = strtotime( absint( $dismissible_length ) . ' days' ); - } - - check_ajax_referer( 'dismissible-notice', 'nonce' ); - self::set_admin_notice_cache( $option_name, $dismissible_length ); - wp_die(); - } - - /** - * Is admin notice active? - * - * @param string $arg data-dismissible content of notice. - * - * @return bool - */ - public static function is_admin_notice_active( $arg ) { - $array = explode( '-', $arg ); - $length = array_pop( $array ); - $option_name = implode( '-', $array ); - $db_record = self::get_admin_notice_cache( $option_name ); - if ( 'forever' == $db_record ) { - return false; - } elseif ( absint( $db_record ) >= time() ) { - return false; - } else { - return true; - } - } - - /** - * Returns admin notice cached timeout. - * - * @access public - * - * @param string|bool $id admin notice name or false. - * - * @return array|bool The timeout. False if expired. - */ - public static function get_admin_notice_cache( $id = false ) { - if ( ! $id ) { - return false; - } - $cache_key = 'pand-' . md5( $id ); - $timeout = get_site_option( $cache_key ); - $timeout = 'forever' === $timeout ? time() + 60 : $timeout; - - if ( empty( $timeout ) || time() > $timeout ) { - return false; - } - - return $timeout; - } - - /** - * Sets admin notice timeout in site option. - * - * @access public - * - * @param string $id Data Identifier. - * @param string|bool $timeout Timeout for admin notice. - * - * @return bool - */ - public static function set_admin_notice_cache( $id, $timeout ) { - $cache_key = 'pand-' . md5( $id ); - update_site_option( $cache_key, $timeout ); - - return true; - } - - } - -} diff --git a/includes/index.php b/includes/index.php deleted file mode 100644 index e71af0e..0000000 --- a/includes/index.php +++ /dev/null @@ -1 +0,0 @@ - true, - 'height' => true, - 'width' => true, - 'style' => true, - 'frameborder' => true, - 'allowfullscreen' => true, - 'scrolling' => true, - 'seamless' => true, - ); - } - return $tags; -} - -add_filter('wp_kses_allowed_html', 'podcast_importer_allow_iframe', 10, 2); - -/** - * Add oEmbed providers - */ -function podcast_importer_oembed_providers($providers) -{ - $providers['#https?://(.+).podbean.com/e/.+#i'] = array('https://api.podbean.com/v1/oembed', true); - return $providers; -} - -add_filter('oembed_providers', 'podcast_importer_oembed_providers'); - -/* Add 'Setting' link to plugins page */ -function podcast_importer_add_settings_link($links) -{ - $settings_link = '' . esc_attr__('Settings', 'podcast-importer') . ''; - array_push($links, $settings_link); - return $links; -} - -$plugin = plugin_basename(__FILE__); -add_filter("plugin_action_links_$plugin", 'podcast_importer_add_settings_link'); - - -/** - * The core plugin class that is used to define internationalization, - * admin-specific hooks - */ -require plugin_dir_path(__FILE__) . 'class-podcast-importer.php'; - -/** - * Begins execution of the plugin. - * - * Since everything within the plugin is registered via hooks, - * then kicking off the plugin from this point in the file does - * not affect the page life cycle. - * - * @since 1.0.0 - */ -function podcast_importer() -{ - new Podcast_Importer(); -} - -podcast_importer(); +min_php, '<=')) { + add_action('admin_notices', array($this, 'php_version_notice')); + return; + } + + /* + * Define Variable + */ + $this->define_constants(); + + /* + * include files + */ + $this->includes(); + + /* + * init Wordpress hook + */ + $this->init_hooks(); + + /* + * Plugin Loaded Action + */ + do_action('wp_podcast_importer_loaded'); + } + + /** + * Define Constant + */ + public function define_constants() + { + + /* + * Get Plugin Data + */ + if (!function_exists('get_plugin_data')) { + require_once(ABSPATH . 'wp-admin/includes/plugin.php'); + } + $plugin_data = get_plugin_data(__FILE__); + + /* + * Set Plugin Version + */ + self::$plugin_version = $plugin_data['Version']; + + /* + * Set Plugin Url + */ + self::$plugin_url = plugins_url('', __FILE__); + + /* + * Set Plugin Path + */ + self::$plugin_path = plugin_dir_path(__FILE__); + + /* + * Set Plugin BaseName + */ + self::$plugin_basename = plugin_basename(__FILE__); + } + + /** + * include Plugin Require File + */ + public function includes() + { + /* + * autoload plugin files + */ + include_once dirname(__FILE__) . '/inc/config/i18n.php'; + include_once dirname(__FILE__) . '/inc/config/install.php'; + include_once dirname(__FILE__) . '/inc/config/uninstall.php'; + include_once dirname(__FILE__) . '/inc/helper.php'; + include_once dirname(__FILE__) . '/inc/admin/admin.php'; + include_once dirname(__FILE__) . '/inc/process.php'; + } + + /** + * Used for regular plugin work. + * + * @wp-hook init Hook + * @return void + */ + public function init_hooks() + { + + /* + * Activation Plugin Hook + */ + register_activation_hook(__FILE__, array('\WP_PODCAST_IMPORTER\config\install', 'run_install')); + + /* + * Uninstall Plugin Hook + */ + register_deactivation_hook(__FILE__, array('\WP_PODCAST_IMPORTER\config\uninstall', 'run_uninstall')); + + /* + * Load i18n + */ + if (self::$use_i18n === true) { + new \WP_PODCAST_IMPORTER\config\i18n('podcast-importer'); + } + } + + /** + * Show notice about PHP version + * + * @return void + */ + function php_version_notice() + { + if (!current_user_can('manage_options')) { + return; + } + $error = __('Your installed PHP Version is: ', 'podcast-importer') . PHP_VERSION . '. '; + $error .= __('The WP PodCast Importer plugin requires PHP version ', 'podcast-importer') . $this->min_php . __(' or greater.', 'podcast-importer'); + ?> +
+

+
+ Podcast Importer" via the main menu that appears in your WordPress dashboard. Set the different options and if you need a continuous import process for future episodes, make sure to hit that checkbox before running the import process. -You can disable a schedueld import at any time by simply deleting the import entry. - -The plugin also supports automatic import of native / embed audio players from 15+ podcast hosting providers, including: Buzzsprout, Megaphone, Pinecast, Captivate, Transistor, Anchor.fm, Simplecast, Podbean, Whooshkaa, Omny, Ausha, Spreaker, Audioboom, Fireside, Libsyn and more. - - -== Installation == - -1. Upload the plugin files to the `/wp-content/plugins/podcast-importer` directory, or install the plugin through the WordPress plugins screen directly. -2. Activate the plugin through the 'Plugins' screen in WordPress. -3. Run a new import via the "Tools -> Podcast Importer" section in your WordPress admin panel. -4. If needed, delete any of the scheduled import processes. - -== Frequently Asked Questions == - -= The import failed or takes too much time to process? = -You can run the importer multiple times, as it will never import the same post twice. Once all episodes are imported, only future ones would be imported, assuming you selected the continuous import option. - -= Do you support podcast feeds from any host? = -Sure. All types of podcast feeds can be imported, as long as they are in an RSS/XML format. If you feel something is missing, please reach out and we will ensure to look into it. - -= The import does not work for my podcast feed = -First of all, make sure you are filling in a valid URL, of a valid podcast RSS feed. Second, make sure your server is up to modern requirements - we recommend PHP 7 or above. - -== Screenshots == - -1. Import your podcast episodes based on multiple options. -2. Add multiple continuous import processes of separate podcasts. - -== Changelog == - -= 1.0 = -* Initial Release. From d91955c28531b227048cc4f24172e2d82ba8f382 Mon Sep 17 00:00:00 2001 From: mehrshaddarzi Date: Mon, 30 Aug 2021 08:53:08 +0430 Subject: [PATCH 2/4] Fix use wpdb in Process --- inc/admin/views/tools.php | 4 +--- inc/process.php | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/inc/admin/views/tools.php b/inc/admin/views/tools.php index 7909c26..636838f 100644 --- a/inc/admin/views/tools.php +++ b/inc/admin/views/tools.php @@ -17,6 +17,4 @@ endif; ?> - - - \ No newline at end of file diff --git a/inc/process.php b/inc/process.php index 3c56efc..f095f82 100644 --- a/inc/process.php +++ b/inc/process.php @@ -6,6 +6,8 @@ class Process { public static function run() { + global $wpdb; + // Init Number Added Post $posts_added_count = 0; From 0c209c975badb0b53fcddb2c198908da7f0c4b12 Mon Sep 17 00:00:00 2001 From: mehrshaddarzi Date: Mon, 30 Aug 2021 09:32:44 +0430 Subject: [PATCH 3/4] Minor improvement --- inc/process.php | 1 - 1 file changed, 1 deletion(-) diff --git a/inc/process.php b/inc/process.php index f095f82..2c0bc16 100644 --- a/inc/process.php +++ b/inc/process.php @@ -20,7 +20,6 @@ public static function run() $podcast_importer_publish = 'publish'; $podcast_importer_author = 'admin'; $podcast_importer_category = ''; - $podcast_importer_continuous = 'off'; $podcast_importer_images = 'off'; $podcast_importer_episode_number = 'off'; $podcast_importer_content_tag = 'content:encoded'; From 044b7e3f714eafbc61dbdf93295aa662eb2e1b84 Mon Sep 17 00:00:00 2001 From: Mostafa Soufi Date: Sat, 4 Sep 2021 13:18:31 +0430 Subject: [PATCH 4/4] Update version and add readme --- podcast-importer.php | 2 +- readme.txt | 55 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 readme.txt diff --git a/podcast-importer.php b/podcast-importer.php index f007a26..5a2f8be 100644 --- a/podcast-importer.php +++ b/podcast-importer.php @@ -2,7 +2,7 @@ /** * Plugin Name: Podcast Importer * Description: A simple podcast import plugin with feed. - * Version: 1.0.0 + * Version: 2.0 * Author: VeronaLabs * Author URI: https://veronalabs.com * License: GPL-2.0+ diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..7349159 --- /dev/null +++ b/readme.txt @@ -0,0 +1,55 @@ +=== Podcast Importer === +Contributors: veronalabs +Donate link: https://veronalabs.com +Tags: podcast, import, podcasting, feed, audio, rss, episodes, embed +Requires at least: 4.8 +Tested up to: 5.7 +Requires PHP: 5.6 +Stable tag: 2.0 +License: GPLv3 or later +License URI: https://www.gnu.org/licenses/gpl-3.0.html + +A simple podcast import tool for WordPress. + +== Description == + +Sync your Podcast RSS feed with WordPress website. The Podcast Importer plugin helps to easily import podcasts into WordPress. You can import your podcast into the regular WordPress posts or into a custom post type (if you have an existing one). + +The plugin supports importing episodes into existing custom post types, assign categories, import featured images and more. Additionally, the plugin enables continuous import or "Sync" of podcast RSS feeds, so every time you release a new podcast episode, it could be automatically created within WordPress. You can also set multiple import schedules and import different podcasts from separate sources at the same time. (For example, when importing separate podcasts from separate feeds into one website) + +To use the plugin, simply run a new import under "Tools -> Podcast Importer" via the main menu that appears in your WordPress dashboard. Set the different options and if you need a continuous import process for future episodes, make sure to hit that checkbox before running the import process. +You can disable a scheduled import at any time by simply deleting the import entry. + +The plugin also supports automatic import of native / embed audio players from 15+ podcast hosting providers, including: Buzzsprout, Megaphone, Pinecast, Captivate, Transistor, Anchor.fm, Simplecast, Podbean, Whooshkaa, Omny, Ausha, Spreaker, Audioboom, Fireside, Libsyn and more. + + +== Installation == + +1. Upload the plugin files to the `/wp-content/plugins/podcast-importer` directory, or install the plugin through the WordPress plugins screen directly. +2. Activate the plugin through the 'Plugins' screen in WordPress. +3. Run a new import via the "Tools -> Podcast Importer" section in your WordPress admin panel. +4. If needed, delete any of the scheduled import processes. + +== Frequently Asked Questions == + += The import failed or takes too much time to process? = +You can run the importer multiple times, as it will never import the same post twice. Once all episodes are imported, only future ones would be imported, assuming you selected the continuous import option. + += Do you support podcast feeds from any host? = +Sure. All types of podcast feeds can be imported, as long as they are in an RSS/XML format. If you feel something is missing, please reach out and we will ensure to look into it. + += The import does not work for my podcast feed = +First of all, make sure you are filling in a valid URL, of a valid podcast RSS feed. Second, make sure your server is up to modern requirements - we recommend PHP 7 or above. + +== Screenshots == + +1. Import your podcast episodes based on multiple options. +2. Add multiple continuous import processes of separate podcasts. + +== Changelog == + += 2.0 = +* Refactor the plugin structure and built from scratch + += 1.0 = +* Initial Release. \ No newline at end of file