#!/usr/local/bin/php
<?php

/* (C) 2023-2025 Xvid Services OÜ - All Rights Reserved! */

/* Configuration */

$client_id = ""; // <-- Enter your app credentials here!
$client_secret = ""; // <-- Enter your app credentials here!

$cutoff_age = 365 * 24 * 3600; // 365 days
$recursive_depth = 1; // Max sub-directory level to search

$api_base_url = "https://api.xvid.com/v1";

/* End of Config Section */


// Log function
function xvid_log($error_message) {
    echo '[' . date("F j, Y, g:i a e O") . '] ' . $error_message . PHP_EOL;
}

// Auth function 
function get_oauth_token($clientid, $clientsecret, $expiry) {
    global $api_base_url;

    $params = array(
         "scope" => 'mediahub,autograph',
         "grant_type" => 'client_credential',
         "client_id" => $clientid,
         "client_secret" => urlencode($clientsecret),
         );

    //url-ify the data for the POST
    $params_string = '';
    foreach($params as $key=>$value) { $params_string .= $key.'='.$value.'&'; }
    rtrim($params_string, '&');

    $url = $api_base_url . '/oauth2/token/?' . 'human=true&expires_in=' . $expiry;
    $curl = curl_init($url);

    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $params_string);
    curl_setopt($curl, CURLOPT_POST, true);
    $curl_response = json_decode(curl_exec($curl));
    $response_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);

    if (($response_code == 200) && ($curl_response !== FALSE)) {
        return $curl_response->{'access_token'};
    }

    xvid_log('ERROR: Failed to obtain API access token. Error code: ' . $response_code);
    return NULL;
}

// Delete files via API
function delete_job_from_file_id($file_id, $token) {
    global $api_base_url;

    $url = $api_base_url . '/files/' . $file_id . '?human=true&access_token=' . $token;
    $curl = curl_init($url);

    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $curl_response = json_decode(curl_exec($curl), true);
    $response_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
    curl_close($curl);

    if (($response_code != 200) || ($curl_response === FALSE)) {
        xvid_log('ERROR: Failed to obtain file details for ' . $file_id);    
        return FALSE;
    }

    if (array_key_exists('file', $curl_response)) {
        $job_id = $curl_response['file']['job']['id'];

        if (strlen($job_id) == 24) { // Is valid Job ID?
            $url = $api_base_url . '/jobs/' . $job_id . '?access_token=' . $token;
            $curl = curl_init($url);
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
            curl_exec($curl);
            $response_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            curl_close($curl);

            if ($response_code == 200) {
                return TRUE;
            }
        }
        xvid_log('ERROR: Failed to delete job ' . $job_id);
    }

    return FALSE; 
}

// Find content sets older than cutoff_age and rename .htaccess file
// This causes these sets to be instantly served from your own server (or default CDN) again
// Optionally, also deletes content disabled in a previous run from the Xvid MediaHub storage
function xvid_disable_watermarking_for_old_content($search_dir, $full_delete=TRUE) {
    global $cutoff_age;
    global $recursive_depth;
    global $client_id;
    global $client_secret;

    $token = NULL;
    // If actual deletion shall be performed, we need an API token to access Xvid MediaHub API
    if ($full_delete) {
        $token = get_oauth_token($client_id, $client_secret, 7200);
    }

    $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($search_dir,
                                        RecursiveDirectoryIterator::SKIP_DOTS), 
                                        RecursiveIteratorIterator::SELF_FIRST);
    $it->setMaxDepth($recursive_depth);

    $now = time();
    foreach($it as $file_name => $file_info) {
        if(!$file_info->isFile()) {
            continue;
        }

        // Rename old .htaccess file to mark it for later deletion
        // Content set will be served from your own server (or CDN) as soon as rename() is done
        if (($file_info->getFilename() === '.htaccess') && (($now - $file_info->getMTime()) > $cutoff_age)) {
            $htaccess = file_get_contents($file_info->getPathname());

            // Double-check it's really a Xvid-generated .htaccess file...
            if (($htaccess !== FALSE) && (strpos($htaccess, 'autograph=') !== FALSE)) {
                file_put_contents($file_info->getPathname() . '_delete_me', $htaccess); // Marker for later deletion
                unlink($file_info->getPathname()); // Remove original .htaccess
                xvid_log('Renamed: ' . $file_info->getPathname());
            }
        }
        else if ($full_delete && ($token != NULL)) {
            // If .htaccess file was marked for deletion more than 24 hrs ago then 
            // ultimately delete the content from Xvid MediaHub Storage
            // WARNING: This delete is permanent and cannot be undone!!
            if (($file_info->getFilename() === '.htaccess_delete_me') && (($now - $file_info->getMTime()) > 3*24*3600)) {
                $htaccess = file_get_contents($file_info->getPathname());

                if (($htaccess !== FALSE) && (strpos($htaccess, 'autograph=') !== FALSE)) {
                    // Extract file ID from .htaccess file
                    $file_id = substr(strstr($htaccess, 'file_id='), 8, 24);

                    // Delete the parent job (with all associated files) belonging to this file_id
                    if (delete_job_from_file_id($file_id, $token)) {
                        unlink($file_info->getPathname()); // Finally, remove .htaccess_delete_me
                        xvid_log('Deleted: ' . $file_info->getPathname() . '|' . $file_id);
                    }
                }
            }
        }
    }
}

// Invoke with: php -f ./xvid_cleanup_old_sets.php Pathname
// Check we're invoked with proper amount of params...
if ($argc < 2) {
    echo "Usage: php -f ./xvid_cleanup_old_sets.php Pathname" . PHP_EOL . PHP_EOL;
    echo "Parameters:" . PHP_EOL;
    echo "    Pathname  - Directory Path under which to recursively search for old content sets" . PHP_EOL;
    echo PHP_EOL;
    echo "Example: ./xvid_cleanup_old_sets.php /home/httpd/mysite.com/public_html/members/content/upload/" . PHP_EOL;
    exit(1);
}

xvid_disable_watermarking_for_old_content($argv[1]);
 
?>

