<?php
######################################################################
# ZW3B.Site v7.1.2 : The Web Sites Management System
# --------------------------------------------------------------------
#
# Copyright (c) 2022 by LAB3W : O.Romain Jaillet-ramey - (orj+php+dmarc@lab3w.fr)
#
# Date Create : 2022/02/03
# Date Modify : 2023/01/13
#
# Web Domain : lab3w.fr
# Web Domain : lab3w.com
#
# Web Domain : zw3b.fr
# Web Domain : zw3b.tv
# Web Domain : zw3b.com
# Web Domain : zw3b.net
# Web Domain : zw3b.blog
# Web Domain : zw3b.eu
#
# Web Domain : ipv01.net
# Web Domain : ipv10.net
#
# This module is to manage ---------------------------- :: Descripton
#
# This program is free software. You can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License.
######################################################################

//----------------------------------------------------------------
// INI Config

ini_set('track_errors','on');
ini_set('display_errors','on');
ini_set('default_charset''UTF-8');

// INI Config
//----------------------------------------------------------------

//----------------------------------------------------------------
// Systeme de cache

# On cache
#header("Cache-Control: max-age=300");
#header("Pragma: cache, max-age=300, max-stale=600");

# No cache
header("Cache-control: private, no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");

// Systeme de cache
//----------------------------------------------------------------

//----------------------------------------------------------------
// Header Security

header('X-Frame-Options: deny'); // permet de ne pas charger cette page depuis un autre site via une iframe

// Header Security
//----------------------------------------------------------------

//----------------------------------------------------------------
// Constantes

# My Title default
define('MY_DMARC_TITLE''<a href="https://www.zw3b.com/dmarc/" title="ZW3B.Com :-: DMARC"><acronym title="Domain-based Message Authentication, Reporting and Conformance" lang="EN">DMARC</acronym> Reports</a> &copy; <a href="https://www.zw3b.site" title="ZW3B :-: The Web Site">ZW3B</a> ');

# My Title compagny
define('MY_DOMAIN_TITLE''by <a href="http://orj.lab3w.fr" title="LAB3W : O.Romain.Jaillet-ramey">LAB3W.ORJ</a>');

# My SPF : dig SPF domain.tld +short
define('MY_DOMAIN_SPF_IP', array('158.69.126.137''2607:5300:60:9389:17:4:0:1''2607:5300:60:9389:17:4c1:0:1a'));

# Root Directory (subdirectory) where XML files are stored /rootdirectory(/AAAA/MM/)
define('DIRECTORY_DMARC_REPORTS''/var/pro/web_sites/zw3b_com/www/dmarc/');

# HTML directory where JSON are stored (with write rights for www-data)
define('DIRECTORY_DMARC_STATS_JSON''/var/pro/web_sites/zw3b_com/www/web/var/dmarc/');

# HTML directory for HTML link of JSON files
define('URL_DMARC_STATS_JSON''/var/dmarc/');

# File identification name (mail server name)
define('URL_DMARC_STATS_JSON_NAME''mail_zw3b_eu');

# Hide SPF (valid) rows in Stats month
define('HIDE_MY_SPF_LINE_STATS'false);

// Constantes
//----------------------------------------------------------------

//----------------------------------------------------------------
// Functions

//define('MAX_XML_SIZE',1524288);

function get_children($vals, &$i){
    
$children = array();     // Contains node data
    
    /* Node has CDATA before it's children */
    
if (isset($vals[$i]['value']))
        
$children['VALUE'] = $vals[$i]['value'];
        
        
/* Loop through children */
        
while (++$i count($vals))
        {
            switch (
$vals[$i]['type'])
            {
                
/* Node has CDATA after one of it's children
                 (Add to cdata found before if this is the case) */
                
case 'cdata':
                    if (isset(
$children['VALUE']))
                        
$children['VALUE'] .= $vals[$i]['value'];
                        else
                            
$children['VALUE'] = $vals[$i]['value'];
                            break;
                            
/* At end of current branch */
                
case 'complete':
                    if (isset(
$vals[$i]['attributes'])) {
                        
$children[$vals[$i]['tag']][]['ATTRIBUTES'] = $vals[$i]['attributes'];
                        
$index count($children[$vals[$i]['tag']])-1;
                        
                        if (isset(
$vals[$i]['value']))
                            
$children[$vals[$i]['tag']][$index]['VALUE'] = $vals[$i]['value'];
                            else
                                
$children[$vals[$i]['tag']][$index]['VALUE'] = '';
                    } else {
                        if (isset(
$vals[$i]['value']))
                            
$children[$vals[$i]['tag']][]['VALUE'] = $vals[$i]['value'];
                            else
                                
$children[$vals[$i]['tag']][]['VALUE'] = '';
                    }
                    break;
                    
/* Node has more children */
                
case 'open':
                    if (isset(
$vals[$i]['attributes'])) {
                        
$children[$vals[$i]['tag']][]['ATTRIBUTES'] = $vals[$i]['attributes'];
                        
$index count($children[$vals[$i]['tag']])-1;
                        
$children[$vals[$i]['tag']][$index] = array_merge($children[$vals[$i]['tag']][$index], get_children($vals$i));
                    } else {
                        
$children[$vals[$i]['tag']][] = get_children($vals$i);
                    }
                    break;
                    
/* End of node, return collected data */
                
case 'close':
                    return 
$children;
            }
        }
}

/**
 * fonction qui renvoit tous les composants de l'xml
 *  $is_file est par defaut a true, s'il est false alors $xmlloc est une chaine
 *
 */
function get_xml_tree($xmlloc,$is_file=true)
{
    
$vals null;
    
$index null;
    
    if ( 
$is_file && file_exists($xmlloc)){
        
$data implode(''file($xmlloc));
    }elseif( !
$is_file ){
        
$data $xmlloc;
    }else{
        return 
FALSE;
    }
    
    
$parser xml_parser_create('ISO-8859-1');
    
xml_parser_set_option($parserXML_OPTION_SKIP_WHITE1);
    
xml_parser_set_option($parserXML_OPTION_CASE_FOLDING0);
    
xml_parse_into_struct($parser$data$vals$index);
    if(
$error_code=xml_get_error_code($parser)!=XML_ERROR_NONE){
        return 
FALSE;
    }
    
xml_parser_free($parser);
    
    
$tree = array();
    
$i 0;
    if( 
count($vals)==)    {
        return 
FALSE;
    }
    if (isset(
$vals[$i]['attributes'])){
        
$tree[$vals[$i]['tag']]['ATTRIBUTES'] = $vals[$i]['attributes'];
        
$tree[$vals[$i]['tag']][] = get_children($vals$i);
    }else
        
$tree[$vals[$i]['tag']][] = get_children($vals$i);
        
        return 
$tree;
}


function 
get_xml_tree_http($xmlloc){
    
    
$vals null;
    
$index null;
    
    if( !( 
$fp = @fopen($xmlloc,'r')) ){
        return 
FALSE;
    }else
    {
        
$data null;
        while(
$html=fread($fpMAX_XML_SIZE)){
            
$data.=$html;
        }
        
fclose($fp);
    }
    
    
// nettoyage du fichier xml pour que le parser ne plante pas.
    
$data=str_replace('(View Source for full doctype...)','',$data);
    
$parser xml_parser_create('ISO-8859-1');
    
xml_parser_set_option($parserXML_OPTION_SKIP_WHITE1);
    
xml_parser_set_option($parserXML_OPTION_CASE_FOLDING0);
    
xml_parse_into_struct($parser$data$vals$index);
    if( 
$error_code=xml_get_error_code($parser)!=XML_ERROR_NONE )    {
        return 
FALSE;
    }
    
xml_parser_free($parser);
    
    
$tree = array();
    
$i 0;
    if(
count($vals)==0){
        return 
FALSE;
    }
    if (isset(
$vals[$i]['attributes'])){
        
$tree[$vals[$i]['tag']]['ATTRIBUTES'] = $vals[$i]['attributes'];
        
$tree[$vals[$i]['tag']][] = get_children($vals$i);
    }
    else
        
$tree[$vals[$i]['tag']][] = get_children($vals$i);
        
        return 
$tree;
}

