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:
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user