astroport/www/LOVELand/podcast/core/functions.php

1778 lines
72 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
############################################################
# PODCAST GENERATOR
#
# Created by Alberto Betella
# http://www.podcastgenerator.net
#
# This is Free Software released under the GNU/GPL License.
############################################################
##################################################################################
function checkFileType ($filetype,$absoluteurl) {
if (file_exists($absoluteurl."components/supported_media/supported_media.xml")) {
$parser = simplexml_load_file($absoluteurl.'components/supported_media/supported_media.xml','SimpleXMLElement',LIBXML_NOCDATA);
$podcast_filetypes = array();
$podcast_filemimetypes = array();
foreach($parser->mediaFile as $singleFileType) {
array_push ($podcast_filetypes,$singleFileType->extension[0]);
array_push ($podcast_filemimetypes,$singleFileType->mimetype[0]);
}
$i=0;
$isFileSupported=FALSE;
$fileData = array();
while (($i < sizeof($podcast_filetypes)) && $isFileSupported==false) {
if ($filetype==$podcast_filetypes[$i]) {
$fileData[0]=$podcast_filetypes[$i];
$fileData[1]=$podcast_filemimetypes[$i];
$isFileSupported=TRUE;
}
$i++;
}
//Always return something
if (!isset($fileData[0])) $fileData[0] = NULL;
if (!isset($fileData[1])) $fileData[1] = NULL;
//returns bool (true if file is present in supported_media.xml)
$fileData[2] = $isFileSupported;
//Array with 3 values: podcast_filetypes, podcast_filemimetypes, isFileSupported
return ($fileData);
}
}
## END - DETECT SUPPORTED MEDIA FILE FORMATS AND RETURN MIMETYPE
##################################################################################
########
## Rename uploaded file - STRICT
function renamefilestrict ($filetorename) { // strict rename policy (just characters from a to z and numbers... no accents and other characters). This kind of renaming can have problems with some languages (e.g. oriental)
$filetorename = remove_accents($filetorename);
$filetorename = strtolower($filetorename);
$filetorename = str_replace(array(' ', '.', ',', 'amp'), "_",$filetorename); //amp is the remaining string from &amp;
// \w matches alphanumeric characters and underscores + dash added
$filetorename = preg_replace("/[^\w-]/", "", $filetorename);
return $filetorename;
}
########
########
#remove accents
function remove_accents($str)
{
$a = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Ā', 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ', 'ĉ', 'Ċ', 'ċ', 'Č', 'č', 'Ď', 'ď', 'Đ', 'đ', 'Ē', 'ē', 'Ĕ', 'ĕ', 'Ė', 'ė', 'Ę', 'ę', 'Ě', 'ě', 'Ĝ', 'ĝ', 'Ğ', 'ğ', 'Ġ', 'ġ', 'Ģ', 'ģ', 'Ĥ', 'ĥ', 'Ħ', 'ħ', 'Ĩ', 'ĩ', 'Ī', 'ī', 'Ĭ', 'ĭ', 'Į', 'į', 'İ', 'ı', 'IJ', 'ij', 'Ĵ', 'ĵ', 'Ķ', 'ķ', 'Ĺ', 'ĺ', 'Ļ', 'ļ', 'Ľ', 'ľ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'Ń', 'ń', 'Ņ', 'ņ', 'Ň', 'ň', 'ʼn', 'Ō', 'ō', 'Ŏ', 'ŏ', 'Ő', 'ő', 'Œ', 'œ', 'Ŕ', 'ŕ', 'Ŗ', 'ŗ', 'Ř', 'ř', 'Ś', 'ś', 'Ŝ', 'ŝ', 'Ş', 'ş', 'Š', 'š', 'Ţ', 'ţ', 'Ť', 'ť', 'Ŧ', 'ŧ', 'Ũ', 'ũ', 'Ū', 'ū', 'Ŭ', 'ŭ', 'Ů', 'ů', 'Ű', 'ű', 'Ų', 'ų', 'Ŵ', 'ŵ', 'Ŷ', 'ŷ', 'Ÿ', 'Ź', 'ź', 'Ż', 'ż', 'Ž', 'ž', 'ſ', 'ƒ', 'Ơ', 'ơ', 'Ư', 'ư', 'Ǎ', 'ǎ', 'Ǐ', 'ǐ', 'Ǒ', 'ǒ', 'Ǔ', 'ǔ', 'Ǖ', 'ǖ', 'Ǘ', 'ǘ', 'Ǚ', 'ǚ', 'Ǜ', 'ǜ', 'Ǻ', 'ǻ', 'Ǽ', 'ǽ', 'Ǿ', 'ǿ');
$b = array('A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 's', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'l', 'l', 'N', 'n', 'N', 'n', 'N', 'n', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'OE', 'oe', 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's', 'f', 'O', 'o', 'U', 'u', 'A', 'a', 'I', 'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'A', 'a', 'AE', 'ae', 'O', 'o');
return str_replace($a, $b, $str);
}
## Rename uploaded file - LESS STRICT
function renamefile ($filetorename) { // normal file rename policy
$filetorename = strtolower($filetorename); // lower-case.
$filetorename = strip_tags($filetorename); // remove HTML tags.
$filetorename = preg_replace('!\s+!','_',$filetorename); // change space chars to underscores.
$filetorename = stripslashes($filetorename); //remove slashes in the file name
$filetorename = str_replace("'", "", $filetorename);
$filetorename = str_replace("&", "_and_", $filetorename);
return $filetorename;
}
########
## Validate e-mail address
function validate_email ($address) { //validate email address
return (preg_match("/^[_\.0-9a-zA-Z-]+@([0-9a-zA-Z][0-9a-zA-Z-]+\.)+[a-zA-Z]{2,6}$/i", $address));
}
########
## Depurate feed Content from non accepted characters (according also to iTunes specifications)
function depurateContent($content) {
$content = stripslashes($content);
//$content = str_replace('<', '&lt;', $content);
//$content = str_replace('>', '&gt;', $content);
//$content = str_replace('&amp;', '&', $content); //double subsitution to avoid &&&amps;
//$content = str_replace('&', '&amp;', $content);
//$content = str_replace('', '&apos;', $content);
/*
$content = str_replace('&amp;', '&', $content); //double subsitution to avoid &&&amps;
$content = str_replace('<', '&#60;', $content);
$content = str_replace('>', '&#62;', $content);
$content = str_replace('&', '&#38;', $content);
$content = str_replace('\'', '&#39;', $content);
$content = str_replace('', '&#39;', $content);
$content = str_replace('"', '&#34;', $content);
$content = str_replace('©', '&#xA9;', $content);
$content = str_replace('&copy;', '&#xA9;', $content);
$content = str_replace('℗', '&#x2117;', $content);
$content = str_replace('™', '&#x2122;', $content);
*/
//NB. double_encode = FALSE Will not encode existing html entities
$content = htmlspecialchars($content,ENT_COMPAT,'UTF-8',FALSE);
return $content;
}
//this is just for CDATA fields such as <itunes:summary> (long description in PG)
function iTunesSummaryLinks($content) {
$content = htmlspecialchars_decode($content);
//tags that work in iTunes and iOS podcast app
$allowedTags = array("<a>","<p>","<ul>","<ol>","<li>");
$content = strip_tags($content,implode($allowedTags)); //implode = array to string
$tagExists = false;
foreach ($allowedTags as $singleTag)
{
//substr removes last character from tags, so attributes are accepted, e.g. <a> and <a href="">
if (strpos($content, substr($singleTag, 0, -1)) === true) $tagExists = true;
}
if ($tagExists = true) {
$content = trim(preg_replace('/\s+/', ' ', $content)); //trim new lines
$content = '<![CDATA['.$content.']]>'; //CDATA Field
}
$content = ampersandEntitiesConvert($content);
return $content;
}
// to ensure compatibility of iTunes:summary and long description (support <a> tags but ampersand should be entities)
function ampersandEntitiesConvert ($content) {
$content = str_replace('&amp;', '&', $content); //double subsitution to avoid &&&amps;
$content = str_replace('&', '&amp;', $content);
return $content;
}
// used in the categores ID at the moment
function ampersandRemove ($content) {
$content = str_replace('&amp;', 'and', $content);
$content = str_replace('&', 'and;', $content);
return $content;
}
########
## Sanitize URL Content to avoid cross-site scripting (XSS)
function avoidXSS($url) {
$url = filter_var($url,FILTER_SANITIZE_URL);
$url = str_replace('<', '&lt;', $url);
$url = str_replace('>', '&gt;', $url);
$url = str_replace('&amp;', '&', $url); //double subsitution to avoid &&&amps;
$url = str_replace('&', '&amp;', $url);
$url = str_replace('', '&apos;', $url);
$url = str_replace('"', '&quot;', $url);
$url = str_replace('iframe', '', $url);
$url = str_replace('width=', '', $url);
$url = str_replace('height=', '', $url);
$url = str_replace('src=', '', $url);
$url = str_replace('javascript=', '', $url);
return $url;
}
############ Determine whether to use the old or the new theme engine
//It depends on the presence or absence of the file theme.xml in the theme root folder
function useNewThemeEngine($theme_path) //$theme_path is defined in config.php
{
if (file_exists($theme_path.'theme.xml')) {
return TRUE;
}
else {
return FALSE;
}
}
############ Create form date and time
function CreaFormData($inName, $useDate=0, $dateformat) //inName is the form name, it can be null
{
// array with months
$monthName = array(1=> _("Jan"), _("Feb"), _("Mar"),
_("Apr"), _("May"), _("Jun"), _("Jul"), _("Aug"),
_("Sep"), _("Oct"), _("Nov"), _("Dec"));
// se data non specificata, o invalida, usa timestamp corrente
if($useDate == NULL)
{
$useDate = Time();
}
$outputform = '<p>'._("Date:").'</p>'; //title
//day
$outputformDAY = "<select class=\"input-sm input-small\" name=\"" . $inName . "Day\">\n";
for($currentDay=1; $currentDay <= 31; $currentDay++)
{
$outputformDAY .= "<option value=\"$currentDay\"";
if(intval(date( "d", $useDate))==$currentDay)
{
$outputformDAY .= " selected";
}
$outputformDAY .= ">$currentDay\n";
}
$outputformDAY .= "</select>";
//mese
$outputformMONTH = "<select class=\"input-sm input-small\" name=\"" . $inName . "Month\">\n";
for($currentMonth = 1; $currentMonth <= 12; $currentMonth++)
{
$outputformMONTH .= "<option value=\"";
$outputformMONTH .= intval($currentMonth);
$outputformMONTH .= "\"";
if(intval(date( "m", $useDate))==$currentMonth)
{
$outputformMONTH .= " selected";
}
$outputformMONTH .= ">" . $monthName[$currentMonth] . "\n";
}
$outputformMONTH .= "</select>";
//anno
$outputformYEAR = "<select class=\"input-sm input-small\" name=\"" . $inName . "Year\">\n";
$startYear = date( "Y", $useDate);
for($currentYear = $startYear - 5; $currentYear <= $startYear+5;$currentYear++)
{
$outputformYEAR .= "<option value=\"$currentYear\"";
if(date( "Y", $useDate)==$currentYear)
{
$outputformYEAR .= " selected";
}
$outputformYEAR .= ">$currentYear\n";
}
$outputformYEAR .= "</select>";
if ($dateformat == "m-d-Y") {
$outputform.= $outputformMONTH.$outputformDAY.$outputformYEAR;}
elseif ($dateformat == "Y-m-d") {
$outputform.= $outputformYEAR.$outputformMONTH.$outputformDAY;}
else { $outputform.= $outputformDAY.$outputformMONTH.$outputformYEAR; }
$outputform .= "&nbsp;&nbsp;"; //two blank spaces
$outputform .= '<p>'._("Time:").'</p>'; //titoletto
//ore
$outputform .= "<select class=\"input-sm input-small\" name=\"" . $inName . "Hour\">\n";
for($currentHour = 0; $currentHour <= 23; $currentHour++)
{
$outputform .= "<option value=\"";
$outputform .= intval($currentHour);
$outputform .= "\"";
if(intval(date( "G", $useDate))==$currentHour)
{
$outputform .= " selected";
}
$outputform .= ">" . $currentHour. "\n";
}
$outputform .= "</select>";
//minuti
$outputform .= "<select class=\"input-sm input-small\" name=\"" . $inName . "Minute\">\n";
for($currentMinute = 0; $currentMinute <= 59; $currentMinute++)
{
$outputform .= "<option value=\"";
if ($currentMinute <= 9) {
$outputform .= "0".intval($currentMinute); } //add 0 to numbers from 1 to 9
else { $outputform .= intval($currentMinute); }
$outputform .= "\"";
if(intval(date( "i", $useDate))==$currentMinute)
{
$outputform .= " selected";
}
if ($currentMinute <= 9) {
$outputform .= ">0".intval($currentMinute). "\n"; } //add 0 to numbers from 1 to 9
else { $outputform .= ">".intval($currentMinute). "\n"; }
}
$outputform .= "</select>";
return $outputform;
} // End - form date and time
##################################################################################
##################################################################################
## SOCIAL NETWORK INTEGRATION
//$fullURL,$text_title are episode data. the rest: value 1 (TRUE) enable a certain social network, value 0 disables
function displaySocialNetworkButtons($fullURL,$text_title,$fb,$tw,$gp) {
$construct_output = '<br />'; //space above
//TWITTER Button
if ($tw == TRUE) {
$construct_output.= '
<a href="https://twitter.com/share" class="twitter-share-button" data-url="'.$fullURL.'" data-text="'.$text_title.'" data-hashtags="podcastgen">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
';
}
//G+ Button
if ($gp == TRUE) {
$construct_output .= '
<div class="g-plusone" data-size="medium" data-href="'.$fullURL.'"></div>
<script type="text/javascript">
(function() {
var po = document.createElement(\'script\'); po.type = \'text/javascript\'; po.async = true;
po.src = \'https://apis.google.com/js/plusone.js\';
var s = document.getElementsByTagName(\'script\')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
';
}
//FB Like Button
if ($fb == TRUE) {
$construct_output .= '
<iframe src="https://www.facebook.com/plugins/like.php?href='.$fullURL.'&width=79&layout=button_count&action=like&size=small&show_faces=false&share=false&height=21&appId=379539238761383" width="100" height="21" style="border:none;overflow:hidden" scrolling="no" frameborder="0" allowTransparency="true"></iframe>
';
}
return $construct_output;
}
## END SOCIAL NETWORK INTEGRATION
##################################################################################
##################################################################################
##################################################################################
## SHOW PODCAST EPISODES
//NB $all is bool (FALSE = takes $max_recent from config.php) $category is the category name from GET (null = all categories)
function showPodcastEpisodes($all,$category) {
include("core/includes.php");
$finalOutputEpisodes = NULL; // declare final output to return
if ($all == TRUE) {
$max_recent = NULL; //reset limitation for recent episodes set in config.php
$categoryURLforPagination = "&cat=all"; //preserve category in links in number of pages at the button
//don't show social networks when noextras is appended to the URL
if (isset($_GET['noextras'])) {
$disableextras = TRUE;
$categoryURLforPagination .= "&noextras"; //preserve category in links in number of pages at the button
}
}
else { // in home page, do not paginate but use $max_recent
$episodeperpage = 999999; //do not use pagination (workaround - could be more elegant)
}
/// Header for Category (RSS and Title)
if (isset($category) AND $category != NULL) {
$CounterEpisodesInCategory = 0; // set counter to 0
$category = avoidXSS($category); //URL depuration
$categoryURLforPagination = "&cat=".$category;
//retrieve existing categories (description/long name)
//NB $existingCategories[$category] is category full name (not just ID)
$existingCategories = readPodcastCategories ($absoluteurl);
$category_header = '<div>';
if (isset($existingCategories[$category])) {
$category_header .= '<h3 class="sectionTitle"><a href="'.$url.'feed.php?cat='.$category.'"><i class="fa fa-rss "></i> '.$existingCategories[$category].'</a></h3>';
}
$category_header .= '</div>';
}
// Open podcast directory and read all the files contained
$fileNamesList = readMediaDir ($absoluteurl,$upload_dir);
if (empty($fileNamesList)) { // If media directory is empty
$finalOutputEpisodes .= '<div class="topseparator"><p>'._("No episodes here yet...").'</p></div>';
}
else { // If media directory contains files
$episodesCounter = 0; //set counter to zero
//if isset pagination variable in GET
if (isset($_GET["pgn"]) AND is_numeric($_GET["pgn"])) {
$maxC = $episodeperpage * $_GET["pgn"];
$minC = $episodeperpage* $_GET["pgn"] - $episodeperpage;
}
//if home page or no pages are set in GET
else {
$maxC = $episodeperpage;
$minC = 0;
}
// Loop through each file in the media directory
foreach ($fileNamesList as $singleFileName) {
$resulting_episodes = NULL; //declare the 1st time and then reset
//If current episode won't be displayed in this page, skip it and break the loop
if ($episodesCounter > $maxC) {
//NB. count($fileNamesList)/2 is the total number of episodes
$episodesCounter = count($fileNamesList)/2;
break;
}
//Else if this episode is shown in this page, or no limitation in $max_recent (i.e. home page)
else if ($episodesCounter < $max_recent OR $max_recent == NULL) {
////Validate the current episode
//NB. validateSingleEpisode returns [0] episode is supported (bool), [1] Episode Absolute path, [2] Episode XML DB absolute path,[3] File Extension (Type), [4] File MimeType, [5] File name without extension, [6] episode file supported but to XML present
$thisPodcastEpisode = validateSingleEpisode($singleFileName);
////If episode is supported and has a related xml db, and if it's not set to a future date OR if it's set for a future date but you are logged in as admin
if (($thisPodcastEpisode[0]==TRUE AND !publishInFuture($thisPodcastEpisode[1])) OR ($thisPodcastEpisode[0]==TRUE AND publishInFuture($thisPodcastEpisode[1]) AND isUserLogged())) {
////Parse XML data related to the episode
// NB. Function parseXMLepisodeData returns: [0] episode title, [1] short description, [2] long description, [3] image associated, [4] iTunes keywords, [5] Explicit language,[6] Author's name,[7] Author's email,[8] PG category 1, [9] PG category 2, [10] PG category 3, [11] file_info_size, [12] file_info_duration, [13] file_info_bitrate, [14] file_info_frequency, [15] embedded image in mp3
$thisPodcastEpisodeData = parseXMLepisodeData($thisPodcastEpisode[2]);
////if category is specified as a parameter of this function
if (isset($category) AND $category != NULL) {
//if category is not associated to the current episode
if ($category != $thisPodcastEpisodeData[8] AND $category != $thisPodcastEpisodeData[9] AND $category != $thisPodcastEpisodeData[10]) {
continue; //STOP this cycle and start a new one
} else {
$CounterEpisodesInCategory++; // Incremente episodes counter
}
}
//// Start constructing episode HTML output
//Theme engine PG version >= 2.0
if (useNewThemeEngine($theme_path)) {
//episodes per line in some themes (e.g. bootstrap)
$numberOfEpisodesPerLine = 2;
//If the current episode number is multiple of $numberOfEpisodesPerLine
if ($episodesCounter % $numberOfEpisodesPerLine != 0 OR $episodesCounter == count($fileNamesList)) {
//open div with class row-fluid (theme based on bootstrap)
//N.B. row-fluid is a CSS class for a div containing 1 or more episodes
//$resulting_episodes .= '<div class="row-fluid">';
$resulting_episodes .= '<div class="episode">';
}
$resulting_episodes .= '<div class="span6 col-md-6 6u episodebox">'; //open the single episode DIV
}
//If old Theme engine for <2.0 themes retro compatibility.
else {
$resulting_episodes .= '<div class="episode">'; //open the single episode DIV
}
////Title
$resulting_episodes .= '<h3 class="episode_title"><a href="?name='.$thisPodcastEpisode[5].'.'.$thisPodcastEpisode[3].'">'.$thisPodcastEpisodeData[0];
if (isItAvideo($thisPodcastEpisode[3])) $resulting_episodes .= '&nbsp;<i class="fa fa-youtube-play"></i>'; //add video icon
$resulting_episodes .= '</a></h3>';
////Date
$resulting_episodes .= '<p class="episode_date">';
$thisEpisodeDate = filemtime($thisPodcastEpisode[1]);
if ($thisEpisodeDate > time()) { //if future date
$resulting_episodes .= '<i class="fa fa-clock-o fa-2x"></i> '; //show watch icon
}
$episodeDate = date ($dateformat, $thisEpisodeDate);
$resulting_episodes .= $episodeDate.'</p>';
//// Edit/Delete button for logged user (i.e. admin)
if (isUserLogged()) {
$resulting_episodes .= '<p><a class="btn btn-inverse btn-xs btn-mini" href="?p=admin&amp;do=edit&amp;=episode&amp;name='.urlencode($thisPodcastEpisode[5]).'.'.$thisPodcastEpisode[3].'">'._("Edit / Delete").'</a></p>';
}
//Show Image embedded in the mp3 file or image associated in the images/ folder from previous versions of PG (i.e. 1.4-) - Just jpg and png extension supported
if (file_exists($absoluteurl.$img_dir.$thisPodcastEpisode[5].'.jpg')) {
$resulting_episodes .= '<img class="episode_image" src="'.$url.$img_dir.$thisPodcastEpisode[5].'.jpg" alt="'.$thisPodcastEpisodeData[0].'" />';
}
else if (file_exists($absoluteurl.$img_dir.$thisPodcastEpisode[5].'.png')) {
$resulting_episodes .= '<img class="episode_image" src="'.$url.$img_dir.$thisPodcastEpisode[5].'.png" alt="'.$thisPodcastEpisodeData[0].'" />';
}
//// Short Description
$resulting_episodes .= '<p>'.$thisPodcastEpisodeData[1].'</p>';
////Buttons (More, Download, Watch)
$resulting_episodes .= showButtons($thisPodcastEpisode[5],$thisPodcastEpisode[3],$url,$upload_dir,$episodesCounter,$thisPodcastEpisode[1],$enablestreaming);
////Other details (file type, duration, bitrate, frequency)
//NB. read from XML DB (except file extension = $thisPodcastEpisode[3]).
$episodeDetails = _('Filetype:')." ".strtoupper($thisPodcastEpisode[3]);
if ($thisPodcastEpisodeData[11] != NULL) $episodeDetails .= ' - '._('Size:')." ".$thisPodcastEpisodeData[11]._("MB");
if($thisPodcastEpisodeData[12]!=NULL) { // display file duration
$episodeDetails .= " - "._("Duration:")." ".$thisPodcastEpisodeData[12]." "._("m");
}
if($thisPodcastEpisode[3]=="mp3" AND $thisPodcastEpisodeData[13] != NULL AND $thisPodcastEpisodeData[14] != NULL) { //if mp3 show bitrate and frequency
$episodeDetails .= " (".$thisPodcastEpisodeData[13]." "._("kbps")." ".$thisPodcastEpisodeData[14]." "._("Hz").")";
}
$resulting_episodes .= '<p class="episode_info">'.$episodeDetails.'</p>';
////Playes: audio (flash/html5) and video (html5), for supported files and browsers
//if audio and video streaming is enabled in PG options
if ($enablestreaming=="yes" AND !detectMobileDevice()) {
$resulting_episodes .= showStreamingPlayers ($thisPodcastEpisode[5],$thisPodcastEpisode[3],$url,$upload_dir,$episodesCounter);
}
$isvideo = FALSE; //RESET isvideo for next episode
////Social networks and (eventual) embedded code
$resulting_episodes .= attachToEpisode($thisPodcastEpisode[5],$thisPodcastEpisode[3],$thisPodcastEpisodeData[0]);
//Blank space as bottom margin (to be replaced with CSS style!)
$resulting_episodes .= "<br />";
//Close the single episode DIV
$resulting_episodes .= "</div>";
//Close div with class row-fluid (theme based on bootstrap). Theme engine >= 2.0
if (useNewThemeEngine($theme_path) AND $episodesCounter % $numberOfEpisodesPerLine != 0 OR $episodesCounter == count($fileNamesList)) {
$resulting_episodes .= "</div>"; //close class row-fluid (bootstrap)
}
$episodesCounter++; //increment counter
} // END - If episode is supported and has a related xml db
if ($episodesCounter <= $maxC AND $episodesCounter > $minC) {
//Append this episode to the final output to return
$finalOutputEpisodes .= $resulting_episodes;
}
} //END - Else if this episode is shown in this page, or no limitation in $max_recent
} // END - Loop through each file in the media directory
} // END - If media directory contains files
//IF a category is requested add category header and message when empty
if (isset($category) AND $category != NULL) {
//If a category is requested and doesn't contain any episode
if ($CounterEpisodesInCategory < 1 AND !empty($fileNamesList)) {
$finalOutputEpisodes .= '<p>'.("No episodes here yet...").'</p>';
}
$finalOutputEpisodes = $category_header.$finalOutputEpisodes; //category header at the top
}
////Pagination (and links to pages)
//Calculate total number of pages
if (isset($episodesCounter)) $numberOfPages = ($episodesCounter / $episodeperpage);
if (isset($numberOfPages) AND $numberOfPages>1) $numberOfPages = ceil($numberOfPages); //round to the next integer
//echo $numberOfPages; // Debug
if (isset($_GET['p'])) $pageURLforPagination = avoidXSS(($_GET['p']));
else $pageURLforPagination = "home";
if (isset($_GET["pgn"])) $thisCurrentPage = $_GET["pgn"];
else $thisCurrentPage = 1;
if (isset($episodesCounter) AND $episodesCounter > $episodeperpage) {
$finalOutputEpisodes .= '<div style="clear:both;"><p>';
//Print page index and links
for ($onePage =1; $onePage <= $numberOfPages; $onePage++) {
if ($thisCurrentPage == $onePage) {
$finalOutputEpisodes .= $onePage.' | ';
} else
$finalOutputEpisodes .= '<a href="?p='.$pageURLforPagination.$categoryURLforPagination.'&amp;pgn='.$onePage.'">'.$onePage.'</a> | ';
}
$finalOutputEpisodes .= '</p></div>';
}
//Finally, return all the episodes to output on the web page
return $finalOutputEpisodes;
}
## END - SHOW PODCAST EPISODES
##################################################################################
##################################################################################
##################################################################################
## SHOW SINGLE EPISODE
// $justTitle is bool and returns just the title of the episode
function showSingleEpisode($singleEpisode,$justTitle) {
include("core/includes.php");
$finalOutputEpisodes = NULL; // declare final output to return
$resulting_episodes = NULL; //declare the 1st time and then reset
////Validate the current episode
//NB. validateSingleEpisode returns [0] episode is supported (bool), [1] Episode Absolute path, [2] Episode XML DB absolute path,[3] File Extension (Type), [4] File MimeType, [5] File name without extension, [6] episode file supported but to XML present
$thisPodcastEpisode = validateSingleEpisode($singleEpisode);
////If episode is supported and has a related xml db, and if it's not set to a future date OR if it's set for a future date but you are logged in as admin
if (($thisPodcastEpisode[0]==TRUE AND !publishInFuture($thisPodcastEpisode[1])) OR ($thisPodcastEpisode[0]==TRUE AND publishInFuture($thisPodcastEpisode[1]) AND isUserLogged())) {
////Parse XML data related to the episode
// NB. Function parseXMLepisodeData returns: [0] episode title, [1] short description, [2] long description, [3] image associated, [4] iTunes keywords, [5] Explicit language,[6] Author's name,[7] Author's email,[8] PG category 1, [9] PG category 2, [10] PG category 3, [11] file_info_size, [12] file_info_duration, [13] file_info_bitrate, [14] file_info_frequency
$thisPodcastEpisodeData = parseXMLepisodeData($thisPodcastEpisode[2]);
//// Return just title and end function here, if just title is required
if (isset($justTitle) AND $justTitle == TRUE) return $thisPodcastEpisodeData[0]; //Function ends here
//// Start constructing episode HTML output
//Theme engine PG version >= 2.0 row-fluid
$resulting_episodes .= '<div class="episode">';
$resulting_episodes .= '<div class="span6 col-md-6 6u episodebox">'; //open the single episode DIV
////Title
$resulting_episodes .= '<h3 class="episode_title">'.$thisPodcastEpisodeData[0];
if (isItAvideo($thisPodcastEpisode[3])) $resulting_episodes .= '&nbsp;<i class="fa fa-youtube-play"></i>'; //add video icon
$resulting_episodes .= '</h3>';
////Date
$resulting_episodes .= '<p class="episode_date">';
$thisEpisodeDate = filemtime($thisPodcastEpisode[1]);
if ($thisEpisodeDate > time()) { //if future date
$resulting_episodes .= '<i class="fa fa-clock-o fa-2x"></i> '; //show watch icon
}
$episodeDate = date ($dateformat, $thisEpisodeDate);
$resulting_episodes .= $episodeDate.'</p>';
//// Edit/Delete button for logged user (i.e. admin)
if (isUserLogged()) {
$resulting_episodes .= '<p><a class="btn btn-inverse btn-xs btn-mini" href="?p=admin&amp;do=edit&amp;=episode&amp;name='.urlencode($thisPodcastEpisode[5]).'.'.$thisPodcastEpisode[3].'">'._("Edit / Delete").'</a></p>';
}
//Show Image embedded in the mp3 file or image associated in the images/ folder from previous versions of PG (i.e. 1.4-) - Just jpg and png extension supported
if (file_exists($absoluteurl.$img_dir.$thisPodcastEpisode[5].'.jpg')) {
$resulting_episodes .= '<img class="episode_image" src="'.$url.$img_dir.$thisPodcastEpisode[5].'.jpg" alt="'.$thisPodcastEpisodeData[0].'" />';
}
else if (file_exists($absoluteurl.$img_dir.$thisPodcastEpisode[5].'.png')) {
$resulting_episodes .= '<img class="episode_image" src="'.$url.$img_dir.$thisPodcastEpisode[5].'.png" alt="'.$thisPodcastEpisodeData[0].'" />';
}
//// Show Long description if available, otherwise, short Description
if ($thisPodcastEpisodeData[2] != NULL) $resulting_episodes .= '<div>'.ampersandEntitiesConvert(htmlspecialchars_decode($thisPodcastEpisodeData[2])).'</div>';
else $resulting_episodes .= '<p>'.$thisPodcastEpisodeData[1].'</p>';
/// Categories
$resulting_episodes .= '<p><em>'._("Categories").'</em> ';
if ($thisPodcastEpisodeData[8] != "") $resulting_episodes .= ' | <a href="?p=archive&amp;cat='.$thisPodcastEpisodeData[8] .'">'.categoryNameFromID($absoluteurl,$thisPodcastEpisodeData[8]).'</a>';
if ($thisPodcastEpisodeData[9] != "") $resulting_episodes .= ' | <a href="?p=archive&amp;cat='.$thisPodcastEpisodeData[9].'">'.categoryNameFromID($absoluteurl,$thisPodcastEpisodeData[9]).'</a>';
if ($thisPodcastEpisodeData[10] != "") $resulting_episodes .= ' | <a href="?p=archive&amp;cat='.$thisPodcastEpisodeData[10].'">'.categoryNameFromID($absoluteurl,$thisPodcastEpisodeData[10]).'</a>';
$resulting_episodes .= '</p>';
////Buttons (More, Download, Watch).
$resulting_episodes .= showButtons($thisPodcastEpisode[5],$thisPodcastEpisode[3],$url,$upload_dir,"singleEpisode",$thisPodcastEpisode[1],$enablestreaming);
////Other details (file type, duration, bitrate, frequency)
//NB. read from XML DB (except file extension = $thisPodcastEpisode[3]).
$episodeDetails = _('Filetype:')." ".strtoupper($thisPodcastEpisode[3]);
if ($thisPodcastEpisodeData[11] != NULL) $episodeDetails .= ' - '._('Size:')." ".$thisPodcastEpisodeData[11]._("MB");
if($thisPodcastEpisodeData[12]!=NULL) { // display file duration
$episodeDetails .= " - "._("Duration:")." ".$thisPodcastEpisodeData[12]." "._("m");
}
if($thisPodcastEpisode[3]=="mp3" AND $thisPodcastEpisodeData[13] != NULL AND $thisPodcastEpisodeData[14] != NULL) { //if mp3 show bitrate and frequency
$episodeDetails .= " (".$thisPodcastEpisodeData[13]." "._("kbps")." ".$thisPodcastEpisodeData[14]." "._("Hz").")";
}
$resulting_episodes .= '<p class="episode_info">'.$episodeDetails.'</p>';
////Playes: audio (flash/html5) and video (html5), for supported files and browsers
//if audio and video streaming is enabled in PG options
if ($enablestreaming=="yes" AND !detectMobileDevice()) {
$resulting_episodes .= showStreamingPlayers ($thisPodcastEpisode[5],$thisPodcastEpisode[3],$url,$upload_dir,"singleEpisode");
}
$isvideo = FALSE; //RESET isvideo for next episode
////Social networks and (eventual) embedded code
$resulting_episodes .= attachToEpisode($thisPodcastEpisode[5],$thisPodcastEpisode[3],$thisPodcastEpisodeData[0]);
//Close the single episode DIV
$resulting_episodes .= "</div>";
//Close div with class row-fluid (theme based on bootstrap). Theme engine >= 2.0
$resulting_episodes .= "</div>"; //close class row-fluid (bootstrap)
//Append this episode to the final output to return
$finalOutputEpisodes .= $resulting_episodes;
}
//Finally, return all the episodes to output on the web page
return $finalOutputEpisodes;
}
## END - SHOW SIGLE EPISODE
##################################################################################
function divideFilenameFromExtension ($filetodivide) {
$file_parts = pathinfo($filetodivide); //divide filename from extension
$fileParts = array();
$fileParts[0] = $file_parts['filename'];
$fileParts[1] = $file_parts['extension'];
return $fileParts;
}
function readPodcastCategories ($absoluteurl) {
if (file_exists($absoluteurl."categories.xml")) { //if categories file exists
$parser = simplexml_load_file($absoluteurl."categories.xml",'SimpleXMLElement',LIBXML_NOCDATA);
//var_dump($parser); //Debug
$existingCategories = array();
$n = 0;
foreach($parser->category as $singlecategory) {
//create array containing category id as seed and description for each id
$catID = $singlecategory->id[0];
$catDescription = $singlecategory->description[0];
$existingCategories["$catID"] = depurateContent($catDescription);
$n++;
}
}
return $existingCategories;
}
//generate language ISO639 format (e.g. just "en" and not "en_EN") for RSS feed
function languageISO639 ($language) {
$parts = explode("_", $language);
return $parts[0];
}
function categoryNameFromID ($absoluteurl,$id) {
include ("$absoluteurl"."core/admin/readXMLcategories.php");
if (in_array($id, $arrid)) {
$positionInArray = array_search($id, $arrid);
$catName = ampersandEntitiesConvert($arr[$positionInArray]);
return $catName;
} else {
return;
}
}
function languagesList ($absoluteurl,$isTranslation) { // $isTranslation TRUE when the list is used for localized files
if (file_exists($absoluteurl."components/locale/languages.xml")) {
$parser = simplexml_load_file($absoluteurl.'components/locale/languages.xml','SimpleXMLElement',LIBXML_NOCDATA);
}
$languageList = array (); //empty
$n = 0;
foreach($parser->language as $singlelanguage)
{
//echo $singlelanguage->id[0]."<br>";
//echo $singlelanguage->description[0];
$id = $singlelanguage->id[0];
$desc = $singlelanguage->description[0];
if ($isTranslation == TRUE) {
//if localization folder exists
$localizedFolder = $absoluteurl."components/locale/".$id."/LC_MESSAGES/";
if (file_exists($localizedFolder."messages.mo") AND file_exists($localizedFolder."messages.po")) {
$languageList["$id"] = "$desc"; //double quotes necessary
}
} else {
//add all to the list
$languageList["$id"] = "$desc"; //double quotes necessary
}
$n++;
}
return $languageList;
}
function random_str($size) {
$text = NULL;
$randoms = array(
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b",
"c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
"o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"
);
srand ((double) microtime() * 1000000);
for($i = 1; $i <= $size; $i++)
$text .= $randoms[(rand(0,35))];
return $text;
}
function detectMobileDevice() {
//Some of the main mobile devices
$iPod = stripos($_SERVER['HTTP_USER_AGENT'],"iPod");
$iPhone = stripos($_SERVER['HTTP_USER_AGENT'],"iPhone");
$iPad = stripos($_SERVER['HTTP_USER_AGENT'],"iPad");
$Android= stripos($_SERVER['HTTP_USER_AGENT'],"Android");
$webOS= stripos($_SERVER['HTTP_USER_AGENT'],"webOS");
$Blackberry= stripos($_SERVER['HTTP_USER_AGENT'],"BlackBerry");
$Kindle= stripos($_SERVER['HTTP_USER_AGENT'],"Kindle");
//here we can do something with the mobile devices or just a subset of them
if($iPod OR $iPhone OR $iPad OR $Android OR $webOS OR $Blackberry OR $Kindle){
return TRUE;
} else {
return FALSE;
}
}
//detect browser name and version from user agent (until get_browser will come in bundle with PHP)
function browserAndVersion() {
$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
//The following conditions are custom-tailored for specific user agents and may change in future
//Opera (NB. It goes before Chrome, cause the user agent contains chrome too
if(preg_match('/(opr)[ \/]([\w.]+)/', $userAgent)) {
$browser = 'opera';
preg_match('/(opr)[ \/]([\w]+)/', $userAgent, $versionExtracted); //used (opr) in regexp
}
//Chrome
else if(preg_match('/(chrome)[ \/]([\w.]+)/', $userAgent)) {
$browser = 'chrome';
preg_match('/('.$browser.')[ \/]([\w]+)/', $userAgent, $versionExtracted);
}
//Firefox
else if(preg_match('/(firefox)[ \/]([\w.]+)/', $userAgent)) {
$browser = 'firefox';
preg_match('/('.$browser.')[ \/]([\w]+)/', $userAgent, $versionExtracted);
}
//IE
else if(preg_match('/(msie)[ \/]([\w.]+)/', $userAgent)) {
$browser = 'msie';
preg_match('/('.$browser.')[ \/]([\w]+)/', $userAgent, $versionExtracted);
}
//IE 11
else if(preg_match('/(trident)[ \/]([\w.]+)/', $userAgent)) {
$browser = 'msie';
$version = "11"; //manually assigned to IE 11
}
//SAFARI
else if(preg_match('/(safari)[ \/]([\w.]+)/', $userAgent)) {
$browser = 'safari';
preg_match('/(version)[ \/]([\w]+)/', $userAgent, $versionExtracted); //version in the regexp
}
else {
$browser = "notDetected";
$version = "0";
}
if (!isset($version)) $version = $versionExtracted[2];
/*
if(preg_match('/(chromium)[ \/]([\w.]+)/', $userAgent))
$browser = 'chromium';
elseif(preg_match('/(chrome)[ \/]([\w.]+)/', $userAgent))
$browser = 'chrome';
elseif(preg_match('/(safari)[ \/]([\w.]+)/', $userAgent))
$browser = 'safari';
elseif(preg_match('/(opera)[ \/]([\w.]+)/', $userAgent))
$browser = 'opera';
elseif(preg_match('/(msie)[ \/]([\w.]+)/', $userAgent))
$browser = 'msie';
elseif(preg_match('/(mozilla)[ \/]([\w.]+)/', $userAgent))
$browser = 'mozilla';
elseif(preg_match('/(opr)[ \/]([\w.]+)/', $userAgent))
$browser = 'opera';
*/
// DEBUG!
//echo $userAgent."<br />";
//echo $browser." v.".$version."<br />";
return array($browser,$version, 'name'=>$browser,'version'=>$version);
}
//Function detectModernBrowser detects modern browsers to enable HTML5 audio/video players
//It compares user agent and versions agains a list of browsers known to support html5 audio/video tags
function detectModernBrowser()
{
$supportHTML5audioTag = array("msie","firefox","chrome","safari");
$supportHTML5videoTag = array("msie","chrome","safari"); //firefox does not fully support mp4 videos yet
//for each browser, which is the minimum required version that supports HTML5 audio and video tags
$minumumRequiredVersion = array(
"msie" => 9,
"firefox" => 29,
"safari" => 5,
"chrome" => 36,
);
$browser = browserAndVersion();
$browsername = $browser[0];
$browserMajorVersion = $browser[1];
$HTML5audiosupport = FALSE;
if (in_array($browser[0], $supportHTML5audioTag)) {
//echo "<br/>Browser: ".$browsername." - Version: ".$browserMajorVersion." supports HTML5 audio tag";
if ($browserMajorVersion >= $minumumRequiredVersion[$browsername]) $HTML5audiosupport = TRUE;
//echo $HTML5audiosupport;
}
$HTML5videosupport = FALSE;
if (in_array($browser[0], $supportHTML5videoTag)) {
//echo "<br/>Browser: ".$browsername." - Version: ".$browserMajorVersion." supports HTML5 video tag";
if ($browserMajorVersion >= $minumumRequiredVersion[$browsername]) $HTML5videosupport = TRUE;
//echo $HTML5audiosupport;
}
$browserCompatibility = array($HTML5audiosupport,$HTML5videosupport);
//print_r($browserCompatibility);
return $browserCompatibility;
}
function isItAvideo($podcast_filetype) {
$listOfVideoFormats = array("mpg","mpeg","mov","mp4","wmv","3gp","avi","flv","m4v");
if (in_array($podcast_filetype, $listOfVideoFormats)) { // if it is a video
return TRUE;
}
}
function showButtons($filenameWithoutExtension,$podcast_filetype,$url,$upload_dir,$recent_count,$absolutePathEpisode,$enablestreaming) {
$buttonsOutput = '<p>';
//// Button "More" - in the permalink it is not show (no numeric var passed)
if (is_numeric($recent_count)) $buttonsOutput .= '<a class="btn btn-default" href="?name='.urlencode($filenameWithoutExtension).'.'.$podcast_filetype.'"><i class="fa fa-search"></i> '._("More").'</a>&nbsp;&nbsp;';
//// Button Watch (takes into account $enablestreaming from config.php)
$browserAudioVideoSupport = detectModernBrowser();
if ($enablestreaming == "yes" AND isItAvideo($podcast_filetype) == TRUE AND $browserAudioVideoSupport[1] == TRUE AND !detectMobileDevice()) {
//javascript:; is added as an empty link for href
$buttonsOutput .= '<a href="javascript:;" class="btn btn-default" onclick="$(\'#videoPlayer'.$recent_count.'\').fadeToggle();$(this).css(\'font-weight\',\'bold\');"><i class="fa fa-youtube-play"></i> '._("Watch").'</a>&nbsp;&nbsp;';
}
//// Button download
//Download button doesn't appear for episodes with future publication date (security reasons)
if (!publishInFuture($absolutePathEpisode)) {
//iOS device has been reported having some trouble downloading episode using the "download.php" forced download...
if (!detectMobileDevice()) {
//show button (FORCED) download using download.php
$buttonsOutput .= '<a class="btn btn-default" href="'.$url.'download.php?filename='.urlencode($filenameWithoutExtension).'.'.$podcast_filetype.'"><i class="fa fa-download"></i> '._("Download").'</a>';
}
else { // SHOW BUTTON DOWNLOAD THAT links directly to the file (so no problems with PHP forcing headers)
//Write "watch" or "listen" in mobile devices.
if (isItAvideo($podcast_filetype) == TRUE) {
$buttonsOutput .= '<a class="btn btn-default" href="'.$url.$upload_dir.urlencode($filenameWithoutExtension).'.'.$podcast_filetype.'"><i class="fa fa-youtube-play"></i> '._("Watch").'</a>';
}
//if it's audio
else if ($podcast_filetype=="mp3" OR $podcast_filetype=="m4a"){
$buttonsOutput .= '<a class="btn btn-default" href="'.$url.$upload_dir.urlencode($filenameWithoutExtension).'.'.$podcast_filetype.'"><i class="fa fa-play"></i> '._("Listen").'</a>';
} else {
$buttonsOutput .= '<a class="btn btn-default" href="'.$url.$upload_dir.urlencode($filenameWithoutExtension).'.'.$podcast_filetype.'"><i class="fa fa-download"></i> '._("Download").'</a>';
}
}
}
$buttonsOutput .= '</p>';
return $buttonsOutput;
}
function showStreamingPlayers($filenameWithoutExtension,$podcast_filetype,$url,$upload_dir,$recent_count) {
$playersOutput = "";
$browserAudioVideoSupport = detectModernBrowser();
//// AUDIO PLAYER (MP3)
if ($browserAudioVideoSupport[0] == TRUE AND $podcast_filetype=="mp3") { //if browser supports HTML5
$showplayercode = '<audio style="width:80%;" controls preload="none">
<source src="'.$url.$upload_dir.$filenameWithoutExtension.'.mp3" type="audio/mpeg">
'._("Your browser does not support the audio player").'
</audio>';
$playersOutput .= ''.$showplayercode.'<br />';
}
// Flash Player disabled from version 2.5
/*
else { //if no support for HTML5, then flash player just for mp3
if($podcast_filetype=="mp3") { //if not mobile
include ("components/player/player.php");
$playersOutput .= ''.$showplayercode.'<br />';
}
}
*/
//// END AUDIO PLAYER (MP3)
//// VIDEO PLAYER (MP4)
// If the file is a video and the browser supports HTML5 video tag
if (isItAvideo($podcast_filetype) == TRUE AND $browserAudioVideoSupport[1] == TRUE) {
$playersOutput .= '<video width="85%" id="videoPlayer'.$recent_count.'" style="display:none;" controls preload="none">
<source src="'.$url.$upload_dir.$filenameWithoutExtension.'.'.$podcast_filetype.'" type="video/mp4">
'._("Your browser does not support the video player").'
</video>';
$playersOutput .= '<br />';
}
return $playersOutput;
}
function retrieveMediaFileDetails ($MediaFile,$absoluteURL,$filenameWithoutExtension,$imgDir) {
if ($filenameWithoutExtension != NULL AND $imgDir != NULL) {
$extraDataSent = TRUE;
// echo 'File name no ext: '.$filenameWithoutExtension.'<br>image dir: '.$imgDir.'<br>';
} else {
$extraDataSent = FALSE;
}
require_once($absoluteURL."components/getid3/getid3.php"); //Lib to read ID3 tags in media files
$getID3 = new getID3; //initialize getID3 engine
$ThisFileSizeInMB = round(filesize($MediaFile)/1048576,2);
$ThisFileInfo = $getID3->analyze($MediaFile); //read file tags
$file_duration = @$ThisFileInfo['playtime_string'];
//$file_type = @$ThisFileInfo['fileformat'];
$file_bitrate = @$ThisFileInfo['bitrate']/1000;
$file_freq = @$ThisFileInfo['audio']['sample_rate'];
$file_embedded_image = NULL;
//// Title from ID3 tags
$thisFileTitleID3 = NULL;
if (isset($ThisFileInfo['tags']['id3v2']['title'][0]) AND $ThisFileInfo['tags']['id3v2']['title'][0] != NULL) { //ID3 v2
$thisFileTitleID3 = @$ThisFileInfo['tags']['id3v2']['title'][0];
} elseif (isset($ThisFileInfo['tags']['id3v1']['title'][0]) AND $ThisFileInfo['tags']['id3v1']['title'][0] != NULL) { //ID3 v1
$thisFileTitleID3 = @$ThisFileInfo['tags']['id3v1']['title'][0];
}
//// Artist from ID3 tags
$thisFileArtistID3 = NULL;
if (isset($ThisFileInfo['tags']['id3v2']['artist'][0]) AND $ThisFileInfo['tags']['id3v2']['artist'][0] != NULL) { //ID3 v2
$thisFileArtistID3 = @$ThisFileInfo['tags']['id3v2']['artist'][0];
} elseif (isset($ThisFileInfo['tags']['id3v1']['artist'][0]) AND $ThisFileInfo['tags']['id3v1']['artist'][0] != NULL) { //ID3 v1
$thisFileArtistID3 = @$ThisFileInfo['tags']['id3v1']['artist'][0];
}
//Image embedded in the MP3 - Extract and Save
if($extraDataSent AND isset($ThisFileInfo['id3v2']['APIC'][0]) AND !file_exists($absoluteURL.$imgDir.$filenameWithoutExtension.'.png') AND !file_exists($absoluteURL.$imgDir.$filenameWithoutExtension.'.jpg')) {
$imageMimeType = $ThisFileInfo['id3v2']['APIC'][0]['image_mime'];
$imageData = $ThisFileInfo['id3v2']['APIC'][0]['data'];
//$file_embedded_image = 'data:'.$ThisFileInfo['id3v2']['APIC'][0]['image_mime'].';charset=utf-8;base64,'.base64_encode( $ThisFileInfo['id3v2']['APIC'][0]['data']);
// echo 'Image Embedded:<br><img id="FileImage" width="150" src="'.$file_embedded_image.'" />';
//Save image file extracted from ID3 v2 APIC (attached picture) tag
$data = 'data:'.$imageMimeType.';base64,'.base64_encode($imageData);
list($type, $data) = explode(';', $data);
list(, $data) = explode(',', $data);
$data = base64_decode($data);
//choose extension between png and jpg (jpg by default)
if ($imageMimeType == "image/png") $thisImageExtension = "png";
else $thisImageExtension = "jpg";
//write file
file_put_contents($absoluteURL.$imgDir.$filenameWithoutExtension.'.'.$thisImageExtension.'', $data);
}
return array($ThisFileSizeInMB,$file_duration,$file_bitrate,$file_freq,$thisFileTitleID3,$thisFileArtistID3);
}
function readMediaDir ($absoluteurl,$upload_dir) {
//List of directories or files to exclude
$toExclude = array("..",".","index.htm","_vti_cnf",".DS_Store",".svn",".xml");
$handle = opendir ($absoluteurl.$upload_dir);
$files_array = array(); //null array
while (($filename = readdir ($handle)) !== false)
{
if (!in_array($filename, $toExclude)) $files_array[$filename] = filemtime ($absoluteurl.$upload_dir.$filename);
}
//$files_array has the file name as key and the file date as value - here we sort inversely by time
arsort ($files_array); //opposite of asort
//Now that the array as been ordered by date (most recent on top), we can keep just keys (file names)
$fileNamesList = array_keys($files_array);
//array containing all the accepted files names in media folder, with the exception of $toExclude
return $fileNamesList;
}
##################################################################################
##################################################################################
## GENERATE PODCAST RSS FEED
//GeneratePodcastFeed $outputInFile TRUE writes to a file (feed.xml), FALSE prints on screen, $manualRegeneration means that the function is called explicitly by the user (and writeEpisodeXMLDB is called)
function generatePodcastFeed ($outputInFile,$category,$manualRegeneration) {
//include functions and variables in config.php
include("core/includes.php");
//// Set custom web url (shown in iTunes Store), if specified in config.php
if (isset($feed_iTunes_LINKS_Website) AND $feed_iTunes_LINKS_Website != NULL) {
$podcastWebHomePage = $feed_iTunes_LINKS_Website; }
else { $podcastWebHomePage = $url; }
//// Define feed filename
$feedfilename = $absoluteurl.$feed_dir."feed.xml";
//// Rewrite the language var to adhere to ISO639
$feed_language = languageISO639($feed_language);
##### Clean categories strings
#Depurate feed content according to iTunes specifications
$itunes_category[0] = depurateContent($itunes_category[0]);
$itunes_category[1] = depurateContent($itunes_category[1]);
$itunes_category[2] = depurateContent($itunes_category[2]);
//If a different URL is specified in config.php
if (isset($feed_URL_replace) AND $feed_URL_replace != NULL)
{ $feed_url = $feed_URL_replace; }
else { $feed_url = $url.$feed_dir."feed.xml"; }
//iTunes Cover art (jpg or png)
if (file_exists($absoluteurl.$img_dir.'itunes_image.jpg')) {
$podcastCoverArt = $url.$img_dir.'itunes_image.jpg';
} else if (file_exists($absoluteurl.$img_dir.'itunes_image.png')) {
$podcastCoverArt = $url.$img_dir.'itunes_image.png';
} else { $podcastCoverArt = ""; }
//RSS FEED HEADER
$head_feed =
'<?xml version="1.0" encoding="'.$feed_encoding.'"?>
<!-- generator="Podcast Generator '.$podcastgen_version.'" -->
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xml:lang="'.$feed_language.'" version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>'.$podcast_title.'</title>
<link>'.$podcastWebHomePage.'</link>
<atom:link href="'.$feed_url.'" rel="self" type="application/rss+xml" />
<description>'.$podcast_description.'</description>
<generator>Podcast Generator '.$podcastgen_version.' - http://www.podcastgenerator.net</generator>
<lastBuildDate>'.date("r").'</lastBuildDate>
<language>'.$feed_language.'</language>
<copyright>'.$copyright.'</copyright>
<itunes:image href="'.$podcastCoverArt.'" />
<image>
<url>'.$podcastCoverArt.'</url>
<title>'.$podcast_title.'</title>
<link>'.$podcastWebHomePage.'</link>
</image>
<itunes:summary>'.$podcast_description.'</itunes:summary>
<itunes:subtitle>'.$podcast_subtitle.'</itunes:subtitle>
<itunes:author>'.$author_name.'</itunes:author>
<itunes:owner>
<itunes:name>'.$author_name.'</itunes:name>
<itunes:email>'.$author_email.'</itunes:email>
</itunes:owner>
<itunes:explicit>'.$explicit_podcast.'</itunes:explicit>
';
//// iTunes categories (and subcategories, which are separated by :)
//category 1
if ($itunes_category[0]!=NULL) {
$tmpcat = explode(":",$itunes_category[0]);
$head_feed.= '
<itunes:category text="'.$tmpcat[0].'">';
//Sub Category
if (isset($tmpcat[1]) AND $tmpcat[1]!=NULL) $head_feed.= '<itunes:category text="'.$tmpcat[1].'" />';
$head_feed.= '</itunes:category>
';
} //end category 1
//category 2
if ($itunes_category[1]!=NULL) {
$tmpcat = explode(":",$itunes_category[1]);
$head_feed.= '<itunes:category text="'.$tmpcat[0].'">';
//Sub Category
if (isset($tmpcat[1]) AND $tmpcat[1]!=NULL) $head_feed.= '<itunes:category text="'.$tmpcat[1].'" />';
$head_feed.= '</itunes:category>
';
} //end category 2
//category 3
if ($itunes_category[2]!=NULL) {
$tmpcat =explode(":",$itunes_category[2]);
$head_feed.= '<itunes:category text="'.$tmpcat[0].'">';
//Sub Category
if (isset($tmpcat[1]) AND $tmpcat[1]!=NULL) $head_feed.= '<itunes:category text="'.$tmpcat[1].'" />';
$head_feed.= '</itunes:category>
';
} //end category 3
//// List all the items (i.e. podcast episodes)
// Open podcast directory
$fileNamesList = readMediaDir ($absoluteurl,$upload_dir);
$episodes_feed = NULL; //define variable
if (!empty($fileNamesList)) { // If media directory contains files
$episodesCounter = 0; //set counter to zero
// Loop through each file in the media directory
foreach ($fileNamesList as $singleFileName) {
//Limit episodes in the feed (from config.php)
if ($episodesCounter < $recent_episode_in_feed OR $recent_episode_in_feed == "All") {
////Validate the current episode
//NB. validateSingleEpisode returns [0] episode is supported (bool), [1] Episode Absolute path, [2] Episode XML DB absolute path,[3] File Extension (Type), [4] File MimeType, [5] File name without extension, [6] episode file supported but to XML present
$thisPodcastEpisode = validateSingleEpisode($singleFileName);
////If episode is supported and has a related xml db, and if it's not set to a future date OR if it's set for a future date but you are logged in as admin
if (($thisPodcastEpisode[0]==TRUE AND !publishInFuture($thisPodcastEpisode[1]))) {
////Parse XML data related to the episode
// NB. Function parseXMLepisodeData returns: [0] episode title, [1] short description, [2] long description, [3] image associated, [4] iTunes keywords, [5] Explicit language,[6] Author's name,[7] Author's email,[8] PG category 1, [9] PG category 2, [10] PG category 3, [11] file_info_size, [12] file_info_duration, [13] file_info_bitrate, [14] file_info_frequency
$thisPodcastEpisodeData = parseXMLepisodeData($thisPodcastEpisode[2]);
//// If feed manually regenerated, recreate XML DB for each file when XML does not contain file data such as size, duration etc... (i.e. <fileInfoPG> tag)
// NB. The following function is transitional, to enable new XML tags in the file XML data introduced with PG 2.3: it can be removed in future versions.
// We check for data about episode size ($thisPodcastEpisodeData[11]) cause all the episodes should have it, if not, the XML was generated with a version of PG < 2.3
// We also check whether $thisPodcastEpisodeData[3] (image) is null. From PG 2.4 the image field can be a) a file name (for retro compatibility with older versions), b) 1 (mp3 parsed for embedded image. If image exists the file is extracted automatically in the images/ folder by the function retrieveMediaFileDetails)
if ($manualRegeneration AND $thisPodcastEpisodeData[11] == NULL OR $manualRegeneration AND $thisPodcastEpisodeData[3] == "") { //NB $thisPodcastEpisodeData[3] = to "" empty and not NULL (it exists but does not contain any value).
//// Remapping data from parseXMLepisodeData to be sent as a parameter to writeEpisodeXMLDB
$thisEpisodeDataToWriteInXML[0] = $thisPodcastEpisodeData[0]; // Title
$thisEpisodeDataToWriteInXML[1] = $thisPodcastEpisodeData[1]; // Short Desc
$thisEpisodeDataToWriteInXML[2] = $thisPodcastEpisodeData[2]; // Long Desc
//Image embedded or specified in the XML file is empty (no values)
if ($thisPodcastEpisodeData[3] == "") $thisEpisodeDataToWriteInXML[3] = 1; // assign value of 1 (so in future it won't be processed)
else $thisEpisodeDataToWriteInXML[3] = $thisPodcastEpisodeData[3]; // Image
$thisEpisodeDataToWriteInXML[4] = array($thisPodcastEpisodeData[8],$thisPodcastEpisodeData[9],$thisPodcastEpisodeData[10]); // Categories
$thisEpisodeDataToWriteInXML[5] = $thisPodcastEpisodeData[4]; // Keywords
$thisEpisodeDataToWriteInXML[6] = $thisPodcastEpisodeData[5]; // Explicit
$thisEpisodeDataToWriteInXML[7] = $thisPodcastEpisodeData[6]; // Auth name
$thisEpisodeDataToWriteInXML[8] = $thisPodcastEpisodeData[7]; // Auth email
//Episode size and data from GETID3 from retrieveMediaFileDetails function
//NB retrieveMediaFileDetails returns: [0] $ThisFileSizeInMB, [1] $file_duration, [2] $file_bitrate, [3] $file_freq, [4] $thisFileTitleID3, [5] $thisFileArtistID3
$episodeID3 = retrieveMediaFileDetails ($thisPodcastEpisode[1],$absoluteurl,$thisPodcastEpisode[5],$img_dir);
//Rewrite the XML data file of this episode (including the fileInfoPG tag)
writeEpisodeXMLDB($thisEpisodeDataToWriteInXML,$absoluteurl,$thisPodcastEpisode[1],$thisPodcastEpisode[2],$thisPodcastEpisode[5],TRUE);
} //end if $manualRegeneration
//// If category is specified, show just episodes belonging to it (if the current is not, skip this loop)
if (isset($category) AND $category != NULL AND $category != $thisPodcastEpisodeData[8] AND $category != $thisPodcastEpisodeData[9] AND $category != $thisPodcastEpisodeData[10]) {
continue;
}
//// Content Depuration (to avoid validation errors in the RSS feed)
$text_title = depurateContent($thisPodcastEpisodeData[0]); //title
$text_shortdesc = depurateContent($thisPodcastEpisodeData[1]); //short desc
$text_longdesc = iTunesSummaryLinks(depurateContent($thisPodcastEpisodeData[2]));
$text_keywordspg = depurateContent($thisPodcastEpisodeData[4]); //Keywords
$text_authornamepg = depurateContent($thisPodcastEpisodeData[6]); //author's name
$text_authoremailpg = depurateContent($thisPodcastEpisodeData[7]);
// Other Data from the file
$text_explicit = $thisPodcastEpisodeData[5];
$file_size = filesize($thisPodcastEpisode[1]);
$filetime = filemtime($thisPodcastEpisode[1]);
$filepubdate = date ('r', $filetime);
$filemimetype = $thisPodcastEpisode[4];
$fileDuration = $thisPodcastEpisodeData[12];
$episodes_feed.= '
<item>
<title>'.$text_title.'</title>
<itunes:subtitle>'.$text_shortdesc.'</itunes:subtitle>
<itunes:summary>'.$text_longdesc.'</itunes:summary>
<description>'.$text_shortdesc.'</description>
<link>'.$link.$singleFileName.'</link>
<enclosure url="'.$url.$upload_dir.$singleFileName.'" length="'.$file_size.'" type="'.$filemimetype.'"/>
<guid>'.$link.$singleFileName.'</guid>
';
//// Duration
if($fileDuration != NULL) {
$episodes_feed.= '<itunes:duration>'.$fileDuration.'</itunes:duration>
';
}
//Image associated to single episode
if (file_exists($absoluteurl.$img_dir.$thisPodcastEpisode[5].'.jpg')) {
$episodes_feed.= '<itunes:image href="'.$url.$img_dir.$thisPodcastEpisode[5].'.jpg" />
';
}
else if (file_exists($absoluteurl.$img_dir.$thisPodcastEpisode[5].'.png')) {
$episodes_feed.= '<itunes:image href="'.$url.$img_dir.$thisPodcastEpisode[5].'.png" />
';
}
//// Author
// If no author specified, use default author from config.php
if ($text_authornamepg == NULL OR $text_authornamepg == ",") {
$episodes_feed.= '<author>'.$author_email.' ('.$author_name.')</author>
<itunes:author>'.$author_name.'</itunes:author>
';
} else {
$episodes_feed.= '<author>'.$text_authoremailpg.' ('.$text_authornamepg.')</author>
<itunes:author>'.$text_authornamepg.'</itunes:author>
';
}
//// Keywords
if ($text_keywordspg!=NULL) { //if keywords are present
$episodes_feed.= '<itunes:keywords>'.$text_keywordspg.'</itunes:keywords>
';
}
//// Explicit
if ($text_explicit!=NULL) {
$episodes_feed.= '<itunes:explicit>'.$text_explicit.'</itunes:explicit>
';
}
//// File Date
$episodes_feed.= '<pubDate>'.$filepubdate.'</pubDate>
</item>
';
$episodesCounter++; // increment recent counter
} // END - If episode is supported
} // END - Limit episodes in the feed
} // END - Loop through each file in the media directory
} // END - If media directory contains files
//// RSS Feed Tail
$tail_feed = '
</channel>
</rss>';
//// Construct Output
$finalRSSfeed = $head_feed.$episodes_feed.$tail_feed;
// Output in a file
if ($outputInFile == TRUE) {
$fp1 = fopen($feedfilename, "w+"); //Open for reading and empty
fclose($fp1);
$fp = fopen($feedfilename, "a+"); //testa xml
fwrite($fp, $finalRSSfeed);
fclose($fp);
}
// Output on screen
else {
echo $finalRSSfeed;
}
if (!isset($episodesCounter)) $episodesCounter = 0;
return $episodesCounter;
}
## END - GENERATE PODCAST RSS FEED
##################################################################################
function attachToEpisode ($episodeFileNameWithoutExtension,$episodeFileExtension,$episodeTitle) {
//include functions and variables in config.php
include("core/includes.php");
//NB $url comes from config.php
$fullURL = $url."?name=".$episodeFileNameWithoutExtension.'.'.$episodeFileExtension; //full URL of the episode
$outputToReturn = NULL;
// CUSTOMIZED CODE TO EMBED along with each episode
// IF a file called embed-code.txt is manually created in the root of Podcast Generator. The content of that file will be displayed along with each episode
if(file_exists($absoluteurl."embed-code.txt")){
$embeddedcodetoshow = file_get_contents($absoluteurl."embed-code.txt");
$outputToReturn .= $embeddedcodetoshow; }
//SOCIAL NETWORKS INTEGRATION
//if the parameter "noextras" (e.g. ?p=archive&cat=all&noextras) is passed in the GET, then no social network integration is displayed
if (!isset($_GET['noextras'])) {
if (in_array(TRUE,$enablesocialnetworks)) { //IF at least one value of config.php is true
$outputToReturn .= displaySocialNetworkButtons($fullURL,$episodeTitle,$enablesocialnetworks[0],$enablesocialnetworks[1],$enablesocialnetworks[2]); //0 is FB, 1 twitter, 2 G+
//Blank space
$outputToReturn .= '<br />';
}
}
return $outputToReturn;
}
function validateSingleEpisode ($episodeFile) {
//include functions and variables in config.php
include("core/includes.php");
$episodeFile_parts = divideFilenameFromExtension($episodeFile); // PHP >= 5.2.0 needed
$episodeFilenameWithoutExtension = $episodeFile_parts[0];
$EpisodeFileExtension = strtolower($episodeFile_parts[1]); //lowercase extension
$checkEpisodeFileFormat = checkFileType($EpisodeFileExtension,$absoluteurl);
$episodeFileType = $checkEpisodeFileFormat[0];
$episodeFileMimeType = $checkEpisodeFileFormat[1];
$episodeFileFullPath = $absoluteurl.$upload_dir.$episodeFile;
$episodeFileXMLDB = $absoluteurl.$upload_dir.$episodeFilenameWithoutExtension.'.xml'; //database file
//If media file is ok and XML file is associated to it
if (isset($episodeFileType) AND $EpisodeFileExtension==$episodeFileType AND file_exists($episodeFileXMLDB)) {
//NB. $GoForIt = TRUE means that the episode file format is supported, it has a corresponding XML data file
$GoForIt = TRUE;
$OkButNoXMLDBpresent = FALSE;
}
//If media file is ok but no XML file is associated (i.e. auto index / FTP feature)
else if (isset($episodeFileType) AND $EpisodeFileExtension==$episodeFileType AND !file_exists($episodeFileXMLDB)) {
$GoForIt = FALSE;
$OkButNoXMLDBpresent = TRUE;
}
else {
$GoForIt = FALSE;
$OkButNoXMLDBpresent = FALSE;
}
return array($GoForIt,$episodeFileFullPath,$episodeFileXMLDB,$episodeFileType,$episodeFileMimeType,$episodeFilenameWithoutExtension,$OkButNoXMLDBpresent);
}
//DETECT WHETHER USER IS LOGGED-IN OR NOT
function isUserLogged () {
//// Security code (Register Globals ON)
if (isset($_REQUEST['GLOBALS'])) { exit; }
//read user and md5 pwd from config.php
if (file_exists("config.php")) include("config.php");
//compare sessions to stored user and md5 pwd
if(isset($_SESSION["user_session"]) AND $_SESSION["user_session"]==$username AND md5($_SESSION["password_session"])==$userpassword) { return TRUE; }
else { return FALSE; }
}
// Is the episode set to a future date?
function publishInFuture($filefullpath) {
$fileTime = 0;
if (file_exists($filefullpath)) $fileTime = filemtime($filefullpath);
if ($fileTime > time()) return TRUE;
else return FALSE;
}
function parseXMLepisodeData ($episodeFileXMLDB) {
$parser = simplexml_load_file($episodeFileXMLDB,'SimpleXMLElement',LIBXML_NOCDATA);
//var_dump($parser); //Debug
//NB. to handle CDATA values see: http://blog.evandavey.com/2008/04/how-to-fix-simplexml-cdata-problem-in-php.html
//Parse the episode in the xml file - just one episode (array [0]) is stored in each XML file
$episode_title = $parser->episode[0]->titlePG[0]; //episode title
$episode_shortdesc = $parser->episode[0]->shortdescPG[0]; //short description
$episode_longdesc = $parser->episode[0]->longdescPG[0]; // long description
$episode_imgpg = $parser->episode[0]->imgPG[0]; // image (url) associated to episode
$episode_keywordspg = $parser->episode[0]->keywordsPG[0]; //iTunes keywords
$episode_explicitpg = $parser->episode[0]->explicitPG[0]; //explicit podcast (yes or no)
$episode_authornamepg = $parser->episode[0]->authorPG[0]->namePG[0]; //author's name
$episode_authoremailpg = $parser->episode[0]->authorPG[0]->emailPG[0]; //author's email
//categories
$episode_category1 = $parser->episode[0]->categoriesPG[0]->category1PG[0];
$episode_category2 = $parser->episode[0]->categoriesPG[0]->category2PG[0];
$episode_category3 = $parser->episode[0]->categoriesPG[0]->category3PG[0];
//Until PG 2.2 this data was read from the media file in real time, from 2.3+ it'll be stored in the XML
$file_info_size = NULL;
$file_info_duration = NULL;
$file_info_bitrate = NULL;
$file_info_frequency = NULL;
if (isset($parser->episode[0]->fileInfoPG[0]->size[0])) $file_info_size = $parser->episode[0]->fileInfoPG[0]->size[0];
if (isset($parser->episode[0]->fileInfoPG[0]->duration[0])) $file_info_duration = $parser->episode[0]->fileInfoPG[0]->duration[0];
if (isset($parser->episode[0]->fileInfoPG[0]->bitrate[0])) $file_info_bitrate = $parser->episode[0]->fileInfoPG[0]->bitrate[0];
if (isset($parser->episode[0]->fileInfoPG[0]->frequency[0])) $file_info_frequency = $parser->episode[0]->fileInfoPG[0]->frequency[0];
return array($episode_title,$episode_shortdesc,$episode_longdesc,$episode_imgpg,$episode_keywordspg,$episode_explicitpg,$episode_authornamepg,$episode_authoremailpg,$episode_category1,$episode_category2,$episode_category3,$file_info_size,$file_info_duration,$file_info_bitrate,$file_info_frequency);
}
// $readID3 is a bool (true on first upload and on manual RSS regeneration)
function writeEpisodeXMLDB ($thisEpisodeData,$absoluteurl,$episodeFileAbsPath,$episodeXMLDBAbsPath,$episodeFileNameWithoutExtension,$readID3) {
include($absoluteurl."core/includes.php");
//NB. $thisEpisodeData array contains [0] $title, [1] $description, [2] $long_description, [3] $image_new_name, [4] $category (array), [5] $keywords, [6] $explicit, [7] $auth_name, [8] $auth_email
$xmlfiletocreate = '<?xml version="1.0" encoding="'.$feed_encoding.'"?>
<PodcastGenerator>
<episode>
<titlePG><![CDATA['.$thisEpisodeData[0].']]></titlePG>
<shortdescPG><![CDATA['.$thisEpisodeData[1].']]></shortdescPG>
<longdescPG><![CDATA['.$thisEpisodeData[2].']]></longdescPG>
<imgPG>'.$thisEpisodeData[3].'</imgPG>
<categoriesPG>
<category1PG>';
if(isset($thisEpisodeData[4][0]) AND $thisEpisodeData[4][0]!= NULL){
$xmlfiletocreate .= depurateContent($thisEpisodeData[4][0]);
}
$xmlfiletocreate .='</category1PG>
<category2PG>';
if(isset($thisEpisodeData[4][1]) AND $thisEpisodeData[4][1]!= NULL){
$xmlfiletocreate .= depurateContent($thisEpisodeData[4][1]);
}
$xmlfiletocreate .='</category2PG>
<category3PG>';
if(isset($thisEpisodeData[4][2]) AND $thisEpisodeData[4][2]!= NULL){
$xmlfiletocreate .= depurateContent($thisEpisodeData[4][2]);
}
$xmlfiletocreate .='</category3PG>
</categoriesPG>
<keywordsPG><![CDATA['.$thisEpisodeData[5].']]></keywordsPG>
<explicitPG>'.$thisEpisodeData[6].'</explicitPG>
<authorPG>
<namePG>'.depurateContent($thisEpisodeData[7]).'</namePG>
<emailPG>'.$thisEpisodeData[8].'</emailPG>
</authorPG>';
$episodeID3 = array(); //Declaration
if ($readID3 == TRUE) {
//Episode size and data from GETID3 from retrieveMediaFileDetails function
//NB retrieveMediaFileDetails returns: [0] $ThisFileSizeInMB, [1] $file_duration, [2] $file_bitrate, [3] $file_freq, [4] $thisFileTitleID3, [5] $thisFileArtistID3
$episodeID3 = retrieveMediaFileDetails ($episodeFileAbsPath,$absoluteurl,$episodeFileNameWithoutExtension,$img_dir);
$xmlfiletocreate .='
<fileInfoPG>';
if(isset($episodeID3[0]) AND $episodeID3[0]!= NULL){
$xmlfiletocreate .= '
<size>'.$episodeID3[0].'</size>';
}
if(isset($episodeID3[1]) AND $episodeID3[1]!= NULL){
$xmlfiletocreate .= '
<duration>'.$episodeID3[1].'</duration>';
}
//NB variable bitrate is rounded to int
if(isset($episodeID3[2]) AND $episodeID3[2]!= NULL){
$xmlfiletocreate .= '
<bitrate>'.round($episodeID3[2]).'</bitrate>';
}
if(isset($episodeID3[3]) AND $episodeID3[3]!= NULL){
$xmlfiletocreate .= '
<frequency>'.$episodeID3[3].'</frequency>';
}
}
$xmlfiletocreate .='
</fileInfoPG>
</episode>
</PodcastGenerator>';
//// Write the XMK file
$fp = fopen($episodeXMLDBAbsPath,'w');
fwrite($fp,$xmlfiletocreate);
fclose($fp);
}
// NB. Former "FTP Feature"
function autoIndexingEpisodes () {
include("core/includes.php");
// Open podcast directory and read all the files contained
$fileNamesList = readMediaDir ($absoluteurl,$upload_dir);
if (!empty($fileNamesList)) { // If media directory contains files
$episodesCounter = 0; //set counter to zero
// Loop through each file in the media directory
foreach ($fileNamesList as $singleFileName) {
////Validate the current episode
//NB. validateSingleEpisode returns [0] episode is supported (bool), [1] Episode Absolute path, [2] Episode XML DB absolute path,[3] File Extension (Type), [4] File MimeType, [5] File name without extension, [6] episode file supported but to XML present
$thisPodcastEpisode = validateSingleEpisode($singleFileName);
////If episode is supported and does NOT have a related xml db
if ($thisPodcastEpisode[6]==TRUE) {
// From config.php
if ($strictfilenamepolicy == "yes") {
$episodeNewFileName = date('Y-m-d')."_".renamefilestrict($thisPodcastEpisode[5]);
}
else {
$episodeNewFileName = renamefile($thisPodcastEpisode[5]);
}
//lowercase extension
$episodeNewFileExtension = strtolower($thisPodcastEpisode[3]);
// New file full path
$episodeNewNameAbsPath = $absoluteurl.$upload_dir.$episodeNewFileName.'.'.$episodeNewFileExtension;
//if file already exists add an incremental suffix
$filesuffix = NULL;
while (file_exists($episodeNewNameAbsPath)) {
$filesuffix++;
$episodeNewNameAbsPath = $absoluteurl.$upload_dir.$episodeNewFileName.$filesuffix.'.'.$episodeNewFileExtension;
}
if (file_exists($thisPodcastEpisode[1])) {
//rename episode
rename ($thisPodcastEpisode[1],$episodeNewNameAbsPath);
// Change file date to now
touch($episodeNewNameAbsPath,time());
} else { exit; }
//Episode size and data from GETID3 from retrieveMediaFileDetails function
//NB retrieveMediaFileDetails returns: [0] $ThisFileSizeInMB, [1] $file_duration, [2] $file_bitrate, [3] $file_freq, [4] $thisFileTitleID3, [5] $thisFileArtistID3
$episodeID3 = retrieveMediaFileDetails ($episodeNewNameAbsPath,$absoluteurl,$thisPodcastEpisode[5],$img_dir);
//// Assign title and short description (from ID3 title and artist, respectively. Or default)
if ($episodeID3[4]!= "") $thisEpisodeTitle = $episodeID3[4];
else $thisEpisodeTitle = $thisPodcastEpisode[5];
if ($episodeID3[5]!= "") $thisEpisodeShortDesc = $episodeID3[5];
else $thisEpisodeShortDesc = _("Podcast Episode");
// Use GETID3 Title and Artist to fill title and description automatically
$thisEpisodeData = array($thisEpisodeTitle,$thisEpisodeShortDesc,NULL,NULL,NULL,NULL,$explicit_podcast,NULL,NULL);
$episodeXMLDBAbsPath = $absoluteurl.$upload_dir.$episodeNewFileName.$filesuffix.'.xml';
//// Creating xml file associated to episode
writeEpisodeXMLDB($thisEpisodeData,$absoluteurl,$episodeNewNameAbsPath,$episodeXMLDBAbsPath,$episodeNewFileName.$filesuffix,TRUE);
$episodesCounter++;
} // END - If episode is supported
} // END - Loop through each file
} // END - If media directory contains files
return $episodesCounter;
}
?>