182 lines
5.3 KiB
PHP
182 lines
5.3 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use AgliPanci\LaravelCase\Facades\CaseBuilder;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
use App\Casts\CompressedStringOrNull;
|
|
use App\Traits\{QueryCacheableConfig,ScopeActive};
|
|
|
|
class Domain extends Model
|
|
{
|
|
use HasFactory,QueryCacheableConfig,ScopeActive;
|
|
|
|
private const CACHE_TIME = 3600;
|
|
private const STATS_MONTHS = 6;
|
|
|
|
protected $casts = [
|
|
'homepage' => CompressedStringOrNull::class,
|
|
];
|
|
|
|
/* SCOPES */
|
|
|
|
/**
|
|
* Only query active records
|
|
*/
|
|
public function scopePublic($query)
|
|
{
|
|
$user = Auth::user();
|
|
|
|
return $query
|
|
->when(((! $user) || (! $user->isAdmin())),function($query) { return $query->where('public',TRUE)->active(); });
|
|
}
|
|
|
|
/* RELATIONS */
|
|
|
|
public function echoareas()
|
|
{
|
|
return $this->hasMany(Echoarea::class);
|
|
}
|
|
|
|
public function fileareas()
|
|
{
|
|
return $this->hasMany(Filearea::class);
|
|
}
|
|
|
|
public function nodelist_filearea()
|
|
{
|
|
return $this->belongsTo(Filearea::class);
|
|
}
|
|
|
|
public function nodestatusarea()
|
|
{
|
|
return $this->belongsTo(Echoarea::class,'nodestatus_id');
|
|
}
|
|
|
|
public function zones()
|
|
{
|
|
return $this->hasMany(Zone::class)
|
|
->select(['id','zone_id','domain_id','active']);
|
|
}
|
|
|
|
/* ATTRIBUTES */
|
|
|
|
public function getCanAcceptAppAttribute(): bool
|
|
{
|
|
return ($x=our_address($this))
|
|
&& $x->count()
|
|
&& $this->active
|
|
&& $this->accept_app
|
|
&& Auth::id()
|
|
&& $this->userHasSystemsNotInNet(Auth::user())->count();
|
|
}
|
|
|
|
public function getHomePageAttribute(?string $value): string
|
|
{
|
|
//0xFD2FB528
|
|
return $this->castAttribute('homepage',$value) ?: 'No available information at the moment.';
|
|
}
|
|
|
|
/* METHODS */
|
|
|
|
public function echoarea_stats(): Collection
|
|
{
|
|
return Cache::remember(md5(sprintf('%d-%s',$this->id,__METHOD__)),self::CACHE_TIME,function() {
|
|
$dt = Carbon::now()->startOfday();
|
|
$case = CaseBuilder::whenRaw("datetime >= '?'",$dt->subDay()->format('Y-m-d'))->thenRaw("'day'")
|
|
->whenRaw("datetime >= '?'",$dt->subDays(7)->format('Y-m-d'))->thenRaw("'week'")
|
|
->whenRaw("datetime >= '?'",$dt->subMonth()->format('Y-m-d'))->thenRaw("'month'")
|
|
->elseRaw("'all'");
|
|
|
|
return Echoarea::select(['echoareas.id','name','description','active',DB::raw('count(echomails.id) AS count'),DB::raw('min(datetime) as first_message'),DB::raw('max(datetime) as last_message')])
|
|
->selectRaw($case->toRaw().' AS stats')
|
|
->join('echomails',['echomails.echoarea_id'=>'echoareas.id'],NULL,NULL,'left outer')
|
|
->where('domain_id',$this->id)
|
|
->groupBy('echoareas.id')
|
|
->groupBy('echoareas.name')
|
|
->groupBy('stats')
|
|
->orderBy('echoareas.name')
|
|
->orderBy('last_message','DESC')
|
|
->get();
|
|
});
|
|
}
|
|
|
|
public function echoarea_total_daily(Collection $systems=NULL): Collection
|
|
{
|
|
return Cache::remember(md5(sprintf('%d-%s',$this->id,$systems?->pluck('id')->join(','))),self::CACHE_TIME,function() use ($systems) {
|
|
return DB::query()
|
|
->select(['echoareas.name','echoareas.show',DB::raw('COUNT(echoareas.name) AS count'),DB::raw('datetime::date AS date')])
|
|
->from($this->getTable())
|
|
->join('echoareas',['echoareas.domain_id'=>'domains.id'])
|
|
->join('echomails',['echomails.echoarea_id'=>'echoareas.id'])
|
|
->where('domains.id',$this->id)
|
|
->where('echomails.datetime','>=',Carbon::now()->subMonths(self::STATS_MONTHS)->startOfMonth())
|
|
->when($systems?->count(),function($query) use ($systems) { return $query->whereIn('echomails.fftn_id',$systems->pluck('addresses')->flatten()->pluck('id')); })
|
|
->groupBy(['echoareas.name','echoareas.show','date'])
|
|
->orderBy('echoareas.name')
|
|
->orderBy('date')
|
|
->get();
|
|
});
|
|
}
|
|
|
|
public function filearea_stats()
|
|
{
|
|
return Cache::remember(md5(sprintf('%d-%s',$this->id,__METHOD__)),self::CACHE_TIME,function() {
|
|
$dt = Carbon::now()->startOfday();
|
|
$case = CaseBuilder::whenRaw("datetime >= '?'",$dt->subDays(7)->format('Y-m-d'))->thenRaw("'week'")
|
|
->whenRaw("datetime >= '?'",$dt->subMonth()->format('Y-m-d'))->thenRaw("'month'")
|
|
->elseRaw("'all'");
|
|
|
|
return Filearea::select(['fileareas.id','fileareas.name','description','active',DB::raw('count(files.id) AS count'),DB::raw('min(datetime) as first_file'),DB::raw('max(datetime) as last_file')])
|
|
->selectRaw($case->toRaw().' AS stats')
|
|
->join('files',['files.filearea_id'=>'fileareas.id'],NULL,NULL,'left outer')
|
|
->where('domain_id',$this->id)
|
|
->groupBy('fileareas.id')
|
|
->groupBy('fileareas.name')
|
|
->groupBy('stats')
|
|
->orderBy('fileareas.name')
|
|
->orderBy('last_file','DESC')
|
|
->get();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Determine if this zone is managed by this host
|
|
*
|
|
* @return bool
|
|
* @throws \Exception
|
|
*/
|
|
public function isManaged(): bool
|
|
{
|
|
return ($x=our_address())
|
|
&& $x->pluck('zone.domain')
|
|
->pluck('id')
|
|
->contains($this->id);
|
|
}
|
|
|
|
/**
|
|
* Work out which of the users systems are not in this domain
|
|
*
|
|
* @param User $o
|
|
* @return Collection
|
|
*/
|
|
public function userHasSystemsNotInNet(User $o): Collection
|
|
{
|
|
$o->load('systems.akas.zone');
|
|
|
|
$result = collect();
|
|
foreach ($o->systems->filter(function($item) { return $item->active; }) as $so) {
|
|
if (! $so->akas->pluck('zone')->unique('domain_id')->pluck('domain_id')->contains($this->id))
|
|
$result->push($so);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
} |