astroport/www/LOVELand/g1barre/image.php

336 lines
14 KiB
PHP

<?php
header ("Content-type: image/png");
if(isset($_GET['lang'])) {
if(empty($_GET['lang'])) $langdetect = true;
else $lang = $_GET['lang'];
}
require('lib/locales.php');
include('lib/phpqrcode/qrlib.php');
function isDate(&$date, $format){
$champsDate = date_parse_from_format($format, $date);
$date = DateTime::createFromFormat($format, $date);
return checkdate($champsDate['month'], $champsDate['day'], $champsDate['year']);
}
function hex2RGB($hexStr, $returnAsString = false, $seperator = ',') {
$hexStr = preg_replace("/[^0-9A-Fa-f]/", '', $hexStr); // Gets a proper hex string
$rgbArray = array();
if (strlen($hexStr) == 6) { //If a proper hex code, convert using bitwise operation. No overhead... faster
$colorVal = hexdec($hexStr);
$rgbArray['red'] = 0xFF & ($colorVal >> 0x10);
$rgbArray['green'] = 0xFF & ($colorVal >> 0x8);
$rgbArray['blue'] = 0xFF & $colorVal;
} elseif (strlen($hexStr) == 3) { //if shorthand notation, need some string manipulations
$rgbArray['red'] = hexdec(str_repeat(substr($hexStr, 0, 1), 2));
$rgbArray['green'] = hexdec(str_repeat(substr($hexStr, 1, 1), 2));
$rgbArray['blue'] = hexdec(str_repeat(substr($hexStr, 2, 1), 2));
} else {
return false; //Invalid hex color code
}
return $returnAsString ? implode($seperator, $rgbArray) : $rgbArray; // returns the rgb string or the associative array
}
function display_column($img,$font_file,$icon_file,$icone,$txt1,$txt2,$x,$y,$color){
$fontsize_icon = 20;
$font_size1 = 15;
$font_size2 = 10;
$type_space = imagettfbbox($fontsize_icon, 0, $icon_file, json_decode($icone));
$icon_width = abs($type_space[4] - $type_space[0]);
$font = 3;
$font_width = imagefontwidth($font);
$txt_width2 = $font_width*strlen($txt2);
imagettftext($img, $fontsize_icon, 0, $x-$icon_width/2, $y, $color, $icon_file, json_decode($icone));
$type_space = imagettfbbox($font_size1, 0, $font_file, $txt1);
$txt_width1 = abs($type_space[4] - $type_space[0]);
imagettftext($img, $font_size1, 0, $x-$txt_width1/2, $y+$fontsize_icon+10, $color, $font_file, $txt1);
$type_space = imagettfbbox($font_size2, 0, $font_file, $txt2);
$txt_width2 = abs($type_space[4] - $type_space[0]);
imagettftext($img, $font_size2, 0, $x-$txt_width2/2, $y+$fontsize_icon+15+$font_size1, $color, $font_file, $txt2);
}
function display($img){
imagepng($img);
imagedestroy($img);
}
// ===============================================================================================================
// Définition des variables
$api_node = 'duniter-g1.p2p.legal';
$format_pubkey = '#^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{43,44}$#';
$units = ['quantitative','relative'];
date_default_timezone_set('Europe/Paris');
$today = new DateTime();
$format = 'Y-m-d';
$display_qrcode = (!empty($_GET['display_qrcode']));
$titre = (!empty($_GET['title'])) ? $_GET['title'] : utf8_decode(tr('title_default'));
$node = (!empty($_GET['node'])) ? $_GET['node'] : 'g1.duniter.org';
$logo = (!empty($_GET['logo'])) ? $_GET['logo'] : 'no-logo';
$logo = 'img/logos/png/' . $logo . '.png';
if (!file_exists($logo)){$logo='no-logo';}
$whitespace = 25;
$content_x = $whitespace;
$content_y = $whitespace+5;
$font_size = 15;
$fontsize_icon = 20;
$font_error = 2;
$arial_font = './lib/webfonts/LiberationSans-Regular.ttf';
$font900 = './lib/webfonts/fontawesome/900/fa-solid-900.ttf';
$font400 = './lib/webfonts/fontawesome/400/fa-regular-400.ttf';
$height = 200;
$width = 500;
$barwidth = 450;
$barheight = 25;
// Adaptation de la largeur de l'image en fonction des paramètres
if ($logo != 'no-logo'){
$img_logo = imagecreatefrompng($logo);
$largeur_logo = imagesx($img_logo);
$width += $largeur_logo + $whitespace;
$content_x += $largeur_logo + $whitespace;
}
// Vérification du format de la pubkey
if (!empty($_GET['pubkey'])){
if (preg_match($format_pubkey, $_GET['pubkey'])){
$pubkey = $_GET['pubkey'];
// ASTROPORT UGGLY PATCH.... MMMMmmmm. but it should works.
// $YOU = shell_exec('ps auxf --sort=+utime | grep -w ipfs | grep -v -E "color=auto|grep" | tail -n 1 | cut -d " " -f 1');
// $pubkey = shell_exec('cat /home/'.$YOU.'/.ssb/secret.dunikey | grep "pub:" | cut -d " " -f 2');
$contribution_url = 'https://' . $api_node . '/api/#/v1/payment/' . $pubkey . '?amount=10|20|50|100|1000&amp;comment=don&amp;redirect_url=https%3A%252F%252F' . $api_node . '&amp;cancel_url=https%3A%252F%252F' . $api_node;
$display_pubkey = (!empty($_GET['display_pubkey']));
if ($display_qrcode){
$qrcode_path = 'img/qrcodes/' . $pubkey . '.png';
if (!file_exists($qrcode_path)){
QRcode::png($pubkey, $qrcode_path);
}
$img_qrcode = imagecreatefrompng($qrcode_path);
$qrcode_width = imagesx($img_qrcode);
$width += $qrcode_width + $whitespace;
}
}
}
// Création de l'image de base
$source = imagecreatetruecolor ($width, $height);
imagealphablending($source, false);
// Définition des couleurs de base
$transparence = imagecolorallocatealpha($source, 255, 255, 255, 127);
$progress_back = ImageColorAllocate($source,233,236,239); // #e9ecef
$noir = imagecolorallocate($source, 0, 0, 0); // #000000
$background_color = (!empty($_GET['background_color'])) ? '#' . $_GET['background_color'] : '#FFF';
$background_color = hex2RGB($background_color);
if (!$background_color){
$background_color = imagecolorallocate($source, 255, 255, 255);
}else{
$background_color = imagecolorallocate($source, $background_color['red'], $background_color['green'], $background_color['blue']);
}
// Remplissage du fond avec gestion de la transparence
imagefill($source, 0, 0, $background_color);
imagefilledrectangle($source, 0, 0, $width,$height,$transparence);
imagealphablending($source, true);
imagesavealpha($source, true);
imagefill($source, 0, 0, $background_color);
// Intégration du logo
if ($logo != 'no-logo'){
imagecopy($source, $img_logo, $whitespace, $whitespace, 0, 0, 150, 150);
imagedestroy($img_logo);
}
if (empty($pubkey)){
imagestring($source, $font_error, $content_x, $content_y, utf8_decode(tr('error_pubkey_missing')), $noir);
display($source);
}
// Vérification de la couleur de bordure
$border_color = (!empty($_GET['border_color'])) ? '#' . $_GET['border_color'] : '#343a40';
$border_color = hex2RGB($border_color);
if (!$border_color){
imagestring($source, $font_error, $content_x, $content_y, utf8_decode(tr('error_border_color_invalid')), $noir);
display($source);
}else{
$border_color = imagecolorallocate($source, $border_color['red'], $border_color['green'], $border_color['blue']);
}
ImageRectangle($source,0,0,$width-1,$height-1,$border_color);
ImageRectangle($source,2,2,$width-3,$height-3,$border_color);
// Vérification des dates et calcul du nombre de jours entre la date du jour et la date de fin
if (!empty($_GET['start_date'])){
$start_date = $_GET['start_date'];
$nb_col = 3;
if (!isDate($start_date, $format)){
imagestring($source, $font_error, $content_x, $content_y, utf8_decode(tr('error_date_start_invalid')), $noir);
display($source);
}
if (!empty($_GET['end_date'])){
if ($_GET['end_date'] !=0){
$end_date = $_GET['end_date'];
if (!isDate($end_date, $format)){
imagestring($source, $font_error, $content_x, $content_y, utf8_decode(tr('error_date_end_invalid')), $noir);
display($source);
}elseif ($end_date < $start_date) {
imagestring($source, $font_error, $content_x, $content_y, utf8_decode(tr('error_date_end_invalid')), $noir);
display($source);
}
}
}
}else{
// Si pas de start_date, on prend le mois courant
$start_date = new DateTime('first day of this month');
$end_date = new DateTime('last day of this month');
}
$start_date->setTime(0,0,0);
if (isset($end_date)){
$nb_col = 4;
if ($end_date < $today){
$days_left = 0;
}else{
$dteDiff = $end_date->diff($today);
$days_left = $dteDiff->format('%a');
}
}
// Génération du QRcode
if ($display_qrcode) {
imagecopymerge($source, $img_qrcode, $width - $qrcode_width - $whitespace, 42, 0, 0, 111, 111, 100);
imagedestroy($img_qrcode);
}
// Vérification du format de la valeur cible à atteindre
if (!empty($_GET['target'])){
$target = (int)$_GET['target'];
if (!is_int($target)){
imagestring($source, $font_error, $content_x, $content_y, utf8_decode(tr('error_target_not_int')), $noir);
display($source);
}elseif ($target<=0){
imagestring($source, $font_error, $content_x, $content_y, utf8_decode(tr('error_target_negative')), $noir);
display($source);
}
}else{
imagestring($source, $font_error, $content_x, $content_y, utf8_decode(tr('error_target_missing')), $noir);
display($source);
}
// Récupération des transactions entrantes entre la date de début et la date du jour
$start_timestamp = $start_date->getTimestamp();
$today_timestamp = $today->getTimestamp();
$url_json = 'https://' . $node . '/tx/history/' . $pubkey . '/times/' . $start_timestamp . '/' . $today_timestamp;
$json = @file_get_contents($url_json);
if ($json === false){
imagestring($source, 2, $content_x, $content_y, utf8_decode(tr('error_connect_node')), $noir);
display($source);
}
$json = json_decode($json);
$transactions = $json->history->received;
$total = 0;
$donneurs = [];
$tmp_timestamp = $start_timestamp;
$array_final = [];
foreach ($transactions as $transaction){
$donneur = $transaction->issuers[0];
if ($donneur != $pubkey){
if(!in_array($donneur, $donneurs)){
array_push($donneurs, $donneur);
}
$outputs = $transaction->outputs;
foreach ($outputs as $output){
if (strstr($output,$pubkey)){
$timestamp = $transaction->blockstampTime;
$output = explode(':', $output);
$montant_transaction = $output[0]/100;
if ($timestamp != $tmp_timestamp){
array_push($array_final, ['t'=>$tmp_timestamp*1000, 'y'=>(string) $total]);
}
$total += $montant_transaction;
$tmp_timestamp = $timestamp;
}
}
}
}
$donors = count($donneurs);
// Vérification de l'unité
$unit = (!empty($_GET['unit']))
? ((!in_array($_GET['unit'], $units)) ? 'quantitative' : $_GET['unit'])
: 'quantitative';
// Si l'unité est relative
if ($unit == 'relative'){
// On récupère le dernier block qui contient le DU
$url_json = 'https://' . $node . '/blockchain/with/ud';
$json = file_get_contents($url_json);
$json = json_decode($json);
$last_block_with_ud = end($json->result->blocks);
// Puis on récupère le montant du DU pour mettre à jour les données
$url_json = 'https://' . $node . '/blockchain/block/' . $last_block_with_ud;
$json = file_get_contents($url_json);
$json = json_decode($json);
$ud = $json->dividend/100;
$total = round($total/$ud);
}
$percentage = round($total/$target*100);
$percentage_bar = ($percentage>100) ? 100 : $percentage;
// ==================================================================================
// Vérification de la couleur de fonte
$font_color = (!empty($_GET['font_color'])) ? '#' . $_GET['font_color'] : '#212529';
$font_color = hex2RGB($font_color);
if (!$font_color){
imagestring($source, $font_error, $content_x, $content_y, utf8_decode(tr('error_font_color_invalid')), $noir);
display($source);
}else{
$font_color = imagecolorallocate($source, $font_color['red'], $font_color['green'], $font_color['blue']);
}
// Vérification de la couleur de la barre de progression
$progress_color = (!empty($_GET['progress_color'])) ? '#' . $_GET['progress_color'] : '#ffc107';
$progress_color = hex2RGB($progress_color);
if (!$progress_color){
imagestring($source, $font_error, $content_x, $content_y, utf8_decode(tr('error_bar_color_invalid')), $noir);
display($source);
}else{
$progress_color = imagecolorallocate($source, $progress_color['red'], $progress_color['green'], $progress_color['blue']);
}
// Affichage du titre
$title_y = ($display_pubkey) ? 23 : $content_y;
imagettftext($source, $font_size, 0, $content_x, $title_y, $font_color, $arial_font, $titre);
if ($display_pubkey){imagettftext($source, $font_size-5, 0, $content_x, $content_y+15, $font_color, $arial_font, 'Pubkey : '.$pubkey);}
// On dessine la barre de progression
$remplissage = $percentage_bar*$barwidth/100;
ImageFilledRectangle($source,$content_x+1,$content_y+$whitespace+1,$content_x+$barwidth,$content_y+$whitespace+$barheight,$progress_back);
ImageFilledRectangle($source,$content_x+1,$content_y+$whitespace+1,$content_x+$remplissage,$content_y+$whitespace+$barheight,$progress_color);
ImageRectangle($source,$content_x,$content_y+$whitespace,$content_x+$barwidth+1,$content_y+$whitespace+$barheight+1,$border_color);
imagettftext($source, $font_size, 0, $content_x+$remplissage/2, $content_y+$whitespace+$barheight/2+9, $font_color, $arial_font, $percentage . '%');
// Colonnes avec icônes Font awesome
$column = $barwidth/$nb_col;
$mid_column = $column/2;
$icone_pos_y = $content_y+$whitespace+$barheight+$whitespace+$fontsize_icon;
// Colonne 1
display_column($source,$arial_font,$font900,'"&#xF200;"',$percentage.'%',utf8_decode(tr('label_reached')),$content_x+$mid_column,$icone_pos_y,$font_color);
// Colonne 2
display_column($source,$arial_font,$font400,'"&#xF007;"',$donors,utf8_decode(tr('label_donators')),$content_x+$column+$mid_column,$icone_pos_y,$font_color);
// Colonne 3
$unit = ($unit=='relative') ? tr('ud').'Ğ1' : 'Ğ1';
$txt_target = tr('label_ontotal_short', array('total'=>$target, 'unit'=>($unit)));
$total = round($total) . ' ' . $unit;
display_column($source,$arial_font,$font400,'"&#xF3D1;"',$total,$txt_target,$content_x+2*$column+$mid_column,$icone_pos_y,$font_color);
// Colonne 4
if ($nb_col==4){
display_column($source,$arial_font,$font400,'"&#xF073;"',$days_left,utf8_decode(tr('label_remaining_d')),$content_x+3*$column+$mid_column,$icone_pos_y,$font_color);
}
// On affiche l'image finale
display($source);
?>