function 
read_all_files($root '.'$desc 0) {
    
$files  = array('files'=>array(), 'dirs'=>array());
    
$directories  = array();
    
$last_letter  $root[strlen($root)-1];
    
$root  = ($last_letter == '\\' || $last_letter == '/') ? $root $root.'/';
    
    
$files['root'] = $root;
    
    
$directories[]  = $root;
    
    while (
sizeof($directories)) {
        
$dir  array_pop($directories);
        if (
$handle = @opendir($dir)) {
            while (
false !== ($file readdir($handle))) {
                if (
$file == '.' || $file == '..') {
                    continue;
                }
                
$file_current $file;
                
$file  $dir.$file;
                if (
is_dir($file)) {
                    
$directory_path $file.'/';
                    
//array_push($directories, $directory_path);
                    
$files['dirs'][$file_current]['caption']  = $file_current;
                    
$files['dirs'][$file_current]['url']  = $directory_path;
                    
                    
$stat = @stat($directory_path);
                    
                    
$files['dirs'][$file_current]['infos']['dev'] = $stat['dev'];
                    
$files['dirs'][$file_current]['infos']['ino'] = $stat['ino'];
                    
$files['dirs'][$file_current]['infos']['mode']['value'] = $stat['mode'];
                    
$files['dirs'][$file_current]['infos']['mode']['humain'] = decoct($stat['mode']);
                    
$files['dirs'][$file_current]['infos']['nlink'] = $stat['nlink'];
                    
$files['dirs'][$file_current]['infos']['uid'] = $stat['uid'];
                    
$files['dirs'][$file_current]['infos']['gid'] = $stat['gid'];
                    
$files['dirs'][$file_current]['infos']['rdev'] = $stat['rdev'];
                    
$files['dirs'][$file_current]['infos']['size']['value'] = $stat['size'];
                    
//$files['dirs'][$file_current]['infos']['size']['humain'] = self::sizeSource($file);
                    
$files['dirs'][$file_current]['infos']['atime']['value'] = $stat['atime'];
                    
$files['dirs'][$file_current]['infos']['atime']['humain'] = date("l, F d, Y \a\\t H:i:s."$stat['atime']);
                    
$files['dirs'][$file_current]['infos']['mtime']['value'] = $stat['mtime'];
                    
$files['dirs'][$file_current]['infos']['mtime']['humain'] = date("l, F d, Y \a\\t H:i:s."$stat['mtime']);
                    
$files['dirs'][$file_current]['infos']['ctime']['value'] = $stat['ctime'];
                    
$files['dirs'][$file_current]['infos']['ctime']['humain'] = date("l, F d, Y \a\\t H:i:s."$stat['ctime']);
                    
$files['dirs'][$file_current]['infos']['blksize'] = $stat['blksize'];
                    
$files['dirs'][$file_current]['infos']['blocks'] = $stat['blocks'];
                    
$files['dirs'][$file_current]['infos']['mime_content_type'] = @mime_content_type($file);
                    
                } elseif (
is_file($file)) {
                    
$files['files'][$file_current]['caption']  = $file_current;
                    
$files['files'][$file_current]['url']  = $file;
                    
                    
$stat = @stat($file);
                    
//$files['files'][$file_current]['infos']  = $stat;
                    
                    
                    
$files['files'][$file_current]['infos']['dev'] = $stat['dev'];
                    
$files['files'][$file_current]['infos']['ino'] = $stat['ino'];
                    
$files['files'][$file_current]['infos']['mode']['value'] = $stat['mode'];
                    
$files['files'][$file_current]['infos']['mode']['humain'] = decoct($stat['mode']);
                    
$files['files'][$file_current]['infos']['nlink'] = $stat['nlink'];
                    
$files['files'][$file_current]['infos']['uid'] = $stat['uid'];
                    
$files['files'][$file_current]['infos']['gid'] = $stat['gid'];
                    
$files['files'][$file_current]['infos']['rdev'] = $stat['rdev'];
                    
$files['files'][$file_current]['infos']['size']['value'] = $stat['size'];
                    
//$files['files'][$file_current]['infos']['size']['humain'] = self::sizeSource($file);
                    
$files['files'][$file_current]['infos']['atime']['value'] = $stat['atime'];
                    
$files['files'][$file_current]['infos']['atime']['humain'] = date("l, F d, Y \a\\t H:i:s."$stat['atime']);
                    
$files['files'][$file_current]['infos']['mtime']['value'] = $stat['mtime'];
                    
$files['files'][$file_current]['infos']['mtime']['humain'] = date("l, F d, Y \a\\t H:i:s."$stat['mtime']);
                    
$files['files'][$file_current]['infos']['ctime']['value'] = $stat['ctime'];
                    
$files['files'][$file_current]['infos']['ctime']['humain'] = date("l, F d, Y \a\\t H:i:s."$stat['ctime']);
                    
$files['files'][$file_current]['infos']['blksize'] = $stat['blksize'];
                    
$files['files'][$file_current]['infos']['blocks'] = $stat['blocks'];
                    
$files['files'][$file_current]['infos']['mime_content_type'] = @mime_content_type($file);
                    
                }
            }
            
closedir($handle);
        }
    }
    
    if (
$desc) {
        
//arsort($files['dirs'], SORT_REGULAR | SORT_STRING);
        //arsort($files['files'], SORT_REGULAR | SORT_STRING);
        
arsort($files['dirs']);
        
arsort($files['files']);
    }
    else {
        
asort($files['dirs']);
        
asort($files['files']);
    }
    
    
    return 
$files;


//$dir = read_all_files($directory_current);
//echo '<pre>'.print_r($dir,1).'</pre>';

function files_reports_lst($dir) {
    
    
$files = array();
    
    if(isset(
$dir['files']) && is_array($dir['files'])):
    
$k 0;
    foreach(
$dir['files'] as $key => $file)
    {
        if((
$file['caption'] != ".") && ($file['caption'] != "..") && (substr($file['caption'], 01) != ".") && ($file['infos']['mime_content_type'] === 'application/xml' || $file['infos']['mime_content_type'] === 'text/xml') )
        {
            
//$currentfile = $directory.$file['caption'].'/';
            //$currentfilefake = $file['caption'].'/';
            
            
$file_explode explode('!'$file['caption']);
            
            
$fai $file_explode[0]; // fai
            
$mydomain $file_explode[1]; // mysite
            
$timestamp_begin $file_explode[2]; // begin
            
            
$timestamp_end str_replace('.xml'''$file_explode[3]); // end
            
$timestamp_end preg_replace('/[-](.+)/si'''$timestamp_end); // end
            
            
$files[$key]['caption'] = $file_explode[0];
            
$files[$key]['domain'] = $file_explode[1];

            
$files[$key]['date'][$timestamp_end] = new stdClass();
            
            
$files[$key]['date'][$timestamp_end]->timestamp $timestamp_end;
            
$files[$key]['date'][$timestamp_end]->humain date('Y-m-d H:i:s'$timestamp_end);
            
            
$files[$key]['dir'] = $dir['root'];
            
$files[$key]['file'] = $file['caption'];
            
            
$k += 1;
        }   
    }
    endif;
    
    return 
$files;
}

//$files = files_reports_lst($dir);
//echo '<pre>'.print_r($files,1).'</pre>'; exit;

function files_lst_reports_by_domain($files) {
    
    
$domains = array();
    
    if(isset(
$files) && is_array($files)):
    
$k 0;
    foreach(
$files as $key => $file)
    {
        
$file_explode explode('!'$key);
        
        
$fai $file_explode[0]; // fai
        
$mydomain $file_explode[1]; // mysite
        
$timestamp_begin $file_explode[2]; // begin
        
        
$timestamp_end str_replace('.xml'''$file_explode[3]); // end
        
$timestamp_end preg_replace('/[-](.+)/si'''$timestamp_end); // end
        
        
$dom $file['domain'];
        
        
$domains[$dom]['fai'][$fai]['caption'] = $file['caption'];
        
$domains[$dom]['fai'][$fai]['domain']  = $file['domain'];

        foreach(
$file['date'] as $date) {
            
            
$domains[$dom]['fai'][$fai]['date'][$key]['date'] = $file['date'][$timestamp_end];
            
            
$domains[$dom]['fai'][$fai]['date'][$key]['file'] = $file['file'];
            
$domains[$dom]['fai'][$fai]['date'][$key]['dir'] = $file['dir'];
            
        }
        
        
$domains[$dom]['fai'][$fai]['date'] = array_reverse($domains[$dom]['fai'][$fai]['date']);
        
        
$k += 1;
    }
    endif;
    
    
//$domains[$dom]['fai'][$fai] = new stdClass();
    /*
    $domains[$dom]['fai'][$fai] = new stdClass();
    foreach ($domains[$dom]['fai'][$fai] as $key => $value)
    {
        $object->$key = $value;
    }
    
    $domains[$dom]['fai'][$fai] = $object;
    */
    
return $domains;
}

function 
stats_ip_dmarc_error($addr_ip$nbr_emails$dmarc_pass$dest$stats null) {
    
    if(
$dmarc_pass === false):
    
    
//$stats['ip'][$addr_ip]['dest'][$dest][]['count_mails_error'] = $nbr_emails;
    
    
if(isset($stats[$addr_ip]) && is_array($stats[$addr_ip]) && isset($stats[$addr_ip]['count_mails_error'])) {
        
        
$stats[$addr_ip]['count_mails_error'] = $stats[$addr_ip]['count_mails_error'] += $nbr_emails;
        
        
//if(isset($stats['ip'][$addr_ip]['dest'][$dest]['count_mails_error']) && )
        //$stats['ip'][$addr_ip]['dest'][$dest]['count_mails_error'] = $nbr_emails;
        
    
}
    else {
        
$stats[$addr_ip]['count_mails_error'] = $nbr_emails;
    }
    
    endif;
    
    return 
$stats;
}

/*
 * Generate JSON FILE
 * 
 * Toutes les (n) secondes pour le mois en cours ou une seule fois pour les mois d'avant.
 * Execution de la fonction en bas de page (ligne 1613)
 * 
 */
function stats_ip_dmarc_error_2_jsonfile($global$stats$year '2022'$month '06') {
    
    
$statistiques_json null;
    
    
$date = isset($year) && isset($month) ? $year.$month date('Ym');
    
    
$year_current_page = isset($year) ? $year date('Y');
    
$month_current_page = isset($month) ? $month date('m');
    
    
$year_default date('Y');
    
$month_default date('m');
    
    
$date $year_current_page.$month_current_page;
    
    
$day '01'$hour '00'$min '00'$sec '00';
    
    
$mktime time();
    
$mktime_current_page mktime($hour$min$sec$month_current_page$day$year_current_page);
    
$mktime_month mktime($hour$min$sec$month_default$day$year_default);
    
$mktime_current_page_month_end mktime($hour$min$sec$month_current_page+1$day$year_current_page);
    
    
$address_ips_spf constant('MY_DOMAIN_SPF_IP');
    
    
$secondes '43200'// 30min (1800) - 1h (3600) - 4h (14400) - 8h (28800) - 12h (43200) - 24h (86400)
    
    
$file constant('DIRECTORY_DMARC_STATS_JSON').'/dmarc_stats-'.constant('URL_DMARC_STATS_JSON_NAME').'-'.$date.'.json';
    
$mtime_file_current_page = @filemtime($file);
    
    
$regenerate false;
    
    if(!
file_exists($file)) {
        
        
$regenerate true;
        
//echo '1 - Generate file - Not exist<br/><br/>';
    
}
    elseif(
file_exists($file)) {
        
        if(
$mtime_file_current_page $mktime_current_page_month_end && $mtime_file_current_page $secondes $mktime)
        {
            
$regenerate true;
            
//echo '1 - Regenerate file exist : file < end & file+sec < time<br/><br/>';
        
}
        elseif(
$mtime_file_current_page $mktime_current_page_month_end && $mtime_file_current_page $secondes >= $mktime) {
            
            
$regenerate false;
            
//echo '2 - Not Regenerate file exist : file > end &  file+sec >= time <br/><br/>';
        
}
        elseif(
$mtime_file_current_page $mktime_current_page_month_end && $mtime_file_current_page $secondes >= $mktime) {
            
            
$regenerate false;
            
//echo '3 - Not Regenerate file exist : file < end & file+sec >= time <br/><br/>';
        
}
        elseif(
$mtime_file_current_page $mktime_current_page_month_end && $mtime_file_current_page $secondes $mktime) {
            
            
$regenerate true;
            
//echo '4 - Regenerate file  exist : file > end & file+sec < time <br/><br/>';
        
}
        else {
            
            
$regenerate false;
            
//echo '5 - Not Regenerate file exist<br/><br/>';
        
}
    }
    
    
//if( !file_exists($file) || (filemtime($file) + $secondes <= time()))
    
if($regenerate === true)
    {
        
    
$statistics = new stdClass();
    
    
$statistics->infos = new stdClass();
    
    
$statistics->infos->file 'dmarc_stats-'.constant('URL_DMARC_STATS_JSON_NAME').'-'.$date.'.json';
    
    
$statistics->infos->title = new stdClass();
    
$statistics->infos->title->dmarc constant('MY_DMARC_TITLE');
    
$statistics->infos->title->compagny constant('MY_DOMAIN_TITLE');
    
    
$statistics->infos->mailserver str_replace('_''.'constant('URL_DMARC_STATS_JSON_NAME'));
    
$statistics->infos->spf is_array($address_ips_spf) ? $address_ips_spf : array();
    
    
$statistics->infos->date = new stdClass();
    
//$statistics->infos->timestamp = $mktime;
    
$statistics->infos->date->year $year_current_page;
    
$statistics->infos->date->month $month_current_page;
    
    
    
$statistics->stats = new stdClass();
    
    
$statistics->stats->count = new stdClass();
    
    
$statistics->stats->count->emails = new stdClass();
    
    
$statistics->stats->count->emails->passed $global['stats']['email']['passed'];
    
$statistics->stats->count->emails->errors $global['stats']['email']['error'];
    
$statistics->stats->count->emails->sent $global['stats']['email']['total'];
    
    
$statistics->stats->count->servers_error count($stats);
    
    
$statistics->stats->servers_error = array();

    
$i=0;
    foreach(
$stats as $ip_key => $stat):
    
        
$authorized = !in_array($ip_key$address_ips_spf) ? 'unauthorized' 'error';
        
        
$command_dig_fqdn = @shell_exec('dig -x '.$ip_key.' +short @dns.google');
        
$fqdn str_replace(array("\r\n""\n""\r"), ' '$command_dig_fqdn);
        
$fqdn substr($fqdn0, -1);
        
        
$statistics->stats->servers_error[$i] = new stdClass();
        
$statistics->stats->servers_error[$i]->address_ip $ip_key;
        
$statistics->stats->servers_error[$i]->fqdn $fqdn;
        
$statistics->stats->servers_error[$i]->count_mails_error $stat['count_mails_error'];
        
$statistics->stats->servers_error[$i]->auth $authorized;
        
$i++;
    endforeach;

    
usort($statistics->stats->servers_error"count_mails_error_sort");
    
$statistics->stats->servers_error array_reverse($statistics->stats->servers_error);
    
    
$statistiques_json json_encode($statistics);
    
    
//$mtime_file_current_page = @filemtime($file);
    
    /*
    echo '<hr/>';
    $mtime_file_current_page = filemtime($file);
    
    echo ''.date('Y-m-d H:i:s', $mktime).' : DATE TIME ACTUAL<br/>';
    echo ''.date('Y-m-d H:i:s', $mktime_month).' : DATE MONTH ACTUAL<br/>';
    echo ''.date('Y-m-d H:i:s', $mktime_current_page).' : DATE CURRENT PAGE<br/>';
    echo ''.date('Y-m-d H:i:s', $mktime_current_page_month_end).' : DATE CURRENT PAGE ALL MONTH<br/>';
    echo ''.date('Y-m-d H:i:s', $mtime_file_current_page).' : DATE FILE CURRENT PAGE<br/>';
    echo '<hr/>';
    
    echo ''.$mktime.' : TIMESTAMP ACTUAL<br/>';
    echo ''.$mktime_month.' : TIMESTAMP MONTH ACTUAL<br/>';
    echo ''.$mktime_current_page.' : TIMESTAMP CURRENT PAGE<br/>';
    echo ''.$mktime_current_page_month_end.' : TIMESTAMP CURRENT PAGE ALL MONTH<br/>';
    echo ''.$mtime_file_current_page.' : TIMESTAMP FILE CURRENT PAGE<br/>';
    
    echo '<hr/>';
    */
    
        //echo "Generate file";
        
if(file_exists(constant('DIRECTORY_DMARC_REPORTS').$year_current_page.'/'.$month_current_page.'/')) 
            
file_write($file$statistiques_json);
        
    }

    return 
$statistiques_json;
    
}

function 
file_write($file$contenu){
    
    
//$contenu = serialize($contenu);
    
    
if( file_exists($file) )
        
$fp = @fopen($file"w+");
    else
        
$fp = @fopen($file"x+");
            
    @
fputs($fp"".($contenu)."");
    @
fclose($fp);
}

function 
check_number($nbr) {
    if (
preg_match("/^[0-9]/",$nbr) and preg_match("/([0-9]{1,})/"$nbr$temp)) {
        
$nbr $temp[1];
    }
    
    return 
$nbr;
}

function 
count_mails_error_sort($a,$b) {
    if (
check_number($a->count_mails_error) == check_number($b->count_mails_error)) {
        return 
0;
    }
    return (
check_number($a->count_mails_error) < check_number($b->count_mails_error) ? -1);
}

// Functions
//----------------------------------------------------------------



$directory constant('DIRECTORY_DMARC_REPORTS');

$config_year = isset($_GET['year']) && !empty($_GET['year']) ? $_GET['year'] : date('Y');
$config_month = isset($_GET['month']) && !empty($_GET['month']) ? $_GET['month'] : date('m');

$directory_current $directory.$config_year.'/'.$config_month.'/';

$dir read_all_files($directory_current);

$files files_reports_lst($dir);
$domains files_lst_reports_by_domain($files);
//echo '<pre>'.print_r($domains,1).'</pre>';

/*
$dmarc_rapport_file_outlook_zw3b = $directory_current.'protection.outlook.com!w1a.zw3b.net!1645488000!1645574400.xml';
$dmarc_rapport_outlook_zw3b = get_xml_tree($dmarc_rapport_file_outlook_zw3b);

$dmarc_rapport_file_google_lab3w = $directory_current.'google.com!lab3w.fr!1643673600!1643759999.xml';
$dmarc_rapport_file_google_zw3b = $directory_current.'google.com!zw3b.net!1643673600!1643759999.xml';
$dmarc_rapport_file_google_zw3b = $directory_current.'google.com!zw3b.net!1643932800!1644019199.xml';
//$dmarc_rapport_file = $directory_current.'aol.com!zw3b.net!1643673600!1643759999.xml';
//$dmarc_rapport_file = $directory_current.'yahoo.fr!zw3b.net!1643673600!1643759999.xml';
$dmarc_rapport_file_yahoo_zw3b = $directory_current.'yahoo.co.uk!zw3b.net!1643932800!1644019199.xml';
//$dmarc_rapport_file_yahoo_zw3b = $directory_current.'yahoo.com!zw3b.net!1643932800!1644019199.xml';


$dmarc_rapport_google_lab3w = get_xml_tree($dmarc_rapport_file_google_lab3w);

$dmarc_rapport_google_zw3b = get_xml_tree($dmarc_rapport_file_google_zw3b);
$dmarc_rapport_yahoo_zw3b = get_xml_tree($dmarc_rapport_file_yahoo_zw3b);

*/
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'."\n";
echo 
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">'."\n";
echo 
'<head>'."\n";
echo 
'<title>Emails Reports - Conformance DMARC - DKIM - SPF</title>'."\n";
echo 
'<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>'."\n";
echo 
'<meta http-equiv="cache-control" content="no-cache"/>'."\n";
echo 
'<meta http-equiv="Pragma" content="no-cache"/>'."\n";

echo 
'<style type="text/css">'."\n";
echo 
'
table {
    margin:0;
    padding:0;
    font-family:Tahoma, Arial, Helvetica, Verdana, sans-serif;
    font-weight:normal;
    font-size:12px;
    letter-spacing: 0.5px;
    color: #565656;
    border-spacing: 0;
    border-collapse: collapse;

    width: 100%;
}

table.rapport {
    border-left: 2px solid #565656;
    border-right: 2px solid #565656;
}

table.rapport tfoot {
  background-color: #EEE;
}
table.rapport tfoot tr {
  background-color: #EEE;
}
table.rapport tfoot tr td {
    height: 30px;
    border-bottom: 2px solid #565656;  
    padding: 10px 5px;
}

table.rapport thead {
    background-color: #EEE;
}
table.rapport thead tr {
    
}
table.rapport thead tr th {
    text-align: center;
    font-weight: bold;

}
table.rapport thead tr td {

}

/* */
table.rapport thead tr.label {
    height: 30px;  
    border-top: 2px solid #565656;
    border-bottom: 1px solid #CCC;  
}

table.rapport thead tr.label th {
    border-left: 1px solid #CCC;  
}
table.rapport thead tr.label th.dest {

}
table.rapport thead tr.label th.sender {

}
table.rapport thead tr.label td {
    border-left: 1px solid #CCC; 
    font-weight: normal;
    text-align: center; 
}
/* */
table.rapport thead tr.infos {
    height: 30px;  
    border-bottom: 1px solid #CCC;
}

table.rapport thead tr.infos th {
    border-left: 1px solid #CCC;  
}
table.rapport thead tr.infos td {
    border-left: 1px solid #CCC; 
    font-weight: normal;
    text-align: center; 
    color: #EEE;
}
table.rapport thead tr.infos td.dest {
    background-color: #333;
}
table.rapport thead tr.infos td.sender {
    background-color: #565656;
}
table.rapport thead tr.infos td h3 {
    margin: 0;
    padding: 0;
}
/* */

table.rapport thead tr.cols {
    height: 30px;
    border-bottom: 2px solid #565656;
    cursor: pointer;
}
table.rapport thead tr.cols th {
    border-left: 1px solid #CCC;  
}

/* */

table.rapport tbody tr.data {
    height: 30px;
    border-bottom: 2px solid #565656;  
}
table.rapport tbody tr.data td {
    border-left: 1px solid #CCC;  
    text-align: center;
}


/* */
.dmarc {

}
.spf {

}
.dkim {

}

/* menu */
a {
    color: #565656;
    text-decoration: none;
    font-weight: bold;
}
acronym {
    cursor: help;
    text-decoration: none;
    border-bottom: 1px dotted;
}
div#report-dmarc-menu {
    margin: 0;
    padding: 0;
    min-height: 30px;
}

