_changeHistoryHandler === null && $this->attachmentType) { if ($this->attachmentType->inQuestionary()) { $this->setChangeHistoryHandler(new QuestionaryActiveRecordChangeHistoryHandler($this)); } else { $this->setChangeHistoryHandler(new ApplicationActiveRecordChangeHistoryHandler($this)); } } } public function afterFind() { $this->_initAttachedEntity(); parent::afterFind(); } public function _initAttachedEntity() { if (!$this->isCommon()) { switch ($this->attachmentType->system_type) { case AttachmentType::SYSTEM_TYPE_TARGET: $this->attachedEntity = BachelorTargetReception::instance(); break; case AttachmentType::SYSTEM_TYPE_PREFERENCE: $this->attachedEntity = BachelorPreferences::instance(); break; case AttachmentType::SYSTEM_TYPE_INDIVIDUAL_ACHIEVEMENT: $this->attachedEntity = IndividualAchievement::instance(); break; case AttachmentType::SYSTEM_TYPE_FULL_RECOVERY_SPECIALITY: $this->attachedEntity = BachelorSpeciality::instance(); break; case AttachmentType::SYSTEM_TYPE_IDENTITY_DOCUMENT: $this->attachedEntity = PassportData::instance(); break; case AttachmentType::SYSTEM_TYPE_EDUCATION_DOCUMENT: $this->attachedEntity = EducationData::instance(); break; default: $this->attachedEntity = null; break; } } } public static function tableName() { return '{{%attachment}}'; } public static function getFileRelationTable() { return '{{%attachments_files}}'; } public static function getFileRelationColumn() { return 'attachment_id'; } public function behaviors() { return [TimestampBehavior::class]; } public function rules() { return [ [ [ 'questionary_id', 'application_id', 'owner_id', 'archived_at' ], 'integer' ], [ [ 'deleted', ], 'boolean' ], [ ['deleted'], 'default', 'value' => false ], [ ['attachment_type_id'], 'required', 'except' => [self::SCENARIO_MARK_DELETED] ], [ ['file'], 'file', 'extensions' => static::getExtensionsListForRules(), 'skipOnEmpty' => true, 'maxSize' => iniGet::getUploadMaxFilesize(false), 'except' => [ self::SCENARIO_MARK_DELETED, self::SCENARIO_RECOVER ] ], ]; } public function attributeLabels() { return [ 'file' => Yii::t('abiturient/attachment', 'Подпись для поля "file" формы "Скан документа": `файл`'), 'deleted' => Yii::t('abiturient/attachment', 'Подпись для поля "deleted" формы "Скан документа": `Удален`'), 'filename' => Yii::t('abiturient/attachment', 'Подпись для поля "filename" формы "Скан документа": `Имя файла`'), 'application_id' => Yii::t('abiturient/attachment', 'Подпись для поля "application_id" формы "Скан документа": `Id заявления`'), 'questionary_id' => Yii::t('abiturient/attachment', 'Подпись для поля "questionary_id" формы "Скан документа": `Id Анкеты`'), 'attachment_type_id' => Yii::t('abiturient/attachment', 'Подпись для поля "attachment_type_id" формы "Скан документа": `Тип прикрепляемого файла`'), ]; } public function scenarios() { $scenarios = parent::scenarios(); $scenarios[self::SCENARIO_MARK_DELETED] = ['deleted']; $scenarios[self::SCENARIO_RECOVER] = $scenarios[self::SCENARIO_DEFAULT]; return $scenarios; } public static function getExtensionsListForRules(): string { return implode(', ', static::getExtensionsList()); } public static function getExtensionsList(): array { return FilesWorker::getAllowedExtensionsToUploadList(); } public function getAbiturientQuestionary() { return $this->hasOne(AbiturientQuestionary::class, ['id' => 'questionary_id']); } public function getAttachmentLinkDependency() { return [ BachelorSpeciality::class, BachelorPreferences::class, BachelorTargetReception::class, IndividualAchievement::class, UserRegulation::class, EducationData::class, PassportData::class, ]; } public function getApplication() { return $this->hasOne(BachelorApplication::class, ['id' => 'application_id']); } public function getAttachmentType() { return $this->hasOne(AttachmentType::class, ['id' => 'attachment_type_id']); } public function getOwner() { return $this->hasOne(User::class, ['id' => 'owner_id']); } public function getOwnerId() { $abiturientQuestionary = $this->abiturientQuestionary; if (isset($abiturientQuestionary)) { return $abiturientQuestionary->user_id; } $bachelorApplication = $this->application; if (isset($bachelorApplication)) { return $bachelorApplication->user_id; } if (isset($this->owner_id)) { return $this->owner_id; } throw new ServerErrorHttpException('Не удалось определить владельца файла'); } public function checkAccess($user) { if ($user->isModer() || $user->isViewer()) { return true; } elseif ($user->id == $this->getOwnerId()) { return true; } else { return false; } } public function afterDelete() { parent::afterDelete(); $disable_history = !$this->getChangeHistoryHandler() || $this->getChangeHistoryHandler()->getDisabled(); if (!$disable_history && ArrayHelper::getValue($this, 'attachmentType.required')) { if ($this->application_id != null) { $application = BachelorApplication::findOne($this->application_id); if (isset($application)) { if ($this->scenario != self::SCENARIO_MARK_DELETED) { $application->resetStatus(); } } } } } public static function getNotFilledRequiredAttachmentTypeIds($attachments, $required_attachment_type_ids): array { if (empty($required_attachment_type_ids)) { return []; } $saved_attachment_type_ids = []; foreach ($attachments as $attachment) { if ($attachment->attachmentType && $attachment->attachmentType->need_one_of_documents) { $document_set_ref_id = $attachment->attachmentType->document_set_ref_id; if ($document_set_ref_id) { $sibling_attachment_type_ids = AttachmentType::find() ->where(['document_set_ref_id' => $document_set_ref_id]) ->andWhere(['not', ['id' => $attachment->attachment_type_id]]) ->select(['id']) ->column(); $saved_attachment_type_ids = array_merge($saved_attachment_type_ids, $sibling_attachment_type_ids); } } $saved_attachment_type_ids[] = $attachment->attachment_type_id; } $saved_attachment_type_ids = array_values(array_unique($saved_attachment_type_ids)); return array_diff($required_attachment_type_ids, $saved_attachment_type_ids); } public function getMimeType() { return AttachmentManager::GetMimeType($this->getExtension()); } public function inRegulation(): bool { if ($this->isNewRecord) { return false; } return $this->userRegulation !== null; } public function getUserRegulation() { return $this->hasOne(UserRegulation::class, ['id' => 'user_regulation_id']) ->viaTable('{{%attachments-user_regulations}}', ['attachment_id' => 'id']); } public function beforeArchive() { $this->setScenario(Attachment::SCENARIO_MARK_DELETED); } public static function getArchiveColumn(): string { return 'deleted'; } public static function getArchiveValue() { return true; } private function unlinkRegulation() { $regulation = $this->userRegulation; if ($regulation !== null) { $regulation->unlink('rawAttachments', $this, true); } } public function safeDelete(User $user, bool $updateHistory = true): bool { $transaction = Yii::$app->db->beginTransaction(); if (!isset($transaction)) { throw new UserException('Ошибка создания транзакции'); } $is_moder = Yii::$app->user->identity->isModer(); try { $this->unlinkRegulation(); $this->archive($updateHistory); if ( !$is_moder && $updateHistory && $user->userRef && $this->application_id != null ) { $application = BachelorApplication::findOne(['id' => $this->application_id]); if ( $application->resetStatus(false) && !$application->save() ) { throw new UserException('Ошибка обновления статуса заявления.'); } } if ($updateHistory) { $this->getChangeHistoryHandler()->getDeleteHistoryAction()->proceed(); } $transaction->commit(); } catch (Throwable $e) { $transaction->rollBack(); throw $e; } return true; } public function silenceSafeDelete() { $transaction = Yii::$app->db->beginTransaction(); if (!isset($transaction)) { throw new UserException('Ошибка создания транзакции'); } try { $this->unlinkRegulation(); $this->archive(false); $transaction->commit(); } catch (\Throwable $e) { $transaction->rollBack(); throw $e; } return true; } public function getFileDownloadUrl(): ?string { return Url::to(['site/download', 'id' => $this->id]); } public function getFileDeleteUrl(bool $make_redirect = false): ?string { return Url::to(['site/deletefile', 'key' => $this->id, 'redirect_back' => $make_redirect]); } public static function getLinkableSystemTypes() { return [ AttachmentType::SYSTEM_TYPE_PREFERENCE, AttachmentType::SYSTEM_TYPE_INDIVIDUAL_ACHIEVEMENT, AttachmentType::SYSTEM_TYPE_TARGET, AttachmentType::SYSTEM_TYPE_FULL_RECOVERY_SPECIALITY, AttachmentType::SYSTEM_TYPE_IDENTITY_DOCUMENT, AttachmentType::SYSTEM_TYPE_EDUCATION_DOCUMENT, ]; } public function isCommon(): bool { return $this->attachmentType->system_type === AttachmentType::SYSTEM_TYPE_COMMON; } public function isLinked(): bool { return in_array($this->attachmentType->system_type, Attachment::getLinkableSystemTypes()); } public function getEntity(): ?ActiveQuery { $en = $this->attachedEntity; if (!empty($_REQUEST['test'])){ $en = $this->entity; var_dump($en); echo '
'; print_r($en); echo ''; exit(); } return $this->hasOne($en::getModel(), ['id' => $en::getEntityTableLinkAttribute()])->viaTable($en::getTableLink(), [ $en::getAttachmentTableLinkAttribute() => 'id' ]); } public function getLinkedEntity(): ?AttachmentLinkableEntity { return $this->entity; } public function getAttachmentTypeName(): string { $name = null; if ($this->isLinked()) { try { $name = $this->entity->getName(); } catch (\Throwable $e) { Yii::error("Не удалось невозможно получить связанную сущность: {$e->getMessage()}"); } } return ($name ?? $this->attachmentType->name); } public function fileExists(): bool { return $this->linkedFile && $this->linkedFile->fileExists(); } public function getChangeLoggedAttributes() { return [ 'file', 'attachment_type_id' ]; } public function getClassTypeForChangeHistory(): int { return ChangeHistoryClasses::CLASS_ATTACHMENT; } public function getOldAttribute($name) { return null; } public function getOldAttributes() { return null; } public function getEntityChangeType(): int { return ChangeHistory::CHANGE_HISTORY_FILE; } public function setChangeHistoryHandler(ChangeHistoryHandlerInterface $handler): void { $this->_changeHistoryHandler = new AttachmentChangeHistoryDecorator($handler); } public function getChangeHistoryHandler(): ?ChangeHistoryHandlerInterface { $this->setUpChangeHistoryHandler(); return $this->_changeHistoryHandler; } public function getOldClass(): ChangeLoggedModelInterface { return $this; } public function getEntityIdentifier(): ?string { $attachmentType = ""; if (!($this->isCommon() || !$this->isLinked())) { try { $attachmentType = $this->getLinkedEntity()->getName(); } catch (\Throwable $e) { } } if (!$attachmentType) { $attachmentType = ArrayHelper::getValue($this, 'attachmentType.name'); } return $attachmentType; } public function beforeDelete() { if (parent::beforeDelete()) { $errorFrom = ''; $deleteSuccess = AttachmentManager::unlinkAttachmentFromAll($this); if (!$deleteSuccess) { $errorFrom .= "{$this->tableName()} -> {$this->id}\n"; } if (!$deleteSuccess) { Yii::error("Ошибка при удалении данных с портала. В таблице: {$errorFrom}"); } $this->deleteAttachedFile(); return $deleteSuccess; } else { return false; } } public function afterValidate() { (new LoggingAfterValidateHandler()) ->setModel($this) ->invoke(); } public function getIdentityString(): string { $attachment_type_doc_uid = ArrayHelper::getValue($this, 'attachmentType.name'); $attachment_type_name = ArrayHelper::getValue($this, 'attachmentType.documentType.ref_key'); $file_name = $this->filename; return "{$attachment_type_doc_uid}_{$attachment_type_name}_{$file_name}"; } public function getPropsToCompare(): array { return ArrayHelper::merge( array_diff( array_keys($this->attributes), [ 'questionary_id', 'application_id', 'owner_id', 'attachment_type_id', ] ), [ 'filename', ] ); } }