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)); $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; } }