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.
257 lines
7.1 KiB
257 lines
7.1 KiB
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Anik\Amqp\Exchange;
|
|
use Anik\Amqp\Facades\Amqp;
|
|
use App\Events\ModelSaved;
|
|
use PhpAmqpLib\Wire\AMQPTable;
|
|
use Anik\Amqp\PublishableMessage;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Validation\Validator;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Validation\ValidationException;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Illuminate\Database\Eloquent\Model as EloquentModel;
|
|
|
|
|
|
class Model extends EloquentModel
|
|
{
|
|
|
|
/**
|
|
* Introducing model relationships
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $fillable_relations = [];
|
|
|
|
/**
|
|
* Models that are ready to change.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $filled_relations = [];
|
|
|
|
/**
|
|
* Models that are ready to change.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $reportable = [];
|
|
|
|
protected $dirties = [];
|
|
|
|
protected $action = null;
|
|
|
|
public const CREATED = 10;
|
|
|
|
public const UPDATED = 20;
|
|
|
|
public const DELETED = 30;
|
|
|
|
public const RESTORED = 40;
|
|
|
|
protected static function booted()
|
|
{
|
|
static::created(function ($model) {
|
|
$model->action = static::CREATED;
|
|
});
|
|
|
|
static::updated(function ($model) {
|
|
$model->action = static::UPDATED;
|
|
});
|
|
|
|
static::deleted(function ($model) {
|
|
$model->action = static::DELETED;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
* @throw \Exception
|
|
*/
|
|
public function rules()
|
|
{
|
|
return [];
|
|
}
|
|
|
|
/**
|
|
*
|
|
*
|
|
* @param array $attributes
|
|
* @return void
|
|
*/
|
|
public function validate(array $attributes = null)
|
|
{
|
|
$attributes = $attributes ?? $this->getAttributes();
|
|
|
|
/** @var Validator $validator */
|
|
$validator = app('validator')->make($attributes, $this->rules());
|
|
|
|
if ($validator->fails()) {
|
|
throw new ValidationException(
|
|
$validator,
|
|
new JsonResponse($validator->errors()->getMessages(), Response::HTTP_UNPROCESSABLE_ENTITY)
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
public function updateRelations()
|
|
{
|
|
}
|
|
|
|
/**
|
|
* @param string|null $key
|
|
* @return void
|
|
*/
|
|
public function getValueOf(?string $key)
|
|
{
|
|
$values = [];
|
|
|
|
if ($key && isset($values, $key)) {
|
|
return $values[$key];
|
|
}
|
|
|
|
return $values;
|
|
}
|
|
|
|
protected function makeChanges()
|
|
{
|
|
if (empty($this->reportable)) {
|
|
return;
|
|
}
|
|
|
|
$changes = new Collection($this->getDirty());
|
|
|
|
// fillable * or field
|
|
$changes = $changes->filter(function ($value, $key) {
|
|
foreach ($this->reportable as $i => $name) {
|
|
if ($key === $name) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
});
|
|
|
|
if (($changes->isEmpty() && $this->action == static::UPDATED)) {
|
|
return;
|
|
}
|
|
|
|
return [
|
|
'original' => $this->getOriginal() + $this->getAttributes(),
|
|
'diff' => $changes->toArray(),
|
|
];
|
|
|
|
// return [
|
|
// 'auth' => Auth::id(),
|
|
// 'timestamp' => $this->freshTimestamp(),
|
|
// 'business' => $this->getValueOf('business_id'),
|
|
// 'info' => \request('_business_info')['info'] ?? null,
|
|
// 'project' => $this->getValueOf('project_id'),
|
|
// 'data' => [
|
|
// 'sprint_id' => $this->getValueOf('sprint_id'),
|
|
// 'system_id' => $this->getValueOf('system_id'),
|
|
// 'workflow_id' => $this->getValueOf('workflow_id'),
|
|
// 'status_id' => $this->getValueOf('status_id'),
|
|
// 'user_id' => $this->getValueOf('user_id'),
|
|
// 'table_name' => $this->getTable(),
|
|
// 'crud_id' => $this->action,
|
|
// 'original' => $this->getOriginal() + $this->getAttributes(),
|
|
// 'diff' => $changes->toArray(),
|
|
// ],
|
|
// 'from' => env('CONTAINER_NAME'),
|
|
// ];
|
|
}
|
|
|
|
protected function report($changes): void
|
|
{
|
|
if ($this->action == null){
|
|
return;
|
|
}
|
|
$payload = [
|
|
'auth' => Auth::id(),
|
|
'timestamp' => $this->freshTimestamp(),
|
|
'business' => $this->getValueOf('business_id'),
|
|
'info' => \request('_business_info') ?? null,
|
|
'project' => $this->getValueOf('project_id'),
|
|
'data' => [
|
|
'sprint_id' => $this->getValueOf('sprint_id'),
|
|
'system_id' => $this->getValueOf('system_id'),
|
|
'workflow_id' => $this->getValueOf('workflow_id'),
|
|
'status_id' => $this->getValueOf('status_id'),
|
|
'task_id' => $this->getValueOf('task_id'),
|
|
'subject_id' => $this->getValueOf('subject_id'),
|
|
'user_id' => $this->getValueOf('user_id'),
|
|
'table_name' => $this->getTable(),
|
|
'crud_id' => $this->action,
|
|
'original' => $changes['original'] + $this->getOriginal(),
|
|
'diff' => $changes['diff'],
|
|
],
|
|
'from' => env('CONTAINER_NAME'),
|
|
];
|
|
|
|
$message = new PublishableMessage(json_encode($payload));
|
|
|
|
ModelSaved::dispatch(json_encode($payload));
|
|
|
|
// $routers = [
|
|
// "activity_exchange" => ["name" => "activity",],
|
|
// "notif_exchange" => ["name" => "notif",],
|
|
// "socket_exchange" => ["name" => "socket",],
|
|
// ];
|
|
//
|
|
// foreach ($routers as $exchange => $properties) {
|
|
// $message->setProperties(["application_headers" => new AMQPTable($properties)]);
|
|
//
|
|
// $message->setExchange(new Exchange($exchange));
|
|
//
|
|
// Amqp::publish($message, "");
|
|
// }
|
|
}
|
|
|
|
/**
|
|
* @param array $options
|
|
* @return void
|
|
*/
|
|
public function save(array $options = [])
|
|
{
|
|
// The validation function is called first
|
|
$this->validate();
|
|
|
|
// Then, because the relationships are set as attributes in this model
|
|
// we pre-enter their names in filled_relation attribute and store
|
|
// them in a temporary variable with a loop.
|
|
foreach ($this->fillable_relations as $relation) {
|
|
$this->filled_relations[$relation] = $this[$relation];
|
|
unset($this[$relation]);
|
|
}
|
|
|
|
// all of its action inside one transaction
|
|
// so if any of them failed the whole
|
|
// process rollbacked
|
|
DB::transaction(function () use ($options) {
|
|
// report to the activity aggregator
|
|
$changes = $this->makeChanges();
|
|
|
|
// save the model with it's attributes
|
|
parent::save($options);
|
|
|
|
// save the model with it's relationships
|
|
$this->updateRelations();
|
|
|
|
is_array($changes) ? $this->report($changes) : true;
|
|
}, 3);
|
|
}
|
|
|
|
public function delete()
|
|
{
|
|
$changes = $this->makeChanges();
|
|
parent::delete();
|
|
is_array($changes) ? $this->report($changes) : true;
|
|
}
|
|
}
|