div#report-dmarc-menu ul {
    margin: 0;
    padding: 0;
}
div#report-dmarc-menu ul li {
    margin: 0;
    padding: 0;
    min-height: 30px;
    float: left;
    display: block;
    list-style-type: none;
    margin-bottom: 5px;
    border: 1px solid #AAA;
    line-height: 18px;
}
div#report-dmarc-menu ul li a {
    padding: 5px 10px;
    display: block;
}
div#report-dmarc-menu ul li a:hover {
    background-color: #EEE;
}
div#report-dmarc-menu ul li a.active {
    background-color: #EEE;
}
/* */

ul.menu {
    margin: 0;
    padding: 0;
    clear: both;
}
ul.menu li {
    margin: 0;
    padding: 0;
    min-height: 30px;
    float: left;
    display: block;
    list-style-type: none;
    margin-bottom: 5px;

    line-height: 18px;
}
ul.menu li a {
    padding: 5px 10px;
    display: block;
    border: 1px solid #AAA;
}
ul.menu li a:hover {
    background-color: #EEE;
}
ul.menu li a.active {
    background-color: #EEE;
}

/* div table */
div.report-dmarc {
    margin-bottom: 20px;
    overflow-x: auto;
    overflow-y: hidden;
    clear: both;
}

table.rapport tbody tr.data.error {
    background-color: coral;
    background-color: orange;
    background-color: #ffd588;
}
table.rapport tbody tr:hover.data.error {
    background-color: coral;
    background-color: orange;
}
table.rapport tbody tr.data.error.ip {
    background-color: darkorange;
    background-color: orangered;
    background-color: #ff9771;
}
table.rapport tbody tr:hover.data.error.ip {
    background-color: darkorange;
    background-color: orangered;
}
table.rapport tbody tr.data.pass {
    background-color: greenyellow;
    background-color: #d0fb8f;
}
table.rapport tbody tr:hover.data.pass {
    background-color: greenyellow;
}
table.rapport tbody tr.data td span.txt {
    display: block;
    min-width: 10px;
    min-height: 10px;
    cursor: help;
}

