Compare commits

..

2 Commits

Author SHA1 Message Date
db91775a5d vers 2.1.1 2026-01-28 19:01:04 +01:00
6b15afb9da vers. 2.1.1 2026-01-28 18:59:25 +01:00
112 changed files with 14658 additions and 14012 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*:Zone.Identifier

77
.htaccess Normal file
View File

@@ -0,0 +1,77 @@
# Abilita il rewrite engine
RewriteEngine On
# Imposta la directory base (modifica se necessario)
# Se l'app è in una sottocartella, usa: RewriteBase /nome_cartella/
RewriteBase /newapp.rpigroup.it/
# Reindirizza richieste HTTP a HTTPS (opzionale, decommentare se necessario)
# RewriteCond %{HTTPS} off
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Non reindirizzare file e cartelle esistenti
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Escludi file statici dal rewriting
RewriteCond %{REQUEST_URI} !\.(css|js|jpg|jpeg|png|gif|svg|ico|xml|json|woff|woff2|ttf|eot)$ [NC]
# Reindirizza tutto a index.php mantenendo il path
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
# Impedisci l'accesso diretto a file sensibili
<FilesMatch "^(config|\.htaccess|\.env)">
Order Allow,Deny
Deny from all
</FilesMatch>
# Gestione MIME types
<IfModule mod_mime.c>
AddType application/javascript js
AddType text/css css
AddType image/svg+xml svg
AddType application/vnd.ms-fontobject eot
AddType font/ttf ttf
AddType font/otf otf
AddType font/woff woff
AddType font/woff2 woff2
</IfModule>
# Abilita compressione GZIP (opzionale)
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json
</IfModule>
# Cache control (opzionale - commentato perché hai lo script no-cache)
# <IfModule mod_expires.c>
# ExpiresActive On
# ExpiresByType image/jpg "access plus 1 month"
# ExpiresByType image/jpeg "access plus 1 month"
# ExpiresByType image/gif "access plus 1 month"
# ExpiresByType image/png "access plus 1 month"
# ExpiresByType image/svg+xml "access plus 1 month"
# ExpiresByType text/css "access plus 1 week"
# ExpiresByType application/javascript "access plus 1 week"
# </IfModule>
# Header no-cache per sviluppo (rimuovi in produzione se usi la cache)
<IfModule mod_headers.c>
<FilesMatch "\.(html|php)$">
Header set Cache-Control "no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "0"
</FilesMatch>
</IfModule>
# Sicurezza aggiuntiva
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
</IfModule>
# Disabilita directory listing
Options -Indexes
# Abilita follow symlinks (necessario per RewriteRule)
Options +FollowSymLinks

BIN
.htaccess:Zone.Identifier Normal file

Binary file not shown.

View File

@@ -1,5 +1,7 @@
<?php
header('Content-Type: text/html; charset=UTF-8');
// Verifica se è una richiesta AJAX
$is_ajax = !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';

Binary file not shown.

View File

@@ -1,5 +1,8 @@
<?php
header('Content-Type: text/html; charset=UTF-8');
// Information App
$title_site = "RPIGroup Play";
$description_site = "Ascolta le radio del gruppo RPIGroup";

Binary file not shown.

View File

@@ -1,5 +1,7 @@
<?php
header('Content-Type: text/html; charset=UTF-8');
// Determina il percorso base dell'applicazione
$script_name = $_SERVER['SCRIPT_NAME'];
$script_path = dirname($script_name);

Binary file not shown.

View File

