refactor: replace custom CRM with Monica fork
Some checks failed
Build & Push Monica Image to Gitea Registry / build-and-push (push) Failing after 9s
Some checks failed
Build & Push Monica Image to Gitea Registry / build-and-push (push) Failing after 9s
This commit is contained in:
48
app/Jobs/AddContactFromVCard.php
Normal file
48
app/Jobs/AddContactFromVCard.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Models\Account\ImportJob;
|
||||
use App\Services\VCard\ImportVCard;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class AddContactFromVCard implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var ImportJob
|
||||
*/
|
||||
protected $importJob;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $behaviour;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param ImportJob $importJob
|
||||
* @param string $behaviour
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ImportJob $importJob, string $behaviour = ImportVCard::BEHAVIOUR_ADD)
|
||||
{
|
||||
$this->importJob = $importJob;
|
||||
$this->behaviour = $behaviour;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->importJob->process($this->behaviour);
|
||||
}
|
||||
}
|
||||
44
app/Jobs/AuditLog/LogAccountAudit.php
Normal file
44
app/Jobs/AuditLog/LogAccountAudit.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\AuditLog;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Services\Instance\AuditLog\LogAccountAction;
|
||||
|
||||
class LogAccountAudit implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* The audit log instance.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $auditLog;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param array $auditLog
|
||||
*/
|
||||
public function __construct(array $auditLog)
|
||||
{
|
||||
$this->auditLog = $auditLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
app(LogAccountAction::class)->execute(
|
||||
$this->auditLog
|
||||
);
|
||||
}
|
||||
}
|
||||
63
app/Jobs/Avatars/CreateAvatarsForExistingContacts.php
Normal file
63
app/Jobs/Avatars/CreateAvatarsForExistingContacts.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Avatars;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
/**
|
||||
* This creates all the avatars (default, adorable and gravatars) for existing
|
||||
* contacts.
|
||||
*/
|
||||
class CreateAvatarsForExistingContacts implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries = 5;
|
||||
|
||||
/**
|
||||
* Determine the time at which this job should timeout.
|
||||
*
|
||||
* @return \Carbon\Carbon
|
||||
*/
|
||||
public function retryUntil()
|
||||
{
|
||||
$totalContact = Contact::whereNull('avatar_adorable_url')
|
||||
->orWhere('avatar_default_url', 'not like', 'avatars/%')
|
||||
->count();
|
||||
|
||||
return now()->addSeconds($totalContact / 500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$delay = $this->retryUntil();
|
||||
|
||||
Contact::without(['account', 'avatarPhoto', 'gender'])
|
||||
->whereNull('avatar_adorable_url')
|
||||
->orWhere('avatar_default_url', 'not like', 'avatars/%')
|
||||
->chunk(1000, function ($contacts) use ($delay) {
|
||||
foreach ($contacts as $contact) {
|
||||
GetAvatarsFromInternet::dispatch($contact)
|
||||
->delay($delay);
|
||||
GenerateDefaultAvatar::dispatch($contact)
|
||||
->delay($delay);
|
||||
}
|
||||
$delay = $delay->addMinutes(1);
|
||||
});
|
||||
}
|
||||
}
|
||||
60
app/Jobs/Avatars/GenerateDefaultAvatar.php
Normal file
60
app/Jobs/Avatars/GenerateDefaultAvatar.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Avatars;
|
||||
|
||||
use App\Helpers\StringHelper;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Services\Contact\Avatar\GenerateDefaultAvatar as GenerateDefaultAvatarService;
|
||||
|
||||
class GenerateDefaultAvatar implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries = 1;
|
||||
|
||||
/**
|
||||
* Contact to treat.
|
||||
*
|
||||
* @var Contact
|
||||
*/
|
||||
public $contact;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param Contact $contact
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Contact $contact)
|
||||
{
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (StringHelper::isNullOrWhitespace($this->contact->default_avatar_color)) {
|
||||
$this->contact->setAvatarColor();
|
||||
$this->contact->save();
|
||||
}
|
||||
|
||||
// generate the default avatar
|
||||
app(GenerateDefaultAvatarService::class)->execute([
|
||||
'contact_id' => $this->contact->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
54
app/Jobs/Avatars/GetAvatarsFromInternet.php
Normal file
54
app/Jobs/Avatars/GetAvatarsFromInternet.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Avatars;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Services\Contact\Avatar\GetAvatarsFromInternet as GetAvatarsFromInternetService;
|
||||
|
||||
class GetAvatarsFromInternet implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries = 1;
|
||||
|
||||
/**
|
||||
* Contact to treat.
|
||||
*
|
||||
* @var Contact
|
||||
*/
|
||||
public $contact;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param Contact $contact
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Contact $contact)
|
||||
{
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// generate the default avatar
|
||||
app(GetAvatarsFromInternetService::class)->execute([
|
||||
'contact_id' => $this->contact->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
196
app/Jobs/Avatars/MoveContactAvatarToPhotosDirectory.php
Normal file
196
app/Jobs/Avatars/MoveContactAvatarToPhotosDirectory.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Avatars;
|
||||
|
||||
use App\Models\Account\Photo;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Events\MoveAvatarEvent;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use App\Exceptions\FileNotFoundException;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Services\Contact\Avatar\UpdateAvatar;
|
||||
|
||||
class MoveContactAvatarToPhotosDirectory implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries = 1;
|
||||
|
||||
/**
|
||||
* @var Contact
|
||||
*/
|
||||
private $contact;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $dryrun;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Filesystem\Filesystem
|
||||
*/
|
||||
private $storage;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param Contact $contact
|
||||
* @param bool $dryrun
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Contact $contact, $dryrun)
|
||||
{
|
||||
$this->contact = $contact;
|
||||
$this->dryrun = $dryrun;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->storage = Storage::disk($this->contact->avatar_location);
|
||||
|
||||
// move avatar to new location
|
||||
$avatarFileName = $this->moveContactAvatars();
|
||||
|
||||
if ($this->dryrun) {
|
||||
return;
|
||||
}
|
||||
|
||||
// create a Photo object for this avatar
|
||||
$photo = $this->createPhotoObject($avatarFileName);
|
||||
|
||||
// associate the Photo object to the contact
|
||||
$this->associatePhotoAsAvatar($photo);
|
||||
|
||||
// delete original avatar
|
||||
$this->deleteOriginalAvatar($avatarFileName);
|
||||
|
||||
// delete thumbnails of avatars
|
||||
$this->deleteThumbnails();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
private function moveContactAvatars(): ?string
|
||||
{
|
||||
Event::dispatch(new MoveAvatarEvent($this->contact));
|
||||
|
||||
$newStorage = Storage::disk(config('filesystems.default'));
|
||||
$avatarFileName = $this->getAvatarFileName();
|
||||
|
||||
// $avatarFileName has the format `avatars/XXX.jpg`. We need to remove
|
||||
// the `avatars/` string to store the new file.
|
||||
$newAvatarFilename = str_replace('avatars/', 'photos/', $avatarFileName);
|
||||
|
||||
if ($newStorage->exists($newAvatarFilename)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $this->dryrun) {
|
||||
$avatarFile = $this->storage->get($avatarFileName);
|
||||
$newStorage->put($newAvatarFilename, $avatarFile, config('filesystems.default_visibility'));
|
||||
|
||||
$this->contact->avatar_location = config('filesystems.default');
|
||||
$this->contact->save();
|
||||
}
|
||||
|
||||
return $avatarFileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $avatarFileName
|
||||
* @return Photo|null
|
||||
*/
|
||||
private function createPhotoObject($avatarFileName): ?Photo
|
||||
{
|
||||
if (is_null($avatarFileName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$newAvatarFilename = str_replace('avatars/', '', $avatarFileName);
|
||||
|
||||
$photo = new Photo;
|
||||
$photo->account_id = $this->contact->account_id;
|
||||
$photo->original_filename = $newAvatarFilename;
|
||||
$photo->new_filename = 'photos/'.$newAvatarFilename;
|
||||
$photo->filesize = Storage::disk($this->contact->avatar_location)->size('/photos/'.$newAvatarFilename);
|
||||
$photo->mime_type = 'adfad';
|
||||
$photo->save();
|
||||
|
||||
return $photo;
|
||||
}
|
||||
|
||||
private function associatePhotoAsAvatar($photo)
|
||||
{
|
||||
if (is_null($photo)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'account_id' => $this->contact->account_id,
|
||||
'contact_id' => $this->contact->id,
|
||||
'source' => 'photo',
|
||||
'photo_id' => $photo->id,
|
||||
];
|
||||
app(UpdateAvatar::class)->execute($data);
|
||||
}
|
||||
|
||||
private function deleteThumbnails()
|
||||
{
|
||||
try {
|
||||
$smallThumbnail = $this->getAvatarFileName(110);
|
||||
$this->storage->delete($smallThumbnail);
|
||||
} catch (FileNotFoundException $e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
try {
|
||||
$bigThumbnail = $this->getAvatarFileName(174);
|
||||
$this->storage->delete($bigThumbnail);
|
||||
} catch (FileNotFoundException $e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private function deleteOriginalAvatar($avatarFileName)
|
||||
{
|
||||
$this->storage->delete($avatarFileName);
|
||||
}
|
||||
|
||||
private function getAvatarFileName($size = null)
|
||||
{
|
||||
$filename = pathinfo($this->contact->avatar_file_name, PATHINFO_FILENAME);
|
||||
$extension = pathinfo($this->contact->avatar_file_name, PATHINFO_EXTENSION);
|
||||
|
||||
$avatarFileName = 'avatars/'.$filename.'.'.$extension;
|
||||
if (! is_null($size)) {
|
||||
$avatarFileName = 'avatars/'.$filename.'_'.$size.'.'.$extension;
|
||||
}
|
||||
|
||||
if (! $this->fileExists($avatarFileName)) {
|
||||
throw new FileNotFoundException($avatarFileName);
|
||||
}
|
||||
|
||||
return $avatarFileName;
|
||||
}
|
||||
|
||||
private function fileExists($avatarFileName): bool
|
||||
{
|
||||
return $this->storage->exists($avatarFileName);
|
||||
}
|
||||
}
|
||||
31
app/Jobs/Avatars/UpdateAllGravatars.php
Normal file
31
app/Jobs/Avatars/UpdateAllGravatars.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Avatars;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class UpdateAllGravatars implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable;
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$contacts = Contact::where('avatar_source', 'gravatar')
|
||||
->orWhere('avatar_gravatar_url', '<>', '')
|
||||
->active()
|
||||
->get();
|
||||
|
||||
foreach ($contacts as $contact) {
|
||||
UpdateGravatar::dispatch($contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
54
app/Jobs/Avatars/UpdateGravatar.php
Normal file
54
app/Jobs/Avatars/UpdateGravatar.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Avatars;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Services\Contact\Avatar\GetGravatar;
|
||||
|
||||
class UpdateGravatar implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries = 1;
|
||||
|
||||
/**
|
||||
* Contact to treat.
|
||||
*
|
||||
* @var Contact
|
||||
*/
|
||||
public $contact;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param Contact $contact
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Contact $contact)
|
||||
{
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// generate the default avatar
|
||||
app(GetGravatar::class)->execute([
|
||||
'contact_id' => $this->contact->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
72
app/Jobs/Dav/DeleteMultipleVCard.php
Normal file
72
app/Jobs/Dav/DeleteMultipleVCard.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Dav;
|
||||
|
||||
use Illuminate\Bus\Batch;
|
||||
use Illuminate\Bus\Batchable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use App\Models\Account\AddressBookSubscription;
|
||||
|
||||
class DeleteMultipleVCard implements ShouldQueue
|
||||
{
|
||||
use Batchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var AddressBookSubscription
|
||||
*/
|
||||
private $subscription;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $hrefs;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param AddressBookSubscription $subscription
|
||||
* @param array $hrefs
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(AddressBookSubscription $subscription, array $hrefs)
|
||||
{
|
||||
$this->subscription = $subscription->withoutRelations();
|
||||
$this->hrefs = $hrefs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Last Consulted At field for the given contact.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
if (! $this->batching()) {
|
||||
return; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$batch = $this->batch();
|
||||
|
||||
collect($this->hrefs)
|
||||
->each(function ($href) use ($batch) {
|
||||
$this->deleteVCard($href, $batch);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the contact.
|
||||
*
|
||||
* @param string $href
|
||||
* @param \Illuminate\Bus\Batch $batch
|
||||
* @return void
|
||||
*/
|
||||
private function deleteVCard(string $href, Batch $batch): void
|
||||
{
|
||||
$batch->add([
|
||||
new DeleteVCard($this->subscription, $href),
|
||||
]);
|
||||
}
|
||||
}
|
||||
56
app/Jobs/Dav/DeleteVCard.php
Normal file
56
app/Jobs/Dav/DeleteVCard.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Dav;
|
||||
|
||||
use Illuminate\Bus\Batchable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use App\Models\Account\AddressBookSubscription;
|
||||
|
||||
class DeleteVCard implements ShouldQueue
|
||||
{
|
||||
use Batchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var AddressBookSubscription
|
||||
*/
|
||||
private $subscription;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $uri;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param AddressBookSubscription $subscription
|
||||
* @param string $uri
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(AddressBookSubscription $subscription, string $uri)
|
||||
{
|
||||
$this->subscription = $subscription->withoutRelations();
|
||||
$this->uri = $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Delete contact.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
if (! $this->batching()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::info(__CLASS__.' '.$this->uri);
|
||||
|
||||
$this->subscription->getClient()
|
||||
->request('DELETE', $this->uri);
|
||||
}
|
||||
}
|
||||
108
app/Jobs/Dav/GetMultipleVCard.php
Normal file
108
app/Jobs/Dav/GetMultipleVCard.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Dav;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Bus\Batchable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Sabre\CardDAV\Plugin as CardDAVPlugin;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use App\Models\Account\AddressBookSubscription;
|
||||
use App\Services\DavClient\Utils\Model\ContactUpdateDto;
|
||||
|
||||
class GetMultipleVCard implements ShouldQueue
|
||||
{
|
||||
use Batchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var AddressBookSubscription
|
||||
*/
|
||||
private $subscription;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $hrefs;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param AddressBookSubscription $subscription
|
||||
* @param array $hrefs
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(AddressBookSubscription $subscription, array $hrefs)
|
||||
{
|
||||
$this->subscription = $subscription->withoutRelations();
|
||||
$this->hrefs = $hrefs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Last Consulted At field for the given contact.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
if (! $this->batching()) {
|
||||
return; // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
$datas = $this->subscription->getClient()
|
||||
->addressbookMultiget([
|
||||
'{DAV:}getetag',
|
||||
$this->getAddressDataProperty(),
|
||||
], $this->hrefs);
|
||||
|
||||
collect($datas)
|
||||
->filter(function (array $contact): bool {
|
||||
return isset($contact[200]);
|
||||
})
|
||||
->each(function (array $contact, $href) {
|
||||
$this->updateVCard($contact, $href);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the contact.
|
||||
*
|
||||
* @param array $contact
|
||||
* @param string $href
|
||||
* @return void
|
||||
*/
|
||||
private function updateVCard(array $contact, $href): void
|
||||
{
|
||||
$card = Arr::get($contact, '200.{'.CardDAVPlugin::NS_CARDDAV.'}address-data');
|
||||
|
||||
if ($card !== null) {
|
||||
$dto = new ContactUpdateDto($href, Arr::get($contact, '200.{DAV:}getetag'), $card);
|
||||
|
||||
if (($batch = $this->batch()) !== null) {
|
||||
$batch->add([
|
||||
new UpdateVCard($this->subscription->user, $this->subscription->addressbook->name, $dto),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for address-data property.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getAddressDataProperty(): array
|
||||
{
|
||||
$addressDataAttributes = Arr::get($this->subscription->capabilities, 'addressData', [
|
||||
'content-type' => 'text/vcard',
|
||||
'version' => '4.0',
|
||||
]);
|
||||
|
||||
return [
|
||||
'name' => '{'.CardDAVPlugin::NS_CARDDAV.'}address-data',
|
||||
'value' => null,
|
||||
'attributes' => $addressDataAttributes,
|
||||
];
|
||||
}
|
||||
}
|
||||
71
app/Jobs/Dav/GetVCard.php
Normal file
71
app/Jobs/Dav/GetVCard.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Dav;
|
||||
|
||||
use Illuminate\Bus\Batchable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use App\Models\Account\AddressBookSubscription;
|
||||
use App\Services\DavClient\Utils\Model\ContactDto;
|
||||
use App\Services\DavClient\Utils\Model\ContactUpdateDto;
|
||||
|
||||
class GetVCard implements ShouldQueue
|
||||
{
|
||||
use Batchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var AddressBookSubscription
|
||||
*/
|
||||
private $subscription;
|
||||
|
||||
/**
|
||||
* @var ContactDto
|
||||
*/
|
||||
private $contact;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param AddressBookSubscription $subscription
|
||||
* @param ContactDto $contact
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(AddressBookSubscription $subscription, ContactDto $contact)
|
||||
{
|
||||
$this->subscription = $subscription->withoutRelations();
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Last Consulted At field for the given contact.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
if (! $this->batching()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::info(__CLASS__.' '.$this->contact->uri);
|
||||
|
||||
$response = $this->subscription->getClient()
|
||||
->request('GET', $this->contact->uri);
|
||||
|
||||
$this->chainUpdateVCard($response->body());
|
||||
}
|
||||
|
||||
private function chainUpdateVCard(string $card): void
|
||||
{
|
||||
$dto = new ContactUpdateDto($this->contact->uri, $this->contact->etag, $card);
|
||||
|
||||
if (($batch = $this->batch()) !== null) {
|
||||
$batch->add([
|
||||
new UpdateVCard($this->subscription->user, $this->subscription->addressbook->name, $dto),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
76
app/Jobs/Dav/PushVCard.php
Normal file
76
app/Jobs/Dav/PushVCard.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Dav;
|
||||
|
||||
use Illuminate\Bus\Batchable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use App\Models\Account\AddressBookSubscription;
|
||||
use App\Services\DavClient\Utils\Model\ContactPushDto;
|
||||
|
||||
class PushVCard implements ShouldQueue
|
||||
{
|
||||
use Batchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var AddressBookSubscription
|
||||
*/
|
||||
private $subscription;
|
||||
|
||||
/**
|
||||
* @var ContactPushDto
|
||||
*/
|
||||
private $contact;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param AddressBookSubscription $subscription
|
||||
* @param ContactPushDto $contact
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(AddressBookSubscription $subscription, ContactPushDto $contact)
|
||||
{
|
||||
$this->subscription = $subscription->withoutRelations();
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Last Consulted At field for the given contact.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
if (! $this->batching()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Log::info(__CLASS__.' '.$this->contact->uri);
|
||||
|
||||
$headers = [];
|
||||
|
||||
switch ($this->contact->mode) {
|
||||
case ContactPushDto::MODE_MATCH_ETAG:
|
||||
$headers['If-Match'] = $this->contact->etag;
|
||||
break;
|
||||
case ContactPushDto::MODE_MATCH_ANY:
|
||||
$headers['If-Match'] = '*';
|
||||
break;
|
||||
}
|
||||
|
||||
$response = $this->subscription->getClient()
|
||||
->request('PUT', $this->contact->uri, $this->contact->card, $headers);
|
||||
|
||||
$etag = $response->header('Etag');
|
||||
|
||||
$contact = Contact::where('account_id', $this->subscription->account_id)
|
||||
->findOrFail($this->contact->contactId);
|
||||
$contact->distant_etag = empty($etag) ? null : $etag;
|
||||
$contact->save();
|
||||
}
|
||||
}
|
||||
127
app/Jobs/Dav/UpdateVCard.php
Normal file
127
app/Jobs/Dav/UpdateVCard.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Dav;
|
||||
|
||||
use App\Models\User\User;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Bus\Batchable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Services\VCard\GetEtag;
|
||||
use App\Services\VCard\ImportVCard;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Support\Traits\Localizable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use App\Services\DavClient\Utils\Model\ContactUpdateDto;
|
||||
use App\Http\Controllers\DAV\Backend\CardDAV\CardDAVBackend;
|
||||
|
||||
class UpdateVCard implements ShouldQueue
|
||||
{
|
||||
use Batchable, InteractsWithQueue, Queueable, SerializesModels, Localizable;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $addressBookName;
|
||||
|
||||
/**
|
||||
* @var ContactUpdateDto
|
||||
*/
|
||||
private $contact;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $addressBookName
|
||||
* @param ContactUpdateDto $contact
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user, string $addressBookName, ContactUpdateDto $contact)
|
||||
{
|
||||
$this->user = $user->withoutRelations();
|
||||
$this->addressBookName = $addressBookName;
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Last Consulted At field for the given contact.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
if (! $this->batching()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->withLocale($this->user->preferredLocale(), function () {
|
||||
$newtag = $this->updateCard($this->addressBookName, $this->contact->uri, $this->contact->card);
|
||||
|
||||
if (! is_null($this->contact->etag) && $newtag !== $this->contact->etag) {
|
||||
Log::warning(__CLASS__.' '.__FUNCTION__.' wrong etag when updating contact. Expected '.$this->contact->etag.', get '.$newtag, [
|
||||
'contacturl' => $this->contact->uri,
|
||||
'carddata' => $this->contact->card,
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the contact with the carddata.
|
||||
*
|
||||
* @param mixed $addressBookId
|
||||
* @param string $cardUri
|
||||
* @param string $cardData
|
||||
* @return string|null
|
||||
*/
|
||||
private function updateCard($addressBookId, $cardUri, $cardData): ?string
|
||||
{
|
||||
$backend = app(CardDAVBackend::class)->init($this->user);
|
||||
|
||||
$contact_id = null;
|
||||
if ($cardUri) {
|
||||
$contactObject = $backend->getObject($addressBookId, $cardUri);
|
||||
|
||||
if ($contactObject) {
|
||||
$contact_id = $contactObject->id;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$result = app(ImportVCard::class)
|
||||
->execute([
|
||||
'account_id' => $this->user->account_id,
|
||||
'user_id' => $this->user->id,
|
||||
'contact_id' => $contact_id,
|
||||
'entry' => $cardData,
|
||||
'etag' => $this->contact->etag,
|
||||
'behaviour' => ImportVCard::BEHAVIOUR_REPLACE,
|
||||
'addressBookName' => $addressBookId === $backend->backendUri() ? null : $addressBookId,
|
||||
]);
|
||||
|
||||
if (! Arr::has($result, 'error')) {
|
||||
return app(GetEtag::class)->execute([
|
||||
'account_id' => $this->user->account_id,
|
||||
'contact_id' => $result['contact_id'],
|
||||
]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error(__CLASS__.' '.__FUNCTION__.': '.$e->getMessage(), [
|
||||
'contacturl' => $cardUri,
|
||||
'contact_id' => $contact_id,
|
||||
'carddata' => $cardData,
|
||||
$e,
|
||||
]);
|
||||
throw $e;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
97
app/Jobs/ExportAccount.php
Normal file
97
app/Jobs/ExportAccount.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Throwable;
|
||||
use Illuminate\Http\File;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Helpers\StorageHelper;
|
||||
use App\Models\Account\ExportJob;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Services\Account\Settings\SqlExportAccount;
|
||||
use App\Services\Account\Settings\JsonExportAccount;
|
||||
|
||||
class ExportAccount implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $path = '';
|
||||
|
||||
/**
|
||||
* Export job.
|
||||
*
|
||||
* @var ExportJob
|
||||
*/
|
||||
protected $exportJob;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param ExportJob $exportJob
|
||||
* @param string|null $path
|
||||
*/
|
||||
public function __construct(ExportJob $exportJob, string $path = null)
|
||||
{
|
||||
$exportJob->status = ExportJob::EXPORT_TODO;
|
||||
$exportJob->save();
|
||||
$this->exportJob = $exportJob->withoutRelations();
|
||||
$this->path = $path ?? 'exports';
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->exportJob->start();
|
||||
|
||||
$tempFileName = '';
|
||||
$handler = $this->exportJob->type === ExportJob::JSON ?
|
||||
app(JsonExportAccount::class) :
|
||||
app(SqlExportAccount::class);
|
||||
try {
|
||||
$tempFileName = $handler->execute([
|
||||
'account_id' => $this->exportJob->account_id,
|
||||
'user_id' => $this->exportJob->user_id,
|
||||
]);
|
||||
|
||||
// get the temp file that we just created
|
||||
$tempFilePath = StorageHelper::disk('local')->path($tempFileName);
|
||||
|
||||
// move the file to the public storage
|
||||
$file = StorageHelper::disk(config('filesystems.default'))
|
||||
->putFileAs($this->path, new File($tempFilePath), basename($tempFileName));
|
||||
|
||||
$this->exportJob->location = config('filesystems.default');
|
||||
$this->exportJob->filename = $file;
|
||||
|
||||
$this->exportJob->end();
|
||||
} catch (Throwable $e) {
|
||||
$this->fail($e);
|
||||
} finally {
|
||||
// delete old file from temp folder
|
||||
$storage = Storage::disk('local');
|
||||
if ($storage->exists($tempFileName)) {
|
||||
$storage->delete($tempFileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a job failure.
|
||||
*
|
||||
* @param \Throwable $exception
|
||||
*/
|
||||
public function failed(Throwable $exception): void
|
||||
{
|
||||
$this->exportJob->status = ExportJob::EXPORT_FAILED;
|
||||
$this->exportJob->save();
|
||||
}
|
||||
}
|
||||
69
app/Jobs/ExportAllAsSQL.php
Normal file
69
app/Jobs/ExportAllAsSQL.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Helpers\DBHelper;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class ExportAllAsSQL
|
||||
{
|
||||
use Dispatchable;
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$sql = '# ************************************************************
|
||||
# Monica data export.
|
||||
# Export date: '.now().'
|
||||
# ************************************************************
|
||||
|
||||
'.PHP_EOL;
|
||||
|
||||
$tables = DBHelper::getTables();
|
||||
|
||||
// Looping over the tables
|
||||
foreach ($tables as $table) {
|
||||
$tableName = $table->table_name;
|
||||
|
||||
$tableData = DB::table($tableName)->get();
|
||||
|
||||
// Looping over the rows
|
||||
foreach ($tableData as $data) {
|
||||
$newSQLLine = 'INSERT INTO '.$tableName.' (';
|
||||
$tableValues = [];
|
||||
|
||||
// Looping over the column names
|
||||
$tableColumnNames = [];
|
||||
foreach ($data as $columnName => $value) {
|
||||
array_push($tableColumnNames, $columnName);
|
||||
}
|
||||
|
||||
$newSQLLine .= implode(',', $tableColumnNames).') VALUES (';
|
||||
|
||||
// Looping over the values
|
||||
foreach ($data as $columnName => $value) {
|
||||
if (is_null($value)) {
|
||||
$value = 'NULL';
|
||||
} elseif (! is_numeric($value)) {
|
||||
$value = "'".addslashes($value)."'";
|
||||
}
|
||||
|
||||
array_push($tableValues, $value);
|
||||
}
|
||||
|
||||
$newSQLLine .= implode(',', $tableValues).');'.PHP_EOL;
|
||||
$sql .= $newSQLLine;
|
||||
}
|
||||
}
|
||||
$filename = 'export-all-'.time().'.sql';
|
||||
Storage::disk('local')->put($filename, $sql);
|
||||
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
81
app/Jobs/GetGPSCoordinate.php
Normal file
81
app/Jobs/GetGPSCoordinate.php
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Account\Place;
|
||||
use Illuminate\Bus\Batchable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\Middleware\RateLimited;
|
||||
use App\Exceptions\RateLimitedSecondException;
|
||||
use App\Services\Instance\Geolocalization\GetGPSCoordinate as GetGPSCoordinateService;
|
||||
|
||||
class GetGPSCoordinate implements ShouldQueue
|
||||
{
|
||||
use Batchable, Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var Place
|
||||
*/
|
||||
protected $place;
|
||||
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries = 10;
|
||||
|
||||
/**
|
||||
* The maximum number of unhandled exceptions to allow before failing.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $maxExceptions = 1;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Place $place)
|
||||
{
|
||||
$this->place = $place->withoutRelations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the middleware the job should pass through.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function middleware()
|
||||
{
|
||||
return [
|
||||
new RateLimited('GPSCoordinate'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (($batch = $this->batch()) !== null && $batch->cancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
app(GetGPSCoordinateService::class)->execute([
|
||||
'account_id' => $this->place->account_id,
|
||||
'place_id' => $this->place->id,
|
||||
]);
|
||||
} catch (RateLimitedSecondException $e) {
|
||||
$this->release(15);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
app/Jobs/GetWeatherInformation.php
Normal file
67
app/Jobs/GetWeatherInformation.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Account\Place;
|
||||
use Illuminate\Bus\Batchable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use App\Exceptions\NoCoordinatesException;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use App\Services\Instance\Weather\GetWeatherInformation as GetWeatherInformationService;
|
||||
|
||||
class GetWeatherInformation implements ShouldQueue
|
||||
{
|
||||
use Batchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var Place
|
||||
*/
|
||||
protected $place;
|
||||
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries = 10;
|
||||
|
||||
/**
|
||||
* The maximum number of unhandled exceptions to allow before failing.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $maxExceptions = 1;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Place $place)
|
||||
{
|
||||
$this->place = $place->withoutRelations();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (! $this->batching()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($this->place->latitude)) {
|
||||
$this->fail(new NoCoordinatesException());
|
||||
} else {
|
||||
app(GetWeatherInformationService::class)->execute([
|
||||
'account_id' => $this->place->account_id,
|
||||
'place_id' => $this->place->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
app/Jobs/Job.php
Normal file
21
app/Jobs/Job.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
||||
abstract class Job
|
||||
{
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Queueable Jobs
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This job base class provides a central location to place any logic that
|
||||
| is shared across all of your jobs. The trait included with the class
|
||||
| provides access to the "onQueue" and "delay" queue helper methods.
|
||||
|
|
||||
*/
|
||||
|
||||
use Queueable;
|
||||
}
|
||||
106
app/Jobs/Reminder/NotifyUserAboutReminder.php
Normal file
106
app/Jobs/Reminder/NotifyUserAboutReminder.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Reminder;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Helpers\AccountHelper;
|
||||
use App\Notifications\UserNotified;
|
||||
use App\Notifications\UserReminded;
|
||||
use App\Interfaces\MailNotification;
|
||||
use App\Models\Contact\ReminderOutbox;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
class NotifyUserAboutReminder implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var ReminderOutbox
|
||||
*/
|
||||
protected $reminderOutbox;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(ReminderOutbox $reminderOutbox)
|
||||
{
|
||||
$this->reminderOutbox = $reminderOutbox;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
// prepare the notification to be sent
|
||||
$message = $this->getMessage();
|
||||
|
||||
if (! is_null($message)) {
|
||||
$this->sendNotification($message);
|
||||
$this->scheduleNextReminder();
|
||||
}
|
||||
|
||||
// delete the reminder outbox
|
||||
$this->reminderOutbox->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the notification to this user.
|
||||
*
|
||||
* @param MailNotification $message
|
||||
* @return void
|
||||
*/
|
||||
private function sendNotification(MailNotification $message): void
|
||||
{
|
||||
if ($this->reminderOutbox->reminder->contact !== null) {
|
||||
$account = $this->reminderOutbox->user->account;
|
||||
$hasLimitations = AccountHelper::hasLimitations($account);
|
||||
if (! $hasLimitations) {
|
||||
Notification::send($this->reminderOutbox->user, $message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the next reminder for this user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function scheduleNextReminder(): void
|
||||
{
|
||||
/** @var \App\Models\Contact\Reminder */
|
||||
$reminder = $this->reminderOutbox->reminder;
|
||||
|
||||
if ($reminder->frequency_type == 'one_time') {
|
||||
$reminder->inactive = true;
|
||||
$reminder->save();
|
||||
} else {
|
||||
$reminder->schedule($this->reminderOutbox->user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message to send.
|
||||
*
|
||||
* @return MailNotification|null
|
||||
*/
|
||||
private function getMessage(): ?MailNotification
|
||||
{
|
||||
switch ($this->reminderOutbox->nature) {
|
||||
case 'reminder':
|
||||
return new UserReminded($this->reminderOutbox->reminder);
|
||||
case 'notification':
|
||||
return new UserNotified($this->reminderOutbox->reminder, $this->reminderOutbox->notification_number_days_before);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
68
app/Jobs/ResizeAvatars.php
Normal file
68
app/Jobs/ResizeAvatars.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Models\Contact\Contact;
|
||||
use Intervention\Image\Facades\Image;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Contracts\Filesystem\FileNotFoundException;
|
||||
|
||||
class ResizeAvatars implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
protected $contact;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Contact $contact)
|
||||
{
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (! $this->contact->has_avatar) {
|
||||
return;
|
||||
}
|
||||
|
||||
$storage = Storage::disk($this->contact->avatar_location);
|
||||
if (! $storage->exists($this->contact->avatar_file_name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$avatarFile = $storage->get($this->contact->avatar_file_name);
|
||||
$filename = pathinfo($this->contact->avatar_file_name, PATHINFO_FILENAME);
|
||||
$extension = pathinfo($this->contact->avatar_file_name, PATHINFO_EXTENSION);
|
||||
} catch (FileNotFoundException $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->resize($avatarFile, $filename, $extension, $storage, 110);
|
||||
$this->resize($avatarFile, $filename, $extension, $storage, 174);
|
||||
}
|
||||
|
||||
private function resize($avatarFile, $filename, $extension, $storage, $size)
|
||||
{
|
||||
$avatarFileName = 'avatars/'.$filename.'_'.$size.'.'.$extension;
|
||||
|
||||
$avatar = Image::make($avatarFile);
|
||||
$avatar->fit($size);
|
||||
|
||||
$storage->put($avatarFileName, (string) $avatar->stream(), config('filesystems.default_visibility'));
|
||||
}
|
||||
}
|
||||
43
app/Jobs/SendNewUserAlert.php
Normal file
43
app/Jobs/SendNewUserAlert.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\User\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Notifications\NewUserAlert;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
|
||||
class SendNewUserAlert implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$email = config('monica.email_new_user_notification');
|
||||
if (! empty($email)) {
|
||||
Notification::route('mail', $email)
|
||||
->notify(new NewUserAlert($this->user));
|
||||
}
|
||||
}
|
||||
}
|
||||
38
app/Jobs/SendVerifyEmail.php
Normal file
38
app/Jobs/SendVerifyEmail.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\User\User;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Auth\Notifications\VerifyEmail;
|
||||
|
||||
class SendVerifyEmail implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user)
|
||||
{
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->user->notify(new VerifyEmail());
|
||||
}
|
||||
}
|
||||
70
app/Jobs/ServiceQueue.php
Normal file
70
app/Jobs/ServiceQueue.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Throwable;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Services\QueuableService;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class ServiceQueue implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* The service to queue.
|
||||
*
|
||||
* @var QueuableService
|
||||
*/
|
||||
public $service;
|
||||
|
||||
/**
|
||||
* The data to run service.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $data;
|
||||
|
||||
/**
|
||||
* The number of times the job may be attempted.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $tries = 1;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param QueuableService $service
|
||||
* @param array|null $data
|
||||
*/
|
||||
public function __construct(QueuableService $service, array $data = null)
|
||||
{
|
||||
$this->service = $service;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$this->service->handle($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a job failure.
|
||||
*
|
||||
* @param \Throwable $exception
|
||||
* @return void
|
||||
*/
|
||||
public function failed(Throwable $exception): void
|
||||
{
|
||||
$this->service->failed($exception);
|
||||
}
|
||||
}
|
||||
61
app/Jobs/StayInTouch/ScheduleStayInTouch.php
Normal file
61
app/Jobs/StayInTouch/ScheduleStayInTouch.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\StayInTouch;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Helpers\AccountHelper;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use App\Notifications\StayInTouchEmail;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Support\Facades\Notification as NotificationFacade;
|
||||
|
||||
class ScheduleStayInTouch implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
protected $contact;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Contact $contact)
|
||||
{
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$account = $this->contact->account;
|
||||
|
||||
$users = [];
|
||||
foreach ($account->users as $user) {
|
||||
if ($user->isTheRightTimeToBeReminded($this->contact->stay_in_touch_trigger_date)
|
||||
&& ! AccountHelper::hasLimitations($account)) {
|
||||
array_push($users, $user);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($users) > 0) {
|
||||
NotificationFacade::send($users, new StayInTouchEmail($this->contact));
|
||||
$this->contact->setStayInTouchTriggerDate($this->contact->stay_in_touch_frequency, $this->contact->stay_in_touch_trigger_date);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$now = now();
|
||||
while ($this->contact->stay_in_touch_trigger_date < $now) {
|
||||
// If stay in touch was missed, we reschedule it.
|
||||
$this->contact->setStayInTouchTriggerDate($this->contact->stay_in_touch_frequency, $this->contact->stay_in_touch_trigger_date);
|
||||
}
|
||||
}
|
||||
}
|
||||
59
app/Jobs/SynchronizeAddressBooks.php
Normal file
59
app/Jobs/SynchronizeAddressBooks.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Models\Account\AddressBookSubscription;
|
||||
use App\Services\DavClient\SynchronizeAddressBook;
|
||||
|
||||
class SynchronizeAddressBooks implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* @var AddressBookSubscription
|
||||
*/
|
||||
public $subscription;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $force;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param AddressBookSubscription $subscription
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(AddressBookSubscription $subscription, bool $force = false)
|
||||
{
|
||||
$this->subscription = $subscription;
|
||||
$this->force = $force;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
try {
|
||||
app(SynchronizeAddressBook::class)->execute([
|
||||
'account_id' => $this->subscription->account_id,
|
||||
'addressbook_subscription_id' => $this->subscription->id,
|
||||
'force' => $this->force,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error(__CLASS__.' '.__FUNCTION__.':'.$e->getMessage(), [$e]);
|
||||
}
|
||||
$this->subscription->last_synchronized_at = now();
|
||||
$this->subscription->save();
|
||||
}
|
||||
}
|
||||
45
app/Jobs/UpdateLastConsultedDate.php
Normal file
45
app/Jobs/UpdateLastConsultedDate.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Models\Contact\Contact;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class UpdateLastConsultedDate implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
protected $contact;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Contact $contact)
|
||||
{
|
||||
$this->contact = $contact;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Last Consulted At field for the given contact.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$timestamps = $this->contact->timestamps;
|
||||
$this->contact->timestamps = false;
|
||||
|
||||
$this->contact->last_consulted_at = now();
|
||||
$this->contact->number_of_views = $this->contact->number_of_views + 1;
|
||||
|
||||
$this->contact->save();
|
||||
|
||||
$this->contact->timestamps = $timestamps;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user