hasErrors()) { return; } if ($this->to_space_id === (int)$this->sourceSpace->id) { $this->addError($attribute, Yii::t('AnimalManagementModule.base', 'You must choose a different destination rescue.')); return; } $target = Space::findOne(['id' => $this->to_space_id, 'status' => Space::STATUS_ENABLED]); if (!$target instanceof Space) { $this->addError($attribute, Yii::t('AnimalManagementModule.base', 'Selected destination rescue was not found.')); } } public function getTargetOptions(): array { return Space::find() ->select(['name', 'id']) ->where(['status' => Space::STATUS_ENABLED]) ->andWhere(['!=', 'id', (int)$this->sourceSpace->id]) ->orderBy(['name' => SORT_ASC]) ->indexBy('id') ->column(); } public function save(): bool { if (!$this->validate()) { return false; } $targetSpace = Space::findOne(['id' => $this->to_space_id, 'status' => Space::STATUS_ENABLED]); if (!$targetSpace instanceof Space) { $this->addError('to_space_id', Yii::t('AnimalManagementModule.base', 'Selected destination rescue was not found.')); return false; } $transaction = Yii::$app->db->beginTransaction(); try { $transfer = new AnimalTransfer(); $transfer->animal_id = (int)$this->animal->id; $transfer->from_contentcontainer_id = (int)$this->sourceSpace->contentcontainer_id; $transfer->to_contentcontainer_id = (int)$targetSpace->contentcontainer_id; $transfer->requested_by = Yii::$app->user->isGuest ? null : (int)Yii::$app->user->id; $transfer->status = AnimalTransfer::STATUS_REQUESTED; $transfer->request_message = trim($this->request_message); $transfer->conditions_text = trim($this->conditions_text); if (!$transfer->save()) { $this->addErrors($transfer->getErrors()); $transaction->rollBack(); return false; } $this->animal->status = Animal::STATUS_TRANSFER_PENDING; if (!$this->animal->save(false, ['status', 'updated_at'])) { $transaction->rollBack(); $this->addError('to_space_id', Yii::t('AnimalManagementModule.base', 'Could not update animal transfer status.')); return false; } $auditSaved = AnimalTransferEvent::log( $transfer, AnimalTransferEvent::EVENT_REQUESTED, null, AnimalTransfer::STATUS_REQUESTED, Yii::t('AnimalManagementModule.base', 'Transfer requested from {from} to {to}.', [ '{from}' => (string)$this->sourceSpace->name, '{to}' => (string)$targetSpace->name, ]), [ 'from_space_id' => (int)$this->sourceSpace->id, 'to_space_id' => (int)$targetSpace->id, ] ); if (!$auditSaved) { $transaction->rollBack(); $this->addError('to_space_id', Yii::t('AnimalManagementModule.base', 'Could not write transfer audit log.')); return false; } $transaction->commit(); } catch (\Throwable $e) { $transaction->rollBack(); Yii::error($e, 'animal_management.transfer_request'); $this->addError('to_space_id', Yii::t('AnimalManagementModule.base', 'Could not create transfer request.')); return false; } $this->transfer = $transfer; $this->notifyTargetManagers(); return true; } private function notifyTargetManagers(): void { $targetSpace = Space::findOne(['id' => $this->to_space_id]); if (!$targetSpace instanceof Space) { return; } $recipients = TransferNotifier::privilegedUsersForSpace($targetSpace); $originator = Yii::$app->user->isGuest ? null : Yii::$app->user->getIdentity(); foreach ($recipients as $recipient) { if ($originator instanceof \humhub\modules\user\models\User && (int)$recipient->id === (int)$originator->id) { continue; } $notification = TransferRequestedNotification::instance(); if ($originator) { $notification->from($originator); } $notification->animalName = $this->animal->getDisplayName(); $notification->fromSpaceName = (string)$this->sourceSpace->name; $notification->toSpaceGuid = (string)$targetSpace->guid; $notification->payload([ 'animalName' => $notification->animalName, 'fromSpaceName' => $notification->fromSpaceName, 'toSpaceGuid' => $notification->toSpaceGuid, ]); $notification->send($recipient); } } }