@@ -1,10 +1,27 @@
<?php
header('Content-Type: text/html; charset=UTF-8');
// File: config/getPage.inc.php
// Whitelist delle pagine valide
$validPages = ['home', 'radio', 'tv', 'play', 'playtv', 'page'];
$validSubPages = ['about', 'contact', 'copyright', 'addradio', 'termini-condizioni', 'policy-privacy', 'changelog'];
// Rileva se l'utente sta usando un dispositivo mobile
function isMobile() {
return preg_match("/(android|avantgo|blackberry|bolt|boost|cricket|docomo|fone|hiptop|mini|mobi|palm|phone|pie|tablet|up\.browser|up\.link|webos|wos)/i", $_SERVER["HTTP_USER_AGENT"]);
}
// Funzione per sanitizzare l'input
function sanitizePageInput($input) {
// Rimuovi caratteri pericolosi
$input = preg_replace('/[^a-zA-Z0-9\-_]/', '', $input);
// Previeni path traversal
$input = str_replace(['..', '/', '\\'], '', $input);
return $input;
}
// Recupera l'URL richiesto
$request_uri = $_SERVER['REQUEST_URI'];
$path = substr(urldecode($request_uri), strlen($base_path));
@@ -23,9 +40,45 @@ if (isset($path_parts[0]) && $path_parts[0] == 'index.php') {
array_shift($path_parts);
}
// Determina la pagina da mostrare in base all'URL
$page = isset($path_parts[0]) && !empty($path_parts[0]) ? $path_parts[0] : 'home';
$param = isset($path_parts[1]) && !empty($path_parts[1]) ? $path_parts[1] : '';
// Determina la pagina da mostrare in base all'URL con validazione
$page = 'home'; // Default sicuro
$param = '';
if (isset($path_parts[0]) && !empty($path_parts[0])) {
$requestedPage = sanitizePageInput($path_parts[0]);
// Verifica se la pagina è nella whitelist
if (in_array($requestedPage, $validPages)) {
$page = $requestedPage;
} else {
// Pagina non valida, redirect a 404
$page = 'home';
error_log("Tentativo di accesso a pagina non valida: " . $path_parts[0]);
}
}
if (isset($path_parts[1]) && !empty($path_parts[1])) {
$requestedParam = sanitizePageInput($path_parts[1]);
// Validazione specifica per tipo di pagina
if ($page === 'play' || $page === 'playtv') {
// Per play/playtv, il parametro deve essere un numero
if (ctype_digit($requestedParam)) {
$param = $requestedParam;
} else {
error_log("ID stazione non valido: " . $path_parts[1]);
$page = 'home';
}
} elseif ($page === 'page') {
// Per page, il parametro deve essere nella whitelist
if (in_array($requestedParam, $validSubPages)) {
$param = $requestedParam;
} else {
error_log("Sottopagina non valida: " . $path_parts[1]);
$page = 'home';
}
}
}
// Debug (rimuovi in produzione)
error_log("Page: $page, Param: $param, Path: $path");
error_log("Page: $page, Param: $param, Path: $path");

Binary file not shown.

View File