table.rapport thead tr.infos td.sender h3 a {
    color: #FFF;
    text-decoration: none;
}
table.rapport thead tr.infos td.sender h3 a:hover {
    text-decoration: underline;
}
.hidden {
    display: none;
}

span.blur {
    cursor: pointer;
    filter: blur(0.5em);
}
span.blur:hover {
     filter: blur(0.18em);  
}
span.blur.none {
    cursor: auto;  
    filter: blur(0);
}

ul.stats {
    min-height: 30px;
    list-style-type: square;
}
ol.stats.list {
    min-height: 30px;  
    list-style-type: decimal;

}
ol.stats li {
    line-height: 20px;
}
ol.stats.list li {
    margin-left: 0px;
    padding-left: 0px;
    border-top: 1px dotted;
    border-bottom: 1px dotted;
}
ol.stats.list li.error {
    background-color: #ffd588;
}
ol.stats.list li.error.ip {
    background-color: #ff9771;
}

ul.stats code, ol.stats code {
    background-color: #565656;
    font-family: Consolas, "Andale Mono WT", "Andale Mono", "Lucida Console", Monaco, "Courier New", Courier, monospace, sans-serif;
    color: #FFF;
    padding: 0 5px;
    margin: 1px 0px;
    display: inline-block;
    font-size: 90%;
    border: 1px dashed #565656;
}

'
;

echo 
'</style>'."\n";


echo 
'<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>'."\n";
//echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" integrity="sha512-uto9mlQzrs59VwILcLiRYeLKPPbS/bT71da/OEBYEwcdNUk8jYIy+D176RYoop1Da+f9mvkYrmj5MCLZWEtQuA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>'."\n";
echo '<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.min.js" integrity="sha512-qzgd5cYSZcosqpzpn7zF2ZId8f/8CHmFKZ8j7mU4OUXTNRd5g+ZHBPsgKEwoqxCtdQvExE5LprwwPAgoicguNg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>'."\n";

echo 
'<script type="text/javascript">'."\n";
echo 
'
function op(element) {
    
    var ancre = element.getAttribute("href");
    var ws = ancre.substring(1);

    //console.log(ws);

    var tab = element.parentNode.parentNode.parentNode.parentNode.getElementsByClassName("report-dmarc");
    //console.log("tab:", tab);
    var tab_length = tab.length;
    //console.log(tab_length);

    var group = document.getElementById("report-dmarc").getElementsByClassName("report-dmarc "+ws);
    //console.log("group:", group);
    var group_length = group.length;
    //console.log(group_length);

    var nav = element.parentNode.parentNode.childNodes; // li
    //console.log("nav:", nav);
    var nav_length = nav.length;
    //console.log(nav_length);

    if(ws == "all") {

        for (var i = 0; i < tab_length; i++) {
                tab[i].classList.remove("hidden");
        }

        for (var i = 0; i < nav_length; i++) {
                nav[i].childNodes[0].classList.add("active");
        }

    }
    else {
    
        for (var i = 0; i < tab_length; i++) {
                tab[i].classList.add("hidden");
        }
        for (var i = 0; i < group_length; i++) {
                group[i].classList.remove("hidden");
        }
        for (var i = 0; i < nav_length; i++) {
                nav[i].childNodes[0].classList.remove("active");
        }

        element.classList.add("active");

    }

    document.location.hash=ws;

    return false;
}

window.addEventListener("DOMContentLoaded", function() {
  
    var elements_blur = document.getElementsByClassName("blur");
    
    for(var x = 0; x < elements_blur.length; x++) {

        elements_blur[x].addEventListener("click",function(){

          if(this.classList.contains("none"))
              this.classList.remove("none"); 
          else
              this.classList.add("none"); 
    
        },false);
    }

    

}, true);


jQuery(document).ready(function(){
    jQuery(function() {

        //jQuery("table.sortable").tablesorter();
        
        var table_sortable = document.getElementsByClassName("sortable");
    
        for(var x = 0; x < table_sortable.length; x++) {
            
            table = table_sortable[x];
            
            if(table.getAttribute("id") !== null) {
                
                table_id = "#"+table.getAttribute("id");
                
                jQuery(table_id).tablesorter({
                    sortList: [[1,1],[3,1]] 
                });
            } 
            if(table.getAttribute("id") === null)
            {
                jQuery("table.sortable").tablesorter();
            }
        }

    });


    if(window.location.hash) {
      var ancre = window.location.hash;
      ancre = ancre.substring(1);

      op_ancre_windowload(ancre);

    }
});

