web-dev-qa-db-fra.com

Fusionneur PHP télécharger le script dans `functions.php`

Je lance un grand site de téléchargement de mixtapes sur WordPress. Je développe actuellement un nouveau thème et j'aimerais inclure autant de fonctionnalités de site dans le functions.php du thème.

Pour servir les téléchargements, j'ai plusieurs scripts PHP. Un visiteur appelle un téléchargement en cliquant sur l’URL (exemple): http://www.tjoonz.com/house.php?id=1234&file=post-slug.
Le script désinfecte les paramètres et sert les fichiers MP3 à partir d'un répertoire de serveur privé. Mon souci principal est que ces scripts contiennent les détails de connexion à la base de données, ce que je préférerais de beaucoup utiliser $wpdb.

Scripts actuels (pour référence)

Je m'excuse si cela est un peu excessif, mais cela pourra être utile plus tard. Vous pouvez probablement passer cette partie pour l'instant si vous ne faites que lire ma question.

PHP

<?php // Tjoonz.com download script v1.2

// test arguments
if(!isset($_REQUEST['id']) || empty($_REQUEST['id']) || !isset($_REQUEST['file']) || empty($_REQUEST['file'])) 
{
    // invalid argument(s), abort script
    header("HTTP/1.0 400 Bad Request");
    die();
}

// set variables
$current_time = time();
$user_ip = $_SERVER['REMOTE_ADDR'];
$post_id = $_GET['id'];
$file_requested = $_GET['file'];
$file_name = strip_tags($file_requested);
$file_path = '/home/tjoonz/audio/house/';
$locked = false;

// test if cookie 'downloadsAllowed' is set
// this prevents hotlinking on other domains for users who haven't visited Tjoonz.com yet
if ($_COOKIE["downloadsAllowed"] == "tj00nz")
{   
    $file_full = $file_path.$file_name;
    if (file_exists($file_full)) // test if requested mixtape exists
    {
        // establish connection to database for Play Counter test
        $user="#######";
        $password="#######";
        $database="#######";
        $Host="#######";
        mysql_connect($Host,$user,$password);
        mysql_select_db($database) or die(mysql_error());

        // set timerange to 2 hours ago (right now minus 7200 seconds)
        $timerange = $current_time - 7200;
        // get all records from 'playcount_lock' table
        $locks = mysql_query("SELECT * FROM playcount_lock WHERE request_time > $timerange") or die(mysql_error()); 

        // test if current IP address has already accessed this mixtape in the last 2 hours
        while ($lock = mysql_fetch_object($locks))
        {
            // set variables with data from record
            $lock_ip = $lock->ip_address;
            $lock_id = $lock->post_id;
            $lock_time = $lock->request_time;

            // compare record data with current user data
            if($lock_ip == $user_ip && $lock_id == $post_id && ($lock_time + 7200) >= $current_time)
            {
                // match found, break out of while loop and continue with script
                $locked = true;
                break;
            }
        }

        if (!$locked) // if playcounter is not locked, update the database
        { 
            // add a lock entry for the next two hours
            mysql_query("INSERT INTO `playcount_lock` (`request_time`, `post_id`, `ip_address`) VALUES ('$current_time', '$post_id', '$user_ip')") or die(mysql_error());

            // update the play counter for this mixtape
            $post_meta = mysql_query("SELECT meta_value FROM `wp_postmeta` WHERE `meta_key` = '_played' AND `post_id` = ".$post_id);
            $count = @mysql_result($post_meta, 0);

            if($count == FALSE)
            {
                // if no plays are present, insert the metadata into table
                mysql_query("INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (".$post_id.",'_played',1)");
            }
            else
            {
                // otherwise increase the existing number of plays by 1
                $newCount = mysql_result($post_meta, 0) + 1;
                mysql_query("UPDATE `wp_postmeta` SET meta_value = ".$newCount." WHERE `meta_key` = '_played' AND `post_id` = ".$post_id);
            }
        }

        // we're done with the database, kill the connection
        mysql_close();

        // finally, send the file
        header("X-SENDFILE: ".$file_full);
        header("Content-Type: audio/mpeg");
        header("Content-Disposition: attachment; filename=".basename($file_full));
        header("Content-Length: ".filesize($file_full));
        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: public");
        header("Content-Description: File Transfer");
        header("Content-Transfer-Encoding: binary");
    }
    else // couldn't find that mixtape
    {
        header('HTTP/1.0 404 Not Found');
    }

}
else // cookie 'downloadsAllowed' not set, redirecting user to mixtape page
{
    $file_redirection = substr($file_name,0, -4);
    header("Location: http://www.tjoonz.com/house/" . $file_redirection . "/");
}