@@ -1,54 +1,202 @@
<?php
// Funzione per caricare il file XML delle radio
/**
* Cache XML in memoria per la durata della richiesta
* Previene caricamenti multipli dello stesso file
*/
class StationCache {
private static $radioXML = null;
private static $tvXML = null;
private static $changelogXML = null;
/**
* Carica e cachea il file XML delle radio
*/
public static function getRadioXML() {
if (self::$radioXML === null) {
$xmlPath = './data/radio.xml';
if (!file_exists($xmlPath)) {
error_log("File XML non trovato: $xmlPath");
return false;
}
if (!is_readable($xmlPath)) {
error_log("File XML non leggibile: $xmlPath");
return false;
}
libxml_use_internal_errors(true);
self::$radioXML = simplexml_load_file($xmlPath);
if (self::$radioXML === false) {
$errors = libxml_get_errors();
foreach ($errors as $error) {
error_log("Errore XML radio.xml: " . trim($error->message) . " (Linea: " . $error->line . ")");
}
libxml_clear_errors();
return false;
}
}
return self::$radioXML;
}
/**
* Carica e cachea il file XML delle TV
*/
public static function getTVXML() {
if (self::$tvXML === null) {
$xmlPath = './data/tv.xml';
if (!file_exists($xmlPath)) {
error_log("File XML non trovato: $xmlPath");
return false;
}
if (!is_readable($xmlPath)) {
error_log("File XML non leggibile: $xmlPath");
return false;
}
libxml_use_internal_errors(true);
self::$tvXML = simplexml_load_file($xmlPath);
if (self::$tvXML === false) {
$errors = libxml_get_errors();
foreach ($errors as $error) {
error_log("Errore XML tv.xml: " . trim($error->message) . " (Linea: " . $error->line . ")");
}
libxml_clear_errors();
return false;
}
}
return self::$tvXML;
}
/**
* Carica e cachea il file XML del changelog
*/
public static function getChangelogXML() {
if (self::$changelogXML === null) {
$xmlPath = './data/changelog.xml';
if (!file_exists($xmlPath)) {
error_log("File XML non trovato: $xmlPath");
return false;
}
if (!is_readable($xmlPath)) {
error_log("File XML non leggibile: $xmlPath");
return false;
}
libxml_use_internal_errors(true);
self::$changelogXML = simplexml_load_file($xmlPath);
if (self::$changelogXML === false) {
$errors = libxml_get_errors();
foreach ($errors as $error) {
error_log("Errore XML changelog.xml: " . trim($error->message) . " (Linea: " . $error->line . ")");
}
libxml_clear_errors();
return false;
}
}
return self::$changelogXML;
}
}
/**
* Funzione per caricare tutte le stazioni radio
* @return array|SimpleXMLElement Array di stazioni o array vuoto in caso di errore
*/
function loadRadioStations() {
$xml = simplexml_load_file('./data/radio.xml');
if ($xml === false) {
error_log("Errore nel caricamento del file XML: data/radio.xml");
$xml = StationCache::getRadioXML();
if ($xml === false || !isset($xml->station)) {
error_log("Impossibile caricare le stazioni radio");
return [];
}
return $xml->station;
}
// Funzione per ottenere una singola stazione radio
/**
* Funzione per ottenere una singola stazione radio
* @param int $id ID della stazione
* @return SimpleXMLElement|null Stazione o null se non trovata
*/
function getRadioStation($id) {
$xml = simplexml_load_file('./data/radio.xml');
$xml = StationCache::getRadioXML();
if ($xml === false) {
error_log("Errore nel caricamento del file XML: data/radio.xml");
error_log("Impossibile caricare XML radio per ID: $id");
return null;
}
if (!isset($xml->station)) {
error_log("Nessuna stazione trovata nel file XML");
return null;
}
foreach ($xml->station as $station) {
if ((int)$station->id === $id) {
if ((int)$station->id === (int)$id) {
return $station;
}
}
error_log("Stazione radio non trovata con ID: $id");
return null;
}
// Funzione per caricare il file XML delle TV
/**
* Funzione per caricare tutte le stazioni TV
* @return array|SimpleXMLElement Array di stazioni o array vuoto in caso di errore
*/
function loadTVStations() {
$xml = simplexml_load_file('./data/tv.xml');
if ($xml === false) {
error_log("Errore nel caricamento del file XML: data/tv.xml");
$xml = StationCache::getTVXML();
if ($xml === false || !isset($xml->station)) {
error_log("Impossibile caricare le stazioni TV");
return [];
}
return $xml->station;
}
// Funzione per ottenere una singola stazione TV
/**
* Funzione per ottenere una singola stazione TV
* @param int $id ID della stazione
* @return SimpleXMLElement|null Stazione o null se non trovata
*/
function getTVStation($id) {
$xml = simplexml_load_file('./data/tv.xml');
$xml = StationCache::getTVXML();
if ($xml === false) {
error_log("Errore nel caricamento del file XML: data/tv.xml");
error_log("Impossibile caricare XML TV per ID: $id");
return null;
}
if (!isset($xml->station)) {
error_log("Nessuna stazione TV trovata nel file XML");
return null;
}
foreach ($xml->station as $station) {
if ((int)$station->id === $id) {
if ((int)$station->id === (int)$id) {
return $station;
}
}
error_log("Stazione TV non trovata con ID: $id");
return null;
}
$changelog = simplexml_load_file("./data/changelog.xml") or die("Errore: Impossibile accedere al file CHANGELOG");
$version_app = $changelog->version->number[0];
/**
* Carica il changelog e la versione dell'app
*/
$changelog = StationCache::getChangelogXML();
$version_app = "1.0.0"; // Versione di default
if ($changelog !== false && isset($changelog->version) && isset($changelog->version[0]->number)) {
$version_app = (string)$changelog->version[0]->number;
} else {
error_log("Impossibile leggere la versione dal changelog.xml, uso versione di default: $version_app");
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -2,6 +2,23 @@
<changelog>
<version>
<number>2.1.1</number>
<logs>
<log>Corretti alcuni bug che impedivano l'accesso al player dal link esterno</log>
<log>Correzione e bugfix di problematiche varie.</log>
</logs>
</version>
<version>
<number>2.1.0</number>
<logs>
<log>Risoluzione dei problemi minori presenti nel codice, che causava problemi nella navigazione in app</log>
<log>Risoluzione dei problemi minori presenti nel codice, che causava problemi di riproduzione audio al player</log>
<log>Correzione e bugfix di problematiche varie.</log>
</logs>
</version>
<version>
<number>2.0.4</number>
<logs>

Binary file not shown.

View File

@@ -35,7 +35,7 @@
<contentplayer></contentplayer>
</station>
<station>
<!-- <station>
<id>4</id>
<name>RC105 Christmas - Eboli</name>
<slogan>La musica di Natale, in giro per Eboli</slogan>
@@ -44,7 +44,7 @@
<stream>https://srvone.radio.asvhosting.com/listen/rc105_christmas/radio.aac</stream>
<streamhls>https://srvone.radio.asvhosting.com/hls/rc105_christmas/live.m3u8</streamhls>
<contentplayer></contentplayer>
</station>
</station> -->
<station>
<id>5</id>

Binary file not shown.

BIN
data/tv.xml:Zone.Identifier Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
img/tv.png:Zone.Identifier Normal file

Binary file not shown.

View File

@@ -11,6 +11,8 @@
# Version app: VEDERE IN CHANGELOG.XML
*/
header('Content-Type: text/html; charset=UTF-8');
# Import config file
include_once './config/config.php';

BIN
index.php:Zone.Identifier Normal file

Binary file not shown.

690
js/app.js

File diff suppressed because it is too large Load Diff

BIN
js/app.js:Zone.Identifier Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<div id="proradio-secondary-header" class="proradio-secondaryhead proradio-primary" style="border-bottom: solid 3px #3849a8;">
<style>
@@ -59,6 +61,7 @@
<a href="https://www.radiocitta105.it" target="_blank"><span class="link">Radio Città 105</span></a>
<a href="https://www.radiodiffusionelibera.com" target="_blank"><span class="link">Radio DiffusioneLibera</span></a>
<a href="https://www.co-municare.it" target="_blank"><span class="link">Co-Municare.it</span></a>
<a href="https://www.ineboli.it" target="_blank"><span class="link">InEboli</span></a>
<a href="https://app.rpigroup.it" target="_blank"><span class="link active">RPIGroup Play</span></a>
</div>
</div>

Binary file not shown.

View File

@@ -1,3 +1,8 @@
<?php
// Debug: verifica valori delle variabili (rimuovi dopo aver risolto)
// echo "<!-- DEBUG - Page: " . htmlspecialchars($page) . " | Param: " . htmlspecialchars($param) . " -->\n";
?>
<div class="header">
<div class="logo-section">
<img src="<?=$base_path?>/img/RpiGroupPlayWHITE.png" alt="Logo">
@@ -94,5 +99,5 @@
<a href="<?php echo $base_path; ?>/page/policy-privacy" data-page="page/policy-privacy" class="navLink">Policy Privacy</a> •
<a href="<?php echo $base_path; ?>/page/changelog" data-page="page/changelog" class="navLink">Changelog</a>
</div>
<div class="copyright-section" <?php if($is_mobile){ ?> style="padding: 10px 0 25px;" <? } ?>>&copy; 2025 RPIGroup • Versione: <?php echo $version_app; ?></div>
<div class="copyright-section" <?php if($is_mobile){ ?> style="padding: 10px 0 25px;" <?php } ?>>© 2025 RPIGroup • Versione: <?php echo $version_app; ?></div>
</div>

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<h1 class="titlePage">Pagina non trovata</h1>
<p class="text-center">La pagina che hai provato a cercare non esiste o non è disponibile.</p>

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<h1 class="titlePage">Come funziona RPIGroup Play?</h1>
<hr>

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<h1 class="titlePage">Aggiungi la tua radio</h1>
<hr>

Binary file not shown.

View File

@@ -1,13 +1,31 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<h1 class="titlePage">Changelog</h1>
<p class="subtitlePage">Visualizza tutti gli ricevuti</p>
<p class="subtitlePage">Visualizza tutti gli aggiornamenti ricevuti</p>
<?php
foreach($changelog->version as $version){
// Verifica che $changelog sia stato caricato correttamente in getStation.inc.php
if (isset($changelog) && $changelog !== false && isset($changelog->version)) {
// Itera attraverso le versioni
foreach($changelog->version as $version) {
echo "<hr>";
echo "<p class=\"changelogTitle\">Versione ".$version->number."</p>";
foreach($version->logs->log as $log_print){
echo "<p class=\"changelogList\">• ".$log_print."</p>";
echo "<p class=\"changelogTitle\">Versione " . htmlspecialchars((string)$version->number) . "</p>";
// Verifica che esistano i log prima di iterare
if (isset($version->logs) && isset($version->logs->log)) {
foreach($version->logs->log as $log_print) {
echo "<p class=\"changelogList\">• " . htmlspecialchars((string)$log_print) . "</p>";
}
} else {
echo "<p class=\"changelogList\" style=\"font-style: italic; color: #999;\">Nessun dettaglio disponibile per questa versione.</p>";
}
}
} else {
// Messaggio di errore se il changelog non è disponibile
echo "<hr>";
echo "<div style=\"padding: 20px; background: #fff3cd; border: 1px solid #ffc107; border-radius: 5px; margin: 20px 0;\">";
echo "<p style=\"margin: 0; color: #856404;\"><strong>Attenzione:</strong> Impossibile caricare il changelog. Il file potrebbe essere mancante o corrotto.</p>";
echo "</div>";
}
?>

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<!-- <div class="content-page">
<h2>Contatti</h2>
<div class="content-box">

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<h1 class="titlePage">Diritti d'Autore</h1>
<p class="subtitlePage">Come funziona e chi lo gestisce</p>

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<h1 class="titlePage">Benvenuto</h1>
<p class="subtitlePage">nella nuova RPIGroup Play</p>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<h1 class="titlePage">Policy Privacy</h1>
<p class="subtitlePage">Ultimo aggiornamento: 17/11/2025</p>

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<?php
// views/home.php - Vista della pagina principale
$stations = loadRadioStations();

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<h1 class="titlePage">Termini & Condizioni</h1>
<p class="subtitlePage">Ultimo aggiornamento: 17/11/2025</p>

Binary file not shown.

View File

@@ -1,3 +1,5 @@
<?php header('Content-Type: text/html; charset=UTF-8'); ?>
<h1 class="titlePage">TV</h1>
<p class="subtitlePage">Guarda in streaming <b>RC105 TV</b></p>

Binary file not shown.

59
process_contact.php.old Normal file
View File

@@ -0,0 +1,59 @@
<?php
// File: process_contact.php
// Imposta header per JSON
header('Content-Type: application/json');
// Verifica se il modulo è stato inviato
if ($_SERVER["REQUEST_METHOD"] === "POST") {
// Raccolta e pulizia dei dati
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$subject = filter_input(INPUT_POST, 'subject', FILTER_SANITIZE_STRING);
$message = filter_input(INPUT_POST, 'message', FILTER_SANITIZE_STRING);
// Validazione dei dati
$errors = [];
if (empty($name)) {
$errors[] = "Il nome è richiesto";
}
if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Email non valida";
}
if (empty($subject)) {
$errors[] = "L'oggetto è richiesto";
}
if (empty($message)) {
$errors[] = "Il messaggio è richiesto";
}
// Se non ci sono errori, procedi con l'invio della mail
if (empty($errors)) {
// Destinatario
$to = "info@tuoaggregatore.it";
// Intestazioni
$headers = "From: $name <$email>" . "\r\n";
$headers .= "Reply-To: $email" . "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();
// Prova a inviare l'email
$success = mail($to, $subject, $message, $headers);
if ($success) {
echo json_encode(['success' => true, 'message' => 'Messaggio inviato con successo']);
} else {
echo json_encode(['success' => false, 'message' => 'Impossibile inviare il messaggio']);
}
} else {
// Restituisci errori di validazione
echo json_encode(['success' => false, 'message' => implode(', ', $errors)]);
}
} else {
// Se qualcuno prova ad accedere direttamente a questa pagina
echo json_encode(['success' => false, 'message' => 'Metodo non consentito']);
}

Binary file not shown.

2
readme.md Normal file
View File

@@ -0,0 +1,2 @@
# RPIGroup Play
Il player ufficiale del gruppo RPIGroup

BIN
readme.md:Zone.Identifier Normal file

Binary file not shown.

BIN
robots.txt:Zone.Identifier Normal file

Binary file not shown.

View File

@@ -1,7 +1,4 @@
<div style="display:none">
<p><a href="https://www.jennymcnieceflowers.com/">777slot</a></p>
</div>
<script src="<?php echo $base_path; ?>/js/app.js?v=<?=time()?>"></script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More