function op_ancre_windowload(ancre) {
    var ws = ancre;

    //console.log(ancre);
    
    var tab = document.getElementsByClassName("report-dmarc");
      //console.log("tab:", tab);
    var tab_length = tab.length;
    //console.log(tab_length);

    var group = document.getElementById("report-dmarc").getElementsByClassName("report-dmarc "+ws);
    //console.log("group:",  group);
    var group_length = group.length;
    //console.log(group_length);

    var nav = document.getElementById("report-dmarc-menu").childNodes[0].childNodes; // li
    //console.log("nav:", nav);
    var nav_length = nav.length;
    //console.log(nav_length);

    if(ws == "all") {

        for (var i = 0; i < tab_length; i++) {
                tab[i].classList.remove("hidden");
        }

        for (var i = 0; i < nav_length; i++) {
                nav[i].childNodes[0].classList.add("active");
        }

    }
    else {
    
        for (var i = 0; i < tab_length; i++) {
                tab[i].classList.add("hidden");
        }
        for (var i = 0; i < group_length; i++) {
                group[i].classList.remove("hidden");
        }
        for (var i = 0; i < nav_length; i++) {
                nav[i].childNodes[0].classList.remove("active");
        }

        document.getElementById("a_"+ancre).classList.add("active");
     
    }

    return false;

}

'
;

echo 
'</script>'."\n";

echo 
'</head>'."\n";

echo 
'<body>'."\n";

echo 
'<h1>';
echo 
''.constant('MY_DMARC_TITLE').'';
echo 
'';
echo 
''.constant('MY_DOMAIN_TITLE').'';
echo 
'</h1>';

echo 
'<p><strong>Prevent spoofing and phishing with <acronym title="Domain-based Message Authentication, Reporting and Conformance" lang="EN">DMARC</acronym></strong> (<a href="https://support.google.com/a/answer/2466580" title="About DMARC">Google Support Infos</a>)</p>';
echo 
'<p><acronym title="Domain-based Message Authentication, Reporting and Conformance" lang="EN">DMARC</acronym> <acronym title="DomainKeys Identified Mail" lang="EN">DKIM</acronym> <acronym title="Sender Policy Framework" lang="EN">SPF</acronym> compliance which allows us to know who (which domain, which IP address) is usurping our identity (our domain name) and valid messages/domains/IP address.</p>';

echo 
'<h2>Emails Reports - Conformance <acronym title="Domain-based Message Authentication, Reporting and Conformance" lang="EN">DMARC</acronym> <acronym title="DomainKeys Identified Mail" lang="EN">DKIM</acronym> <acronym title="Sender Policy Framework" lang="EN">SPF</acronym></h2>'//exit;


echo '<div id="report-dmarc">';

echo 
'<p>Mail server : <code>'.str_replace('_''.'constant('URL_DMARC_STATS_JSON_NAME')).'</code></p>';

echo 
'<ul>';
echo 
'<li>';
echo 
'<acronym title="Sender Policy Framework" lang="EN">SPF</acronym> authorized : ';

foreach(
constant('MY_DOMAIN_SPF_IP') as $k => $spf)
    echo 
'<code>'.$spf.'</code> '.(count(constant('MY_DOMAIN_SPF_IP'))-$k ' | ' '');

echo 
'</li>';
echo 
'</ul>';

echo 
'<div id="report-dmarc-date">';

echo 
'<ul class="menu years">';
$years read_all_files($directorytrue);
//echo '<pre>'.print_r($years,1).'</pre>';

if(isset($years) && is_array($years)):
foreach(
$years['dirs'] as $key_year => $year):
$get_class_year $key_year == $config_year 'active' 'default';
echo 
'<li class="year">';
echo 
'<a class="'.$get_class_year.'" href="?year='.$key_year.'">'.$key_year.'</a>';

    echo 
'<ul class="menu months">';
    
$year read_all_files($year['url']);
    
    if(isset(
$year) && is_array($year)):
    foreach(
$year['dirs'] as $key_month => $month):
    
$get_class_month $key_month == $config_month && $key_year == $config_year 'active' 'default';
    echo 
'<li class="month"><a class="'.$get_class_month.'" href="?year='.$key_year.'&month='.$key_month.'">'.$key_month.'</a></li>';
    endforeach;
    endif;
    
    echo 
'</ul>';
    
echo 
'</li>';
endforeach;
endif;

echo 
'</ul>';

echo 
'</div>';


echo 
'<div id="report-dmarc-menu">';
if(isset(
$domains) && is_array($domains) && count($domains) >= 1):
    echo 
'<ul class="menu websites">';
    echo 
'<li><a id="a_all" class="active" href="#all" onclick="op(this); return false;">All</a></li>';
    foreach(
$domains as $clef => $domain):
    echo 
'<li><a id="a_'.$clef.'" class="active" href="#'.$clef.'" onclick="op(this); return false;">'.$clef.'</a></li>';
    endforeach;
    echo 
'</ul>';
endif;
echo 
'</div>';

$emails_global_passed 0;
$emails_global_error 0;
$emails_global_total 0;

$d=0;
$f=0;
if(isset(
$domains) && is_array($domains)):
foreach(
$domains as $domain_key => $domain) {
$d += 1;
if(isset(
$domain) && is_array($domain)):
foreach(
$domain['fai'] as $fai_key => $fai) {
$f += 1;

echo 
'<div class="report-dmarc '.$domain_key.'">';

echo 
'<table class="rapport sortable" id="table_'.$d.'_'.$f.'">';

//----------------------------------
echo '<thead>';

//--------------------
echo '<tr class="label">';

//--------------
echo '<th colspan="2" class="dest" style="width:20%;">';
echo 
'Destination Report';
echo 
'</th>';
//--------------

//--------------
echo '<th colspan="2" class="sender" style="width:25%;">';
echo 
'Sender Domain';
echo 
'</th>';
//--------------

//--------------
echo '<th colspan="3" class="dmarc" style="width:15%;">';
echo 
'<acronym title="Domain-based Message Authentication, Reporting and Conformance" lang="EN">DMARC</acronym> Conformance';
echo 
'</th>';
//--------------

//--------------
echo '<th colspan="5" class="spf" style="width:20%;">';
echo 
'<acronym title="Sender Policy Framework" lang="EN">SPF</acronym>';
echo 
'</th>';
//--------------

//--------------
echo '<th colspan="5" class="dkim" style="width:20%;">';
echo 
'<acronym title="DomainKeys Identified Mail" lang="EN">DKIM</acronym>';
echo 
'</th>';
//--------------


echo '</tr>';
//--------------------

//--------------------
echo '<tr class="infos">';

//--------------
echo '<td colspan="2" class="dest">';
echo 
'<h3>'.($fai_key).'</h3>';
echo 
'</td>';
//--------------

//--------------
echo '<td colspan="2" class="sender">';
echo 
'<h3><a href="https://mxtoolbox.com/SuperTool.aspx?action=mx:'.($domain_key).'&run=toolpage" title="Check my mail server" target="_blank">'.($domain_key).'</a></h3>';
echo 
'</td>';
//--------------

//--------------
echo '<th colspan="3" class="dmarc">';
echo 
'&nbsp;';
echo 
'</th>';
//--------------

//--------------
echo '<th colspan="2" class="spf">';
echo 
'Authentification';
echo 
'</th>';
//--------------
//--------------
echo '<th colspan="2" class="spf">';
echo 
'Alignement';
echo 
'</th>';
//--------------
//--------------
echo '<th colspan="1" class="spf">';
echo 
'Policy';
echo 
'</th>';
//--------------


//--------------
echo '<th colspan="2" class="dkim">';
echo 
'Authentification';
echo 
'</th>';
//--------------
//--------------
echo '<th colspan="2" class="dkim">';
echo 
'Alignement';
echo 
'</th>';
//--------------
//--------------
echo '<th colspan="1" class="dkim">';
echo 
'Policy';
echo 
'</th>';
//--------------

echo '</tr>';
//--------------------


//--------------------
echo '<tr class="cols">';

//--------------
echo '<th>';
echo 
'Report ID';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Date';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Ip Address';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Email Volume';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Pass';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Fail';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Rate';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Pass';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Fail';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Pass';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Fail';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Pass';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Pass';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Fail';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Pass';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Fail';
echo 
'</th>';
//--------------

//--------------
echo '<th>';
echo 
'Pass';
echo 
'</th>';
//--------------

echo '</tr>';
//--------------------

echo '</thead>';
//----------------------------------

//----------------------------------
echo '<tbody>';

$emails_passed 0;
$emails_error 0;
$emails_total 0;

if(isset(
$fai['date']) && is_array($fai['date'])):
foreach(
$fai['date'] as $date_report) {

$timestamp $date_report['date']->timestamp;
    
$dmarc_rapport_file $date_report['dir'].$date_report['file'];

$dmarc_rapport_data get_xml_tree($dmarc_rapport_file);

// DMARC (Domain-based Message Authentication, Reporting and Conformance) : Resultat de tout - compl�mentaire au spf et dkim
// DKIM (DomainKeys Identified Mail) : authentification valide
// SPF (Sender Policy Framework) : exp�diteurs sont l�gitimes a pouvoir envoyer/relayer des mails

$report_metadata[$timestamp] = $dmarc_rapport_data['feedback'][0]['report_metadata'];
$policy_published[$timestamp] = $dmarc_rapport_data['feedback'][0]['policy_published'];
$record[$timestamp] = $dmarc_rapport_data['feedback'][0]['record'];

// TEMP ----
/*
// report_metadata (fai)
$report_metadata[0]['org_name'][0]['VALUE']; // google.com | Yahoo
$report_metadata[0]['email'][0]['VALUE']; // noreply-dmarc-support@google.com | dmarchelp@yahooinc.com
$report_metadata[0]['report_id'][0]['VALUE']; // 15611396437762941573 | 1643765891.57232

$report_metadata[0]['extra_contact_info'][0]; //
$report_metadata[0]['extra_contact_info'][0]['VALUE']; // https://support.google.com/a/answer/2466580

$report_metadata[0]['date_range'][0];
$report_metadata[0]['date_range'][0]['begin'][0]['VALUE']; // 1643673600
$report_metadata[0]['date_range'][0]['end'][0]['VALUE']; // 1643759999

// policy_published (config)
$policy_published[0]['domain'][0]['VALUE']; // lab3w.fr | zw3b.net
$policy_published[0]['adkim'][0]['VALUE']; // s | r (r default) (facultatif) d�finit le mode d'alignement pour DKIM afin de de d�terminer la correspondance exacte requise entre les informations du message et les signature DKIM - strict : le nom de domaine de l'expediteur doit correspondre exactement au d=name associ� dans les en-t�tes de messages DKIM de (from) - relaxed : autorise les correspondances partielles - Tous les sous-domaines valide de d=name est accept�
$policy_published[0]['aspf'][0]['VALUE']; //  s | r (r default) (facultatif) d�finit le mode d'alignement de SPF - strict : Les en-t�tes From: doit correspondre exactement au domaine domain.name - relaxed : Tous les sous-domaines valide de domain.name est accept�
$policy_published[0]['p'][0]['VALUE']; // none | quarantine | reject (obligatoire) definit la maniere dont le domaine principal traite les message suspect
$policy_published[0]['sp'][0]['VALUE']; //  none | quarantine | reject (facultatif) regle relative aux sous-domaine du domaine
$policy_published[0]['pct'][0]['VALUE']; // 5 (100 default) (facultatif) 1<>100 pourcentage de messages suspects auquel la regle DMARC s'applique - les messages suspects sont des messages non valid�s par les controle DMARC

// record -> row
$record[0]['row'][0];
$record[0]['row'][0]['source_ip'][0]['VALUE']; // 158.69.126.137
$record[0]['row'][0]['count'][0]['VALUE']; // nombre (ex: 2)

$record[0]['row'][0]['policy_evaluated'][0];
$record[0]['row'][0]['policy_evaluated'][0]['disposition'][0]['VALUE']; // none
$record[0]['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']; // pass|fail
$record[0]['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']; // pass|fail

// identifiers - domaine valide ou pas
$record[0]['identifiers'][0]['header_from'][0];
$record[0]['identifiers'][0]['header_from'][0]['VALUE']; // lab3w.fr | zw3b.net | w1a.zw3b.net

// auth_results == DKIM && SPF
$record[0]['auth_results'][0]['dkim'][0];
$record[0]['auth_results'][0]['dkim'][0]['domain'][0]['VALUE']; // lab3w.fr | w1a.zw3b.net
$record[0]['auth_results'][0]['dkim'][0]['result'][0]['VALUE']; // pass|fail
$record[0]['auth_results'][0]['dkim'][0]['selector'][0]['VALUE']; // KEY DKIM IN DNS

$record[0]['auth_results'][0]['spf'][0];
$record[0]['auth_results'][0]['spf'][0]['domain'][0]['VALUE']; // lab3w.fr | w1a.zw3b.net
$record[0]['auth_results'][0]['spf'][0]['result'][0]['VALUE']; // pass|fail
*/

// SPF Authentification
// SPF Alignement
// SPF Policy

// DKIM Authentification
// DKIM Alignement
// DKIM Policy

// DMARC Resulat

//$address_ips_spf = array('158.69.126.137', '2607:5300:60:9389:17:4:0:1');
$address_ips_spf constant('MY_DOMAIN_SPF_IP');

if(isset(
$record[$timestamp]) && is_array($record[$timestamp])):
foreach(
$record[$timestamp] as $row) {

$get_class = (isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE'] == 'pass' && isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE'] == 'pass''pass' null);
$get_class = ((isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE'] == 'fail') || (isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE'] == 'fail') || (!isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) || !isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) ) ? 'error' $get_class);
$get_class = (isset($row['row'][0]['source_ip'][0]['VALUE']) && !in_array($row['row'][0]['source_ip'][0]['VALUE'], $address_ips_spf) ? 'error ip' $get_class);

