diff --git a/common/models/File.php b/common/models/File.php index 4aa34c6..93b2e41 100644 --- a/common/models/File.php +++ b/common/models/File.php @@ -71,4 +71,21 @@ class File extends \yii\db\ActiveRecord 'status' => 'Status', ]; } + + /** + * @return string[] + */ + public function fields(): array + { + return [ + 'id', + 'name', + 'created_at', + 'updated_at', + 'url', + 'type', + 'mime-type', + 'status', + ]; + } } diff --git a/common/models/FileEntity.php b/common/models/FileEntity.php new file mode 100644 index 0000000..a94ed82 --- /dev/null +++ b/common/models/FileEntity.php @@ -0,0 +1,79 @@ + TimestampBehavior::class, + 'createdAtAttribute' => 'created_at', + 'updatedAtAttribute' => 'updated_at', + 'value' => new Expression('NOW()'), + ], + ]; + } + + /** + * {@inheritdoc} + */ + public static function tableName() + { + return 'file_entity'; + } + + /** + * {@inheritdoc} + */ + public function rules() + { + return [ + [['file_id', 'entity_type', 'entity_id', 'status'], 'integer'], + [['created_at', 'updated_at'], 'safe'], + [['file_id'], 'exist', 'skipOnError' => true, 'targetClass' => File::className(), 'targetAttribute' => ['file_id' => 'id']], + ]; + } + + /** + * {@inheritdoc} + */ + public function attributeLabels() + { + return [ + 'id' => 'ID', + 'file_id' => 'File ID', + 'entity_type' => 'Entity Type', + 'entity_id' => 'Entity ID', + 'created_at' => 'Created At', + 'updated_at' => 'Updated At', + 'status' => 'Status', + ]; + } + + /** + * @return \yii\db\ActiveQuery + */ + public function getFile() + { + return $this->hasOne(File::className(), ['id' => 'file_id']); + } +} diff --git a/console/migrations/m230526_105126_create_file_entity_teble.php b/console/migrations/m230526_105126_create_file_entity_teble.php new file mode 100644 index 0000000..a829b79 --- /dev/null +++ b/console/migrations/m230526_105126_create_file_entity_teble.php @@ -0,0 +1,51 @@ +createTable('{{%file_entity}}', [ + 'id' => $this->primaryKey(), + 'file_id' => $this->integer(11), + 'entity_type' => $this->integer(2), + 'entity_id' => $this->integer(11), + 'created_at' => $this->dateTime(), + 'updated_at' => $this->dateTime(), + 'status' => $this->integer(1)->defaultValue(1), + ]); + + $this->addForeignKey('fk_file_entity_file', 'file_entity', 'file_id', 'file', 'id'); + } + + /** + * {@inheritdoc} + */ + public function safeDown() + { + $this->dropForeignKey('fk_file_entity_file', 'file_entity'); + $this->dropTable('{{%file_entity}}'); + } + + /* + // Use up()/down() to run migration code without a transaction. + public function up() + { + + } + + public function down() + { + echo "m230526_105126_create_file_entity_teble cannot be reverted.\n"; + + return false; + } + */ +} diff --git a/frontend/modules/api/controllers/FileController.php b/frontend/modules/api/controllers/FileController.php index ed8a123..c8f79a5 100644 --- a/frontend/modules/api/controllers/FileController.php +++ b/frontend/modules/api/controllers/FileController.php @@ -4,7 +4,9 @@ namespace frontend\modules\api\controllers; use common\classes\Debug; use common\models\File; +use frontend\modules\api\models\FileEntity; use yii\helpers\FileHelper; +use yii\web\NotFoundHttpException; use yii\web\ServerErrorHttpException; use yii\web\UploadedFile; @@ -14,9 +16,47 @@ class FileController extends ApiController { return [ 'upload' => ['post'], + 'attach' => ['post'], ]; } + /** + * + * @OA\Post(path="/file/upload", + * summary="Загрузить файл", + * description="Метод для загрузки файлов", + * security={ + * {"bearerAuth": {}} + * }, + * tags={"File"}, + * + * @OA\RequestBody( + * @OA\MediaType( + * mediaType="multipart/form-data", + * @OA\Schema( + * required={"uploadFile"}, + * @OA\Property( + * property="uploadFile", + * type="file", + * description="Файл который необходимо загрузить", + * ), + * ), + * ), + * ), + * @OA\Response( + * response=200, + * description="Возвращает объект Файла", + * @OA\MediaType( + * mediaType="application/json", + * @OA\Schema(ref="#/components/schemas/FileExample"), + * ), + * ), + * ) + * + * @return array + * @throws ServerErrorHttpException + * @throws \yii\base\Exception + */ public function actionUpload() { $uploads = UploadedFile::getInstancesByName("uploadFile"); @@ -39,11 +79,11 @@ class FileController extends ApiController $fileModel = new File(); $fileModel->name = $file->name; $fileModel->path = $path; - $fileModel->url = "/files/". $md5[0] . $md5[1] . "/" . $md5[2] . $md5[3] . "/" . $md5 . '.' . $file->getExtension(); + $fileModel->url = "/files/" . $md5[0] . $md5[1] . "/" . $md5[2] . $md5[3] . "/" . $md5 . '.' . $file->getExtension(); $fileModel->type = $file->getExtension(); $fileModel->{'mime-type'} = $file->type; - if (!$fileModel->validate()){ + if (!$fileModel->validate()) { throw new ServerErrorHttpException(json_encode($fileModel->errors)); } @@ -55,4 +95,80 @@ class FileController extends ApiController return $savedFiles; } + /** + * + * @OA\Post(path="/file/attach", + * summary="Прикрепить файл", + * description="Метод для прикрепления файлов", + * security={ + * {"bearerAuth": {}} + * }, + * tags={"File"}, + * + * @OA\RequestBody( + * @OA\MediaType( + * mediaType="multipart/form-data", + * @OA\Schema( + * required={"file_id", "entity_type", "entity_id"}, + * @OA\Property( + * property="file_id", + * type="intager", + * example=232, + * description="Идентификатор файла", + * ), + * @OA\Property( + * property="entity_type", + * type="intager", + * example=2, + * description="Идентификатор типа сущности", + * ), + * @OA\Property( + * property="entity_id", + * type="intager", + * example=234, + * description="Идентификатор сущности", + * ), + * @OA\Property( + * property="status", + * type="intager", + * example=1, + * description="Статус", + * ), + * ), + * ), + * ), + * @OA\Response( + * response=200, + * description="Возвращает объект прикрепления", + * @OA\MediaType( + * mediaType="application/json", + * @OA\Schema(ref="#/components/schemas/FileEntity"), + * ), + * ), + * ) + * + * @return FileEntity + * @throws NotFoundHttpException + * @throws ServerErrorHttpException + */ + public function actionAttach() + { + $request = \Yii::$app->request->post(); + $file = File::findOne($request['file_id']); + if (!$file) { + throw new NotFoundHttpException('File bot found'); + } + + $fileEntity = new FileEntity(); + $fileEntity->load($request, ''); + + if(!$fileEntity->validate()){ + throw new ServerErrorHttpException(json_encode($fileEntity->errors)); + } + + $fileEntity->save(); + + return $fileEntity; + } + } \ No newline at end of file diff --git a/frontend/modules/api/controllers/ProjectController.php b/frontend/modules/api/controllers/ProjectController.php index ffa351f..0707066 100644 --- a/frontend/modules/api/controllers/ProjectController.php +++ b/frontend/modules/api/controllers/ProjectController.php @@ -141,7 +141,7 @@ class ProjectController extends ApiController } if (!empty($user_id)) { $projectIdList = ProjectUser::find()->where(['user_id' => $user_id])->select('project_id')->column(); - $query = Project::find()->where(['IN', 'id', $projectIdList])->andWhere(['status' => Project::STATUS_OTHER])->orWhere(['owner_id' => $user_id]); + $query = Project::find()->where(['IN', 'id', $projectIdList])->orWhere(['owner_id' => $user_id, 'status' => Project::STATUS_OTHER]); } else { $query = Project::find(); } diff --git a/frontend/modules/api/models/File.php b/frontend/modules/api/models/File.php new file mode 100644 index 0000000..6f9863e --- /dev/null +++ b/frontend/modules/api/models/File.php @@ -0,0 +1,66 @@ +