mirror of https://github.com/movim/movim
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
5.2 KiB
147 lines
5.2 KiB
<?php
|
|
|
|
namespace App;
|
|
|
|
use Illuminate\Database\Capsule\Manager as DB;
|
|
use Moxl\Xec\Action\Disco\Request;
|
|
use Moxl\Xec\Action\Vcard\Get;
|
|
|
|
use App\Presence;
|
|
use App\Info;
|
|
use App\Contact;
|
|
use Movim\Scheduler;
|
|
|
|
class PresenceBufferSaver
|
|
{
|
|
private $_models = null;
|
|
private $_calls = null;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->_models = collect();
|
|
$this->_calls = collect();
|
|
}
|
|
|
|
public function save()
|
|
{
|
|
if ($this->_models->count() > 0) {
|
|
try {
|
|
DB::beginTransaction();
|
|
|
|
// We delete all the presences that might already be there
|
|
$table = DB::table('presences');
|
|
$first = $this->_models->first();
|
|
$table = $table->where(function ($query) use ($first) {
|
|
$query->where('session_id', $first['session_id'])
|
|
->where('jid', $first['jid'])
|
|
->where('resource', $first['resource'])
|
|
->where('mucjid', $first['mucjid']);
|
|
});
|
|
|
|
$this->_models->skip(1)->each(function ($presence) use ($table) {
|
|
$table->orWhere(function ($query) use ($presence) {
|
|
$query->where('session_id', $presence['session_id'])
|
|
->where('jid', $presence['jid'])
|
|
->where('resource', $presence['resource'])
|
|
->where('mucjid', $presence['mucjid']);
|
|
});
|
|
});
|
|
$table->delete();
|
|
|
|
// And we save it
|
|
Presence::insert($this->_models->toArray());
|
|
DB::commit();
|
|
|
|
/**
|
|
* Handle the Capabilities & Vcards
|
|
*/
|
|
$nodes = collect();
|
|
$avatarHashes = collect();
|
|
|
|
$this->_models->each(function ($presence) use (&$nodes, &$avatarHashes) {
|
|
// Capabilities
|
|
if ($presence['node']) {
|
|
$resource = !empty($presence['resource']) ? '/' . $presence['resource'] : '';
|
|
$nodes->put($presence['node'], $presence['jid'] . $resource);
|
|
}
|
|
|
|
// Vcards
|
|
if (isset($presence['avatarhash'])) {
|
|
$fullJid = !empty($presence['resource'])
|
|
? $presence['jid'] . '/' . $presence['resource']
|
|
: $presence['jid'];
|
|
|
|
$jid = ($presence['muc'])
|
|
? (($presence['mucjid'] != '')
|
|
? $presence['mucjid']
|
|
: $fullJid)
|
|
: $presence['jid'];
|
|
|
|
$avatarHashes->put($presence['avatarhash'], $jid);
|
|
}
|
|
});
|
|
|
|
$infos = Info::whereIn('node', $nodes->keys())->get();
|
|
|
|
// Remove the already saved capabilities
|
|
$infos->each(function ($info) use (&$nodes) {
|
|
if ($nodes->has($info->node) && !$info->isEmptyFeatures()) {
|
|
$nodes->pull($info->node);
|
|
}
|
|
});
|
|
|
|
// Request the others
|
|
$nodes->each(function ($to, $node) {
|
|
$d = new Request;
|
|
$d->setTo($to)
|
|
->setNode($node)
|
|
->request();
|
|
});
|
|
|
|
// Memory leak there
|
|
if ($avatarHashes->count() > 0) {
|
|
$contactsHashes = Contact::whereIn('avatarhash', $avatarHashes->keys())
|
|
->whereNotNull('avatartype')
|
|
->get(['id', 'avatarhash'])->pluck('avatarhash', 'id');
|
|
|
|
// Remove the existing Contacts
|
|
$avatarHashes = $avatarHashes->reject(
|
|
fn($jid, $avatarhash) =>
|
|
$contactsHashes->has($jid) && $contactsHashes->get($jid) == $avatarhash
|
|
);
|
|
|
|
$avatarHashes->each(function ($jid, $avatarhash) {
|
|
if ($jid != me()->id) {
|
|
Scheduler::getInstance()->append('avatar_' . $jid . '_' . $avatarhash, function () use ($jid, $avatarhash) {
|
|
$r = new Get;
|
|
$r->setAvatarhash($avatarhash)
|
|
->setTo($jid)
|
|
->request();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
} catch (\Exception $e) {
|
|
DB::rollback();
|
|
logError($e);
|
|
}
|
|
$this->_models = collect();
|
|
}
|
|
|
|
if ($this->_calls->isNotEmpty()) {
|
|
$this->_calls->each(fn($call) => $call());
|
|
$this->_calls = collect();
|
|
}
|
|
}
|
|
|
|
public function append(Presence $presence, $call)
|
|
{
|
|
$this->_models[$this->getPresenceKey($presence)] = $presence->toArray();
|
|
$this->_calls->push($call);
|
|
}
|
|
|
|
private function getPresenceKey(Presence $presence)
|
|
{
|
|
return $presence->jid . $presence->mucjid . $presence->resource;
|
|
}
|
|
}
|