//--------------------
echo '<tr class="data '.$get_class.'">';

// ID report --------------
echo '<td>';
//echo ''.$report_metadata[$timestamp][0]['report_id'][0]['VALUE'].'';
echo ''.(strlen($report_metadata[$timestamp][0]['report_id'][0]['VALUE']) <= 22 $report_metadata[$timestamp][0]['report_id'][0]['VALUE'] : substr($report_metadata[$timestamp][0]['report_id'][0]['VALUE'], 011).'(...)'.substr($report_metadata[$timestamp][0]['report_id'][0]['VALUE'], -10)).'';
echo 
'</td>';
//--------------

// Date report--------------
echo '<td>';
echo 
''.$date_report['date']->humain.'';
echo 
'</td>';
//--------------

// IP Address--------------
$title_identifier 'Identifier'."\r\r";
$title_identifier.= ''.(isset($row['identifiers'][0]['envelope_to'][0]['VALUE']) ? 'envelope_to : '.$row['identifiers'][0]['envelope_to'][0]['VALUE']."\r" null);
$title_identifier.= ''.(isset($row['identifiers'][0]['envelope_from'][0]['VALUE']) ? 'envelope_from : '.$row['identifiers'][0]['envelope_from'][0]['VALUE']."\r" null);
$title_identifier.= ''.(isset($row['identifiers'][0]['header_from'][0]['VALUE']) ? 'header_from : '.$row['identifiers'][0]['header_from'][0]['VALUE']."\r" null);

echo 
'<td title="'.$title_identifier.'" style="cursor: help;">';
echo 
'<span class="txt">'.$row['row'][0]['source_ip'][0]['VALUE'].'</span>';
echo 
'</td>';
//--------------

// Email Volume --------------
echo '<td>';
echo 
''.number_format($row['row'][0]['count'][0]['VALUE']).'';
echo 
'</td>';
//--------------

// DMARC PASS --------------
//echo '<pre>'.print_r($policy_published[$timestamp],1).'<pre>';

$title_pp 'DMARC Policy published'."\r\r";
$title_pp.= ''.(isset($policy_published[$timestamp][0]['domain'][0]['VALUE']) ? 'd='.$policy_published[$timestamp][0]['domain'][0]['VALUE'] : 'd=')."\r";
$title_pp.= ''.(isset($policy_published[$timestamp][0]['p'][0]['VALUE']) ? 'p='.$policy_published[$timestamp][0]['p'][0]['VALUE'] : 'p=')."\r";
$title_pp.= ''.(isset($policy_published[$timestamp][0]['sp'][0]['VALUE']) ? (isset($policy_published[$timestamp][0]['sp'][0]['VALUE']) ? 'sp='.$policy_published[$timestamp][0]['sp'][0]['VALUE'] : 'sp='.$policy_published[$timestamp][0]['p'][0]['VALUE'])."\r" null);
$title_pp.= ''.(isset($policy_published[$timestamp][0]['pct'][0]['VALUE']) ? (isset($policy_published[$timestamp][0]['pct'][0]['VALUE']) ? 'pct='.$policy_published[$timestamp][0]['pct'][0]['VALUE'] : 'pct=100')."\r" null);
$title_pp.= ''.(isset($policy_published[$timestamp][0]['aspf'][0]['VALUE']) ? (isset($policy_published[$timestamp][0]['aspf'][0]['VALUE']) ? 'aspf='.$policy_published[$timestamp][0]['aspf'][0]['VALUE'] : 'aspf=r')."\r" null);
$title_pp.= ''.(isset($policy_published[$timestamp][0]['adkim'][0]['VALUE']) ? (isset($policy_published[$timestamp][0]['adkim'][0]['VALUE']) ? 'adkim='.$policy_published[$timestamp][0]['adkim'][0]['VALUE'] : 'adkim=r')."\r" null);
$title_pp.= ''.(isset($policy_published[$timestamp][0]['fo'][0]['VALUE']) ? (isset($policy_published[$timestamp][0]['fo'][0]['VALUE']) ? 'fo='.$policy_published[$timestamp][0]['fo'][0]['VALUE'] : 'fo=0')."\r" null);
$title_pp.= ''.(isset($policy_published[$timestamp][0]['ri'][0]['VALUE']) ? (isset($policy_published[$timestamp][0]['ri'][0]['VALUE']) ? 'ri='.$policy_published[$timestamp][0]['ri'][0]['VALUE'] : '')."\r" null);
$title_pp.= ''.(isset($policy_published[$timestamp][0]['rf'][0]['VALUE']) ? (isset($policy_published[$timestamp][0]['rf'][0]['VALUE']) ? 'rf='.$policy_published[$timestamp][0]['rf'][0]['VALUE'] : 'rf=afrf')."\r" null);

echo 
'<td title="'.$title_pp.'" style="cursor: help;">';
echo 
''.(isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE'] == 'pass' && isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE'] == 'pass' '1' '0').'';
echo 
'</td>';
//--------------

// DMARC FAIL --------------
echo '<td title="'.$title_pp.'"  style="cursor: help;">';
echo 
''.((isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE'] == 'fail') || (isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE'] == 'fail') || (!isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) || !isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) ) ? '1' '0').'';
echo 
'</td>';
//--------------

// DMARC RATE --------------
echo '<td title="'.$title_pp.'"  style="cursor: help;">';

// Par exemple sur un domain qui est authentifi� sur un SPF (mais qui n'est pas le mien) - l'alignement DMARC return fail - donc 0% - 
// Pour l'alignement SPF DMARC donc conforme return pass sur authentification et sur la policy - donc 50 dirais-je.
// La m�me chose sur DKIM - DKIM DMARC

$rate_spf = isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE'] == 'pass' '50' '0';
$rate_dkim = isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE'] == 'pass' '50' '0';

$pourcentage $rate_spf $rate_dkim;

echo 
''.$pourcentage.'%';
echo 
'</td>';
//--------------

//echo '<pre>'.print_r($row['auth_results'][0],1).'<pre>';

$title_spf 'SPF (Sender Policy Framework)'."\r\r";
$title_spf.= ''.(isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) ? 'auth_results : '.$row['auth_results'][0]['spf'][0]['result'][0]['VALUE'] : '')."\r";
$title_spf.= ''.(isset($row['auth_results'][0]['spf'][0]['domain'][0]['VALUE']) ? 'domain : '.$row['auth_results'][0]['spf'][0]['domain'][0]['VALUE'] : '')."\r";
$title_spf.= ''.(isset($row['auth_results'][0]['spf'][0]['scope'][0]['VALUE']) ? 'scope : '.$row['auth_results'][0]['spf'][0]['scope'][0]['VALUE'] : '')."\r";
$title_spf.= ''.(isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) ? 'policy_evaluated : '.$row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']."\r" '');

// SPF AUTH PASS --------------
echo '<td title="'.$title_spf.'" style="cursor: help;">';
$spf_auth_pass = isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['spf'][0]['result'][0]['VALUE'] == 'pass' '1' : (!isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) ? 'null' '0');
echo 
''.$spf_auth_pass.'';
echo 
'</td>';
//--------------

// SPF AUTH FAIL --------------
echo '<td title="'.$title_spf.'" style="cursor: help;">';
$spf_auth_fail = isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['spf'][0]['result'][0]['VALUE'] == 'fail' '1' : (isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['spf'][0]['result'][0]['VALUE'] == 'pass' '0' : (!isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) ? 'null' '1'));
echo 
''.$spf_auth_fail.'';
echo 
'</td>';
//--------------

// SPF ALIGNEMENT PASS --------------
echo '<td title="'.$title_spf.'" style="cursor: help;">';
$spf_alignement_pass = isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['spf'][0]['result'][0]['VALUE'] == 'pass' && isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE'] == 'pass' '1' : (!isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) || !isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) ? 'null' '0');
echo 
''.$spf_alignement_pass.'';
echo 
'</td>';
//--------------

