Last active
June 12, 2024 15:06
-
-
Save mrladeia/fd8b5a4c9251dbe05ff9c521fca9332e to your computer and use it in GitHub Desktop.
Clear Cloudflare cache Chevereto
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Cloudflare's purge directly depends on what your url looks like, in my case it's an example: https://s1.domain.com/Akd3X.jpg | |
That is, with the name of the encoded image. | |
Within my script I had to place a function to encode the image because the deleted image table does not have its code encoded. | |
I quickly made this script a while ago, it doesn't follow any good programming practices. | |
This script is not plug and play in the variables, each case must be analyzed. | |
*/ | |
//crontab, you need define run every 5 minutes | |
//database select will pick up images deleted 5 minutes ago | |
//*/5 * * * * sudo -u nginx php /home/nginx/script/cf-purge.php > /home/nginx/script/cf-purge.log | |
//salt chevereto | |
$chvSalt = ""; //you can get salt here https://yourdomain.app/dashboard/settings/system | |
$chvUrlDirect = "https://s1.domain.com/"; //direct url of images, Example: https://s1.domain.com/xxxxx.png you need put: https://s1.domain.com/ | |
//cloudflare api config | |
$cfEmail = "[email protected]"; | |
$cfAuthKey = ""; | |
$cfZone = "zone of your cloudflare, you can get on Zone ID in dashboard"; | |
//mysql | |
$servername = "127.0.0.1"; | |
$username = "user"; | |
$password = "pass"; | |
$dbname = "dbname"; | |
//encode decode image name | |
//this function was captured within the chevereto code | |
function chvEncDec($in, $salt, $action = 'encode'){ | |
$cheveretoID = null; | |
$index = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; | |
$id_padding = intval("5000"); | |
// Use a stock version of the hashed values (faster execution) | |
if (isset($cheveretoID)) { | |
$passhash = $cheveretoID['passhash']; | |
$p = $cheveretoID['p']; | |
$i = $cheveretoID['i']; | |
} else { | |
for ($n = 0; $n < strlen($index); ++$n) { | |
$i[] = substr($index, $n, 1); | |
} | |
$passhash = hash('sha256', $salt); | |
$passhash = (strlen($passhash) < strlen($index)) ? hash('sha512', $salt) : $passhash; | |
for ($n = 0; $n < strlen($index); ++$n) { | |
$p[] = substr($passhash, $n, 1); | |
} | |
$cheveretoID = [ | |
'passhash' => $passhash, | |
'p' => $p, | |
'i' => $i, | |
]; | |
} | |
array_multisort($p, SORT_DESC, $i); | |
$index = implode($i); | |
$base = strlen($index); | |
if ($action == 'decode') { | |
$out = 0; | |
$len = strlen($in) - 1; | |
for ($t = 0; $t <= $len; ++$t) { | |
$bcpow = bcpow((string) $base, (string) ($len - $t)); | |
$out = $out + strpos($index, substr($in, $t, 1)) * $bcpow; | |
} | |
if ($id_padding > 0) { | |
$out = $out / $id_padding; | |
} | |
$out = (int) sprintf('%s', $out); | |
} else { | |
if ($id_padding > 0) { | |
$in = $in * $id_padding; | |
} | |
$out = ''; | |
for ($t = floor(log((float) $in, $base)); $t >= 0; --$t) { | |
$bcp = bcpow((string) $base, (string) $t); | |
$a = floor($in / $bcp) % $base; | |
$out = $out . substr($index, $a, 1); | |
$in = $in - ($a * $bcp); | |
} | |
} | |
return $out; | |
} | |
function cfPurge($files, $cfEmail, $cfAuthKey, $cfZone){ | |
$curl = curl_init(); | |
curl_setopt_array($curl, array( | |
CURLOPT_URL => 'https://api.cloudflare.com/client/v4/zones/' . $cfZone . '/purge_cache', | |
CURLOPT_RETURNTRANSFER => true, | |
CURLOPT_ENCODING => '', | |
CURLOPT_MAXREDIRS => 10, | |
CURLOPT_TIMEOUT => 0, | |
CURLOPT_FOLLOWLOCATION => true, | |
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, | |
CURLOPT_CUSTOMREQUEST => 'POST', | |
CURLOPT_POSTFIELDS => $files, | |
CURLOPT_HTTPHEADER => array( | |
'Content-Type: application/json', | |
'X-Auth-Email: ' . $cfEmail, | |
'X-Auth-Key: ' . $cfAuthKey, | |
), | |
)); | |
$response = curl_exec($curl); | |
curl_close($curl); | |
return $response; | |
} | |
try { | |
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); | |
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | |
//get images deleted from table chv_deletions | |
//images deleted with 5 min blocks ago | |
$stmt = $conn->prepare(" | |
SELECT * FROM chv_deletions WHERE deleted_date_gmt | |
BETWEEN | |
date_format(DATE_SUB(NOW(),INTERVAL 10 MINUTE), '%Y-%m-%d %H:%i:00') | |
AND | |
date_format(DATE_SUB(NOW(),INTERVAL 5 MINUTE), '%Y-%m-%d %H:%i:00') | |
ORDER BY deleted_date_gmt DESC; | |
"); | |
$stmt->execute(); | |
// set the resulting array to associative | |
//$result = $stmt->setFetchMode(PDO::FETCH_ASSOC); | |
$result = $stmt->fetchAll(); | |
if(count($result)<1){ | |
echo "nothing for the purge"; | |
exit(); | |
} | |
#print_r($result); | |
$allImages = []; | |
foreach($result as $v){ | |
#$ext = "." . pathinfo($v['deleted_content_original_filename'], PATHINFO_EXTENSION); | |
//encode image from id | |
$urlNameDecoded = $chvUrlDirect . chvEncDec($v['deleted_content_id'], $chvSalt); | |
//set all images variants | |
$allImages[] = $urlNameDecoded . ".jpg"; | |
$allImages[] = $urlNameDecoded . ".jpeg"; | |
$allImages[] = $urlNameDecoded . ".png"; | |
$allImages[] = $urlNameDecoded . ".bmp"; | |
$allImages[] = $urlNameDecoded . ".gif"; | |
$allImages[] = $urlNameDecoded . ".webp"; | |
$allImages[] = $urlNameDecoded . ".md.jpg"; | |
$allImages[] = $urlNameDecoded . ".md.jpeg"; | |
$allImages[] = $urlNameDecoded . ".md.png"; | |
$allImages[] = $urlNameDecoded . ".md.bmp"; | |
$allImages[] = $urlNameDecoded . ".md.gif"; | |
$allImages[] = $urlNameDecoded . ".md.webp"; | |
$allImages[] = $urlNameDecoded . ".th.jpg"; | |
$allImages[] = $urlNameDecoded . ".th.jpeg"; | |
$allImages[] = $urlNameDecoded . ".th.png"; | |
$allImages[] = $urlNameDecoded . ".th.bmp"; | |
$allImages[] = $urlNameDecoded . ".th.gif"; | |
$allImages[] = $urlNameDecoded . ".th.webp"; | |
} | |
//create a chuncks of 30 images, beacause the limit of api cloudflare | |
$imagesChunks = array_chunk($allImages, 30); | |
foreach($imagesChunks as $v){ | |
$files = json_encode(["files" => $v], JSON_UNESCAPED_SLASHES); | |
$cfReturn = cfPurge($files, $cfEmail, $cfAuthKey, $cfZone); | |
echo $cfReturn; | |
echo $files . "\n\n"; | |
} | |
} catch(PDOException $e) { | |
echo "Error: " . $e->getMessage(); | |
} | |
$conn = null; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment