%PDF- %PDF-
| Direktori : /www/varak.net/dmarc.varak.net/classes/ |
| Current File : //www/varak.net/dmarc.varak.net/classes/Statistics.php |
<?php
/**
* dmarc-srg - A php parser, viewer and summary report generator for incoming DMARC reports.
* Copyright (C) 2020-2024 Aleksey Andreev (liuch)
*
* Available at:
* https://github.com/liuch/dmarc-srg
*
* 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 3 of the License.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* =========================
*
* This file contains the class Statistics
*
* @category API
* @package DmarcSrg
* @author Aleksey Andreev (liuch)
* @license https://www.gnu.org/licenses/gpl-3.0.html GNU/GPLv3
*/
namespace Liuch\DmarcSrg;
use Liuch\DmarcSrg\DateTime;
/**
* This class is designed to get statistics on DMARC reports of a specified period
*/
class Statistics
{
/** @var Database\DatabaseController*/
private $db = null;
/** @var Domains\Domain|null */
private $domain = null;
/** @var Users\User|null */
private $user = null;
/** @var array<string,DateTime|null> */
private $range = [
'date1' => null,
'date2' => null
];
private $filter = [];
/**
* The constructor of the class, it only uses in static methods of this class
*
* @param Domains\Domain|null $domain The domain for which you need to get statistics,
* null for all the domains.
* @param Database\DatabaseController|null $db The database controller
*
* @return void
*/
private function __construct($domain, $db)
{
$this->domain = $domain;
$this->db = $db ?? Core::instance()->database();
}
/**
* Returns an instance of the class for the period from $date1 to $date2
*
* @param Domains\Domain|null $domain See the constructor for the details
* @param DateTime $date1 The date you need statistics from
* @param DateTime $date2 The date you need statistics to (not included)
* @param Database\DatabaseController $db The database controller
*
* @return Statistics Instance of the class
*/
public static function fromTo($domain, $date1, $date2, $db = null)
{
$r = new Statistics($domain, $db);
$r->range['date1'] = $date1;
$r->range['date2'] = $date2;
return $r;
}
/**
* Returns an instance of the class for the last week
*
* @param Domains\Domain|null $domain See the constructor for the details
* @param int $offset Offset to the past (weeks)
* @param Database\DatabaseController $db The database controller
*
* @return Statistics Instance of the class
*/
public static function lastWeek($domain, int $offset = 0, $db = null)
{
$r = new Statistics($domain, $db);
$r->range['date1'] = new DateTime('monday last week');
if ($offset > 0) {
$r->range['date1']->sub(new \DateInterval("P{$offset}W"));
}
$r->range['date2'] = (clone $r->range['date1'])->add(new \DateInterval('P1W'));
return $r;
}
/**
* Returns an instance of the class for the last month
*
* @param Domains\Domain|null $domain See the construct for the details
* @param int $offset Offset to the past (months)
* @param Database\DatabaseController $db The database controller
*
* @return Statistics Instance of the class
*/
public static function lastMonth($domain, int $offset = 0, $db = null)
{
$r = new Statistics($domain, $db);
$r->range['date1'] = new DateTime('midnight first day of last month');
if ($offset > 0) {
$r->range['date1']->sub(new \DateInterval("P{$offset}M"));
}
$r->range['date2'] = (clone $r->range['date1'])->add(new \DateInterval('P1M'));
return $r;
}
/**
* Returns an instance of the class for the last N days
*
* @param Domains\Domain|null $domain See the construct for the details
* @param int $ndays Number of days
* @param int $offset Offset to the past (days)
* @param Database\DatabaseController $db The database controller
*
* @return Statistics Instance of the class
*/
public static function lastNDays($domain, int $ndays, int $offset = 0, $db = null)
{
$r = new Statistics($domain, $db);
$r->range['date2'] = new DateTime('midnight');
if ($offset > 0) {
$r->range['date2']->sub(new \DateInterval("P{$offset}D"));
}
$r->range['date1'] = (clone $r->range['date2'])->sub(new \DateInterval("P{$ndays}D"));
return $r;
}
/**
* Sets the user for whom statistics are generated
*
* @param Users\User $user User to generate statistics
*
* @return self
*/
public function setUser($user)
{
$this->user = $user;
return $this;
}
/**
* Returns the date from and the date to in an array
*
* @return DateTime[] - The range of the statistics
*/
public function range(): array
{
return [ (clone $this->range['date1']), (clone $this->range['date2'])->sub(new \DateInterval('PT1S')) ];
}
/**
* Returns summary information for e-mail messages as an array
*
* @return array Array with summary information
*/
public function summary(): array
{
return $this->db->getMapper('statistics')->summary(
$this->domain,
$this->range,
$this->filter,
$this->user ? $this->user->id() : 0
);
}
/**
* Returns a list of ip-addresses from which the e-mail messages were received, with some statistics for each one
*
* @return array A list of ip-addresses with fields
* `ip`, `emails`, `dkim_aligned`, `spf_aligned`
*/
public function ips(): array
{
return $this->db->getMapper('statistics')->ips(
$this->domain,
$this->range,
$this->filter,
$this->user ? $this->user->id() : 0
);
}
/**
* Returns a list of organizations that sent the reports with some statistics for each one
*
* @return array List of organizations with fields `name`, `reports`, `emails`
*/
public function organizations(): array
{
return $this->db->getMapper('statistics')->organizations(
$this->domain,
$this->range,
$this->filter,
$this->user ? $this->user->id() : 0
);
}
/**
* Sets filter values for the returning information
*
* @param array $filter Key-value array with filtering parameters:
* 'dkim' => string, 'fail' or 'pass'
* 'organization' => string
* 'spf' => string, 'fail' or 'pass'
* 'status' => string, 'read' or 'unread'
*
* @return void
*/
public function setFilter(array $filter): void
{
$this->filter = $filter;
}
}