?>

JS

// when playnow is clicked, add to myPlaylist and immediately start playing the mixtape
$("body").on("click", ".jplayer-playnow", function (e) {
    e.preventDefault();

    // add to Play Queue and play it immediately
    $.jPlayer.timeFormat.showHour = true;
    $.jPlayer.timeFormat.sepHour = ":";
    $.jPlayer.timeFormat.sepMin = ":";
    $.jPlayer.timeFormat.sepSec = "";
    myPlaylist.add({
        title: $(".single-title-mixtape").text(),
        artist: $(".single-title-artist").text(),
        genre: $(".jplayer-playnow span").attr("class"),
        mp3: $(this).attr("href"),                       // <--- This is where my problem comes up for my new theme, keep reading
        poster: $(".wp-post-image").attr("src")
    }, true); // true value here makes the newly added track play immediately
});

Intentions

J'utilise le script actuel en deux étapes: lorsqu'un utilisateur clique sur le bouton PLAY, jQuery empêche la navigation vers le lien et prend l'URL pour indiquer à un lecteur de musique de récupérer le fichier. Lorsqu'un utilisateur clique sur le bouton DOWNLOADS, le navigateur ne fait que suivre et un téléchargement direct est lancé. Les deux boutons utilisent les mêmes scripts et les mêmes URL.

Dans mon nouveau script, je souhaite associer house.php, electro.php, dubstep.php, drum-and-bass.php et techno.php à un seul script prenant un paramètre genre. De plus, en fonction de la situation, je vais ajouter un paramètre pour spécifier la action (télécharger ou lire).

J'ai l'intention d'intégrer complètement le script dans functions.php. Sur une page de mixtape, deux liens seraient:

<!--Play-->
<a href="?id=<?php echo $post->ID; ?>&file=<?php tjnz_slug(); ?>&genre=<?php echo $category[0]->category_nicename; ?>&action=play">Play</a>
<!--Download-->
<a href="?id=<?php echo $post->ID; ?>&file=<?php tjnz_slug(); ?>&genre=<?php echo $category[0]->category_nicename; ?>&action=download">Download</a>

Le problème

Dans mon ancien script, je prenais simplement des liens de lecture (par nom de classe sur l'ancre) et empêchais l'action du navigateur par défaut, puis je faisais ce que je voulais. J'ai été capable de faire cela parce que je pouvais pointer sur un "vrai" fichier (par exemple house.php).

Si je devais coller le code dans functions.php, comment puis-je indiquer à mon lecteur de musique où se trouve le fichier audio? Le fichier audio ne doit pas nécessairement être un fichier MP3, comme le montre mon code actuel: j’informe jPlayer que le fichier audio se trouve sur house.php, par exemple.

Comment puis-je dire à jPlayer que le fichier provient maintenant du mystérieux functions.php? Est-ce que je lie directement à theme dir/functions.php? Cela ne semble pas être une bonne idée, mais ce n'est que mon instinct.

Comme je l'ai déjà dit, la principale raison pour laquelle le script doit être à l'intérieur de functions.php est pour pouvoir exploiter le pouvoir de $wpdb. Si un fichier PHP séparé est toujours le chemin à parcourir, j'accepterais toujours cette réponse (à condition que vous ayez sauvegardé cette théorie).

1
Marc Dingena

Vous n'appelez pas directement des éléments du fichier functions.php par référence d'URL.

Le functions.php est chargé avec le thème WordPress et vous permet d'accéder à des fonctions à partir des fichiers de modèle de thème.

La plupart de votre code peut être directement porté dans le functions.php, mais vous devrez envelopper une sorte d'interface autour de celui-ci, qui peut être appelée dans un modèle de page.

Si je le faisais, je mettrais probablement du code PHP dans le fichier index.php du thème, en haut à droite pour voir le contenu de l'objet $_REQUEST, comme vous le faites au début de votre PHP code.

Ensuite, plutôt que d’exécuter le PHP que vous avez déjà, vous pouvez appeler des fonctions se trouvant dans votre fichier functions.php qui traitent des connexions à la base de données proprement dite et qui servent le fichier.

Comme vous l'avez mentionné, vous devrez utiliser la variable globale $wpdb pour lire les tableaux. La bonne nouvelle est que, puisque vous travaillez dans la session WordPress, vous n'avez pas à vous authentifier auprès de la base de données, vous n'avez donc aucune information UN/PW. .

Votre JS sera mieux servi dans un fichier séparé de votre thème et chargé correctement dans WordPress en utilisant wp_enqueue_script .

2
user28206