// SPF ALIGNEMENT FAIL --------------
echo '<td title="'.$title_spf.'" style="cursor: help;">';
$spf_alignement_fail = isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['spf'][0]['result'][0]['VALUE'] == 'fail' '1' : (isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['spf'][0]['result'][0]['VALUE'] == 'pass' && isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE'] == 'pass' '0' : (!isset($row['auth_results'][0]['spf'][0]['result'][0]['VALUE']) || !isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) ? 'null' '1'));
echo 
''.$spf_alignement_fail.'';
echo 
'</td>';
//--------------

// SPF POLICY PASS--------------
echo '<td title="'.$title_spf.'" style="cursor: help;">';
$spf_policy = isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE'] == 'pass' '1' : (!isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) ? 'null' '0');
echo 
''.$spf_policy.'';
echo 
'</td>';
//--------------

$title_dkim '';
$text_style '';
if(isset(
$row['auth_results'][0]['dkim'][0]['selector'][0]['VALUE']) && isset($row['auth_results'][0]['dkim'][0]['selector'][0]['VALUE']) && isset($row['auth_results'][0]['dkim'][0]['selector'][0]['VALUE']))
{
$text_style 'style="cursor: help;"';
    
$title_dkim 'DKIM (Domain Key Identified Mail)'."\r\r";
$title_dkim.= ''.(isset($row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']) ? 'auth_results : '.$row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']."\r" '');
$title_dkim.= ''.(isset($row['auth_results'][0]['dkim'][0]['domain'][0]['VALUE']) ? 'domain : '.$row['auth_results'][0]['dkim'][0]['domain'][0]['VALUE']."\r"'');
//$title_dkim.= ''.(isset($row['auth_results'][0]['dkim'][0]['selector'][0]['VALUE']) ? 'selector : '.$row['auth_results'][0]['dkim'][0]['selector'][0]['VALUE']."\r" : ''); // on pourait r�cup�rer la clef priv� avec ÃƒÂ§ÃƒÂ  !!
$title_dkim.= ''.(isset($row['auth_results'][0]['dkim'][0]['selector'][0]['VALUE']) ? 'selector : '.''.(strlen($row['auth_results'][0]['dkim'][0]['selector'][0]['VALUE']) <= 20 $row['auth_results'][0]['dkim'][0]['selector'][0]['VALUE'] : substr($row['auth_results'][0]['dkim'][0]['selector'][0]['VALUE'], 08).'(...)'.substr($row['auth_results'][0]['dkim'][0]['selector'][0]['VALUE'], -8))."\r" ''); // on pourait r�cup�rer la clef priv� avec ÃƒÂ§ÃƒÂ  !!
$title_dkim.= ''.(isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) ? 'policy_evaluated : '.$row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']."\r" '');
}
// DKIM AUTH PASS --------------
echo '<td title="'.$title_dkim.'" '.$text_style.'>';
$dkim_auth_pass = isset($row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['dkim'][0]['result'][0]['VALUE'] == 'pass' '1' : (isset($row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['dkim'][0]['result'][0]['VALUE'] == 'fail' '0' 'null');
echo 
''.$dkim_auth_pass.'';
echo 
'</td>';
//--------------

// DKIM AUTH FAIL --------------
echo '<td title="'.$title_dkim.'" '.$text_style.'>';
$dkim_auth_fail = isset($row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['dkim'][0]['result'][0]['VALUE'] == 'fail' '1' : (isset($row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['dkim'][0]['result'][0]['VALUE'] == 'pass' '0' 'null');
echo 
''.$dkim_auth_fail.'';
echo 
'</td>';
//--------------

// DKIM ALIGNEMENT PASS --------------
echo '<td title="'.$title_dkim.'" '.$text_style.'>';
$dkim_alignement_pass = isset($row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['dkim'][0]['result'][0]['VALUE'] == 'pass' && isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE'] == 'pass' '1' : (!isset($row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']) || !isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) ? 'null' '0');
echo 
''.$dkim_alignement_pass.'';
echo 
'</td>';
//--------------

// DKIM ALIGNEMENT FAIL --------------
echo '<td title="'.$title_dkim.'" '.$text_style.'>';
$dkim_alignement_fail = isset($row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['dkim'][0]['result'][0]['VALUE'] == 'fail' '1' : (isset($row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']) && $row['auth_results'][0]['dkim'][0]['result'][0]['VALUE'] == 'pass' && isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE'] == 'pass' '0' : (!isset($row['auth_results'][0]['dkim'][0]['result'][0]['VALUE']) || !isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) ? 'null' '0'));
echo 
''.$dkim_alignement_fail.'';
echo 
'</td>';
//--------------

// DKIM POLICY PASS --------------
echo '<td title="'.$title_dkim.'" '.$text_style.'>';
$dkim_policy = isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE'] == 'pass' '1' : (!isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) ? 'null' '0');
echo 
''.$dkim_policy.'';
echo 
'</td>';
//--------------

echo '</tr>';
//--------------------

//---------------------------------------------

$dmarc_pass = isset($row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['spf'][0]['VALUE'] == 'pass' && isset($row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE']) && $row['row'][0]['policy_evaluated'][0]['dkim'][0]['VALUE'] == 'pass' true false;

// Statistiques par destinataire --------------
$temp['stats']['email']['passed'] = $dmarc_pass === true ? ($emails_passed += $row['row'][0]['count'][0]['VALUE'])  : $emails_passed;
$temp['stats']['email']['error'] = $dmarc_pass === false ? ($emails_error += $row['row'][0]['count'][0]['VALUE'])  : $emails_error;
$temp['stats']['email']['total'] = $emails_total += $row['row'][0]['count'][0]['VALUE'];
// Statistiques par destinataire --------------

// Statistiques Global des serveurs in error --------------
$ip_rows $row['row'][0]['source_ip'][0]['VALUE'];
$nbr_email $row['row'][0]['count'][0]['VALUE'];
//$stats[$addr_ip]['count_mails_error']
$stats_ip = isset($stats_ip) && is_array($stats_ip) ? stats_ip_dmarc_error($addr_ip $ip_rows$nbr_email $nbr_email$dmarc_pass$dest $fai_key$stats_ip) : array($ip_rows => array('count_mails_error' => $nbr_email));
// Statistiques Global des serveurs in error --------------

//---------------------------------------------

// rows
endif; // rows
// date report
endif; // date report

echo '</tbody>';
//----------------------------------

// Statistiques par destinataire --------------
echo '<tfoot>';

echo 
'<tr class="stats">';
echo 
'<td colspan="17">';
echo 
'<h3>Recipient mail server statistics '.$fai_key.' for the domain '.$domain_key.'</h3>';
echo 
'<ul>';
echo 
'<li>Emails past : '.number_format($temp['stats']['email']['passed']).'</li>';
echo 
'<li>Emails errors : '.number_format($temp['stats']['email']['error']).'</li>';
echo 
'<li>Total emails sent : '.number_format($temp['stats']['email']['total']).'</li>';
echo 
'</ul>';
echo 
'</td>';
echo 
'</tr>';

echo 
'</tfoot>';
// Statistiques par destinataire --------------

echo '</table>';

echo 
'</div>'// class dmarc

// Statistiques global --------------
$global['stats']['email']['passed'] = $emails_global_passed += $temp['stats']['email']['passed'];
$global['stats']['email']['error'] = $emails_global_error += $temp['stats']['email']['error'];
$global['stats']['email']['total'] = $emails_global_total += $temp['stats']['email']['total'];
// Statistiques global --------------

// fai
endif; // fai
// domain
endif; // domain

echo '</div>'// id dmarc

//echo '<hr style="clear:both;"/>';


if(isset($global) && is_array($global['stats']) && is_array($global['stats']['email'])) {
// Statistiques global --------------
echo '<h3>Global statistics of the month (<a href="'.constant('URL_DMARC_STATS_JSON').'dmarc_stats-'.constant('URL_DMARC_STATS_JSON_NAME').'-'.$config_year.$config_month.'.json"><acronym title="JavaScript Object Notation" lang="EN">JSON</acronym> file</a>)</h3>';
/*
echo '<ul class="stats">';
echo '<li>Emails past : '.number_format($global['stats']['email']['passed']).'</li>';
echo '<li>Emails errors : '.number_format($global['stats']['email']['error']).'</li>';
echo '<li>Total emails sent : '.number_format($global['stats']['email']['total']).'</li>';
echo '</ul>';
*/
}
//echo '<hr style="clear:both;"/>';

//-------
/*
@arsort($stats_ip);
$count_mails_error = 0;
if(isset($stats_ip) && is_array($stats_ip)) {

foreach($stats_ip as $ip): $count_mails_error += $ip['count_mails_error']; endforeach;

echo '<ul class="stats">';
echo '<li>';
echo 'Number of email sender servers in error : '.count($stats_ip).'<br /><br />';

echo '<ol class="stats list">';
foreach($stats_ip as $ip_key => $ip) {
    
    $get_class = !in_array($ip_key, $address_ips_spf) ? 'error ip' : 'error';
    
    echo '<li class="'.$get_class.'">Address IP sender : <code>'.$ip_key.'</code> (<strong>'.number_format($ip['count_mails_error']).'</strong> email'.($ip['count_mails_error'] <= 1 ? '' : 's').' sent '.($get_class == 'error ip' ? 'unauthorized' : 'with error').')</li>';
}
echo '</ol>';

echo '<br /></li>';

echo '<li>Total emails errors : '.number_format($count_mails_error).'</li>';

echo '</ul>';
}
*/

//--------------------------------------------------------------------

#$year = isset($_GET['year']) ? $_GET['year'] : date('Y');
#$month = isset($_GET['month']) ? $_GET['month'] : date('m');

// Generate Json file
if(isset($global)  && is_array($global) && isset($stats_ip) && is_array($stats_ip))
    
$generate_json_statistics stats_ip_dmarc_error_2_jsonfile($global$stats_ip$config_year$config_month);
    
//echo '<pre>JSON : '.print_r($generate_json_statistics,1).'</pre>';
    
//--------------------------------------------------------------------
    
$json_file file_get_contents(constant('DIRECTORY_DMARC_STATS_JSON').'dmarc_stats-'.constant('URL_DMARC_STATS_JSON_NAME').'-'.$config_year.$config_month.'.json');
$json_data json_decode($json_file);

$count_mails_error 0;
if(isset(
$json_data->stats->servers_error) && is_array($json_data->stats->servers_error)) {
    
    foreach(
$json_data->stats->servers_error as $server_error): $count_mails_error += $server_error->count_mails_error; endforeach;

    
//echo '<ul class="stats">';
    
    
$list '<ol class="stats list">';
    
    
$count_my_spf 0;
    
$count_my_error_mail 0;
    
$count_spoofers_error_mail 0;
    foreach(
$json_data->stats->servers_error as $key => $server_error) {
        
        
$req_if_hide_my_spf constant('HIDE_MY_SPF_LINE_STATS') === true ? !in_array($server_error->address_ip$json_data->infos->spf) : true;
        
        
$get_class = !in_array($server_error->address_ip$address_ips_spf) ? 'error ip' 'error';
        
        
$count_my_spf += constant('HIDE_MY_SPF_LINE_STATS') === true && in_array($server_error->address_ip$json_data->infos->spf) ? 0;
        
$count_my_error_mail += in_array($server_error->address_ip$json_data->infos->spf) ? (constant('HIDE_MY_SPF_LINE_STATS') === true $server_error->count_mails_error 0) : 0;
        
$count_spoofers_error_mail += !in_array($server_error->address_ip$json_data->infos->spf) ? $server_error->count_mails_error 0;
        
        if(
$req_if_hide_my_spf)
        
$list.= '<li class="'.$get_class.'">Address IP sender : <a href="https://dnslytics.com/'.(preg_match('/(:)/'$server_error->address_ip$m) ? 'ipv6' 'ip').'/'.$server_error->address_ip.'" title="Check this address ip" " target="_blank"><code>'.$server_error->address_ip.'</code></a> <a href="https://mxtoolbox.com/SuperTool.aspx?action=mx:'.($server_error->fqdn).'&run=toolpage" title="Check this mail server" target="_blank"><code>'.$server_error->fqdn.'</code></a> (<strong>'.number_format($server_error->count_mails_error).'</strong> sent '.($get_class == 'error ip' 'unauthorized' 'with error').')</li>';
        
    }
    
    
$list.= '</ol>';
    
    
    echo 
'<ul class="stats">';
    echo 
'<li>Emails sent : '.number_format($json_data->stats->count->emails->sent).'</li>';
    echo 
'<li>Emails past : '.number_format($json_data->stats->count->emails->passed).'</li>';
    echo 
'<li>Emails errors : '.number_format($json_data->stats->count->emails->errors $count_spoofers_error_mail).'</li>';
    echo 
'</ul>';
    
    echo 
'<h4>DMARC statistics on spoofing servers</h4>';
    
    echo 
$list;
    
    echo 
'<ul class="stats">';
    echo 
'<li>Mail sender servers '.(constant('HIDE_MY_SPF_LINE_STATS') === true 'unauthorized' 'error').' : '.number_format(count($json_data->stats->servers_error) - $count_my_spf).'</li>'."\n";
    echo 
'<li>Emails unauthorized : '.number_format($count_spoofers_error_mail).'</li>'."\n";
    echo 
'</ul>';
}
echo 
'<hr style="clear:both;"/>';
// Statistiques global --------------

// Analytics global spoofers --------------
echo '<h3><a href="/dmarc-reports.php"><acronym title="Domain-based Message Authentication, Reporting and Conformance" lang="EN">DMARC</acronym> Reports HTML visualisation</a> <span style="font-size: 80%;">(<a href="/dmarc-reports.phps">PHPSource</a>)</span>.</h3>';
echo 
'<h3><a href="/dmarc-reports-analytics.php">Global analysis of mail servers of spoofers from <acronym title="Domain-based Message Authentication, Reporting and Conformance" lang="EN">DMARC</acronym> reports with <acronym title="REpresentational State Transfer" lang="EN">REST</acronym>ful Server <acronym title="Application Programming Interface" lang="EN">API</acronym></a> <span style="font-size: 80%;">(<a href="/dmarc-reports-analytics.phps">PHPSource</a>)</span>.</h3>';
echo 
'<h3><a href="/dmarc-reports-analytics-rest.php">Global analysis of mail servers of spoofers from <acronym title="Domain-based Message Authentication, Reporting and Conformance" lang="EN">DMARC</acronym> reports on <acronym title="REpresentational State Transfer" lang="EN">REST</acronym>ful Client <acronym title="Application Programming Interface" lang="EN">API</acronym></a> <span style="font-size: 80%;">(<a href="/dmarc-reports-analytics-rest.phps">PHPSource</a>)</span>.</h3>';

echo 
'<hr style="clear:both;"/>';
// Analytics global spoofers --------------

echo '<p>';
echo 
'<strong><i>And above all, could a competent authority verify the IP addresses of usurpers ? Should I add <span class="blur">"and sanction them"</span> or am I to do it ? Thanking you !</i></strong>';
echo 
'</p>';



/*
$dmarc_zw3b = 'Output file yahoo zw3b.net<pre>'.print_r($dmarc_rapport_yahoo_zw3b,1).'</pre>';
echo $dmarc_zw3b;

$dmarc_zw3b = 'Output file google zw3b.net<pre>'.print_r($dmarc_rapport_google_zw3b,1).'</pre>';
echo $dmarc_zw3b;

$dmarc_lab3w = 'Output file google lab3w.fr<pre>'.print_r($dmarc_rapport_google_lab3w,1).'</pre>';
echo $dmarc_lab3w;
*/

//$dmarc_zw3b = 'Output file outlook w1a.zw3b.fr<pre>'.print_r($dmarc_rapport_outlook_zw3b,1).'</pre>';
//echo $dmarc_zw3b;

//--------------------------------------------------------------------

$html '<div id="zw-footer">'."\n";
$html.= '<p class="copyright"><span><a href="https://www.zw3b.site">&copy; 2018-'.date('Y').' ZW3B :-: The Web Site</a>';
$html.= '<br /><br />';
$html.= '<a href="http://www.lab3w.fr">&copy; 2003-'.date('Y').' LAB3W O.Romain.Jaillet-ramey : Web and networks laboratory - InterNet engineering</a> - All rights reserved</a></span>';
$html.= '</p>';

$html.= '<p class="author"><a href="https://www.zw3b.site/dmarc-rapport.php" title="DMARC REPORTS">DMARC REPORTS : ZW3B</a> &copy; LAB3W.<acronym title="O.Romain.Jaillet-ramey" lang="FR">ORJ</acronym> 2023/01/13</p>'."\n";

$html.= '</div>';

echo 
$html;
//--------------------------------------------------------------------


echo '</body>'."\n";

echo 
'</html>'."\n";

?>