The interface for uploading files in Yii 2.0, the realization of multiplexing in multi-scenario (the validation rules for each scenario)
1. The interface for uploading the file, which only realizes the scenario of uploading the topic selection material, now needs to add the scene of the upload base icon, and decide to reuse the interface of the upload file, as shown in Figure 1
2. New request parameters, Scenario: optional, scene, default: default; CONFIG_BASE_LOCATION_ICON: The icon set by the base, default: default
3. Edit \api\rests\asset\uploadaction.php, the scene is set by constructing initialization configuration
* @since 1.0
*/
class UploadAction extends Action
{
/**
* @var string the scenario to be assigned to the new model before it is validated and saved.
*/
public $scenario = Model::SCENARIO_DEFAULT;
/**
* @var string the name of the view action. This property is need to create the URL when the model is successfully created.
*/
public $viewAction = 'view';
/**
* Uploads a new model.
* @return array the model newly uploaded
* @throws ServerErrorHttpException 如果创建目录失败,将抛出 500 HTTP 异常
* @throws ServerErrorHttpException if there is any error when creating the model
* @throws Exception if the directory could not be created (i.e. php error due to parallel changes)
*/
public function run()
{
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id);
}
$request = Yii::$app->request;
$scenario = $request->post('scenario', $this->scenario);
/* 验证场景的范围(['default', 'config_base_location_icon']) */
if (!in_array($scenario, [$this->scenario, Upload::SCENARIO_CONFIG_BASE_LOCATION_ICON])) {
throw new UnprocessableEntityHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '226076'), ['scenario' => $scenario])), 226076);
}
/* @var $model Upload */
$model = new Upload(['scenario' => $scenario]);
// 将 UploadedFile 实例数组赋值给 Upload::files
$model->files = UploadedFile::getInstances($model, 'files');
if ($model->validate()) {
$assetService = new AssetService();
$result = $assetService->uploadTempAssets($model->files);
return ['code' => 10000, 'message' => Yii::t('success', '126033'), 'data' => ['items' => $result]];
} elseif ($model->hasErrors()) {
$response = Yii::$app->getResponse();
$response->setStatusCode(422, 'Data Validation Failed.');
$firstError = '';
foreach ($model->getFirstErrors() as $message) {
$firstError = $message;
break;
}
return ['code' => 226004, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '226004'), ['first_error' => $firstError]))];
} elseif (!$model->hasErrors()) {
throw new ServerErrorHttpException('Failed to upload the object for unknown reason.');
}
}
}
4. Edit \common\logics\upload.php. By specifying the on attribute of the rule, a rule can only be applied in a certain scenario to distinguish the verification rules in different scenarios. Example: Upload the scene with the default scene, and upload the scene with the icon set by the base icon as the base.
false, 'extensions' => Yii::$app->params['pcsApi']['asset']['upload']['scenario']['configBaseLocationIcon']['extensions'], 'mimeTypes' => Yii::$app->params['pcsApi']['asset']['upload']['scenario']['configBaseLocationIcon']['mimeTypes'], 'minSize' => Yii::$app->params['pcsApi']['asset']['upload']['scenario']['configBaseLocationIcon']['minSize'], 'maxSize' => Yii::$app->params['pcsApi']['asset']['upload']['scenario']['configBaseLocationIcon']['maxSize'], 'maxFiles' => Yii::$app->params['pcsApi']['asset']['upload']['scenario']['configBaseLocationIcon']['maxFiles'], 'minWidth' => Yii::$app->params['pcsApi']['asset']['upload']['scenario']['configBaseLocationIcon']['minWidth'], 'maxWidth' => Yii::$app->params['pcsApi']['asset']['upload']['scenario']['configBaseLocationIcon']['maxWidth'], 'minHeight' => Yii::$app->params['pcsApi']['asset']['upload']['scenario']['configBaseLocationIcon']['minHeight'], 'maxHeight' => Yii::$app->params['pcsApi']['asset']['upload']['scenario']['configBaseLocationIcon']['maxHeight'], 'on' => self::SCENARIO_CONFIG_BASE_LOCATION_ICON],
[['files'], 'file', 'skipOnEmpty' => false, 'extensions' => Yii::$app->params['pcsApi']['asset']['upload']['extensions'], 'mimeTypes' => Yii::$app->params['pcsApi']['asset']['upload']['mimeTypes'], 'minSize' => Yii::$app->params['pcsApi']['asset']['upload']['minSize'], 'maxSize' => Yii::$app->params['pcsApi']['asset']['upload']['maxSize'], 'maxFiles' => Yii::$app->params['pcsApi']['asset']['upload']['maxFiles']],
];
}
public function formName()
{
return '';
}
}
5. The specific parameters of the verification rule are configured in the file \common\config\params-local.php
// 策划指挥系统接口
'pcsApi' => [
'asset' => [ // 资源
'basePath' => 'E:/wwwroot/pcs-api/storage', // BASE PATH
'tempDir' => '/tmp', // TEMP DIR
'hostInfo' => 'http://127.0.0.1/pcs-api/storage', // HOME URL
'baseUrl' => '', // BASE URL
'upload' => [ // 上传
'extensions' => 'ogg, pdf, xml, zip, gz, mp4, mp3, wav, webm, gif, jpeg, jpg, png, webp, svg, svgz, tiff, css, csv, txt, vcf, vcard, mov, qt, mkv, mk3d, mka, mks, wmv, flv', // 可接受上传的文件扩展名列表
'mimeTypes' => 'application/ogg, application/pdf, application/xml, application/zip, application/gzip, audio/mp4, audio/mpeg, audio/ogg, audio/vnd.wave, audio/webm, image/gif, image/jpeg, image/png, image/webp, image/svg+xml, image/tiff, text/css, text/csv, text/plain, text/vcard, text/xml, video/mpeg, video/mp4, video/ogg, video/quicktime, video/webm, video/x-matroska, video/x-ms-wmv, video/x-flv', // 可接受上传的 MIME 类型列表
'minSize' => null, // 上传文件所需最少多少 Byte 的大小
'maxSize' => 1024 * 1024 * 1024, // 上传文件所需最多多少 Byte 的大小
'maxFiles' => 10, // 给定属性最多能承载多少个文件
'scenario' => [ // 场景
'configBaseLocationIcon' => [ // 基地设置的图标
'extensions' => 'jpeg, jpg, png', // 可接受上传的文件扩展名列表
'mimeTypes' => 'image/jpeg, image/png', // 可接受上传的 MIME 类型列表
'minSize' => null, // 上传文件所需最少多少 Byte 的大小
'maxSize' => 1024 * 1024 * 2, // 上传文件所需最多多少 Byte 的大小
'maxFiles' => 2, // 给定属性最多能承载多少个文件
'minWidth' => 50, // 图片的最小宽度
'maxWidth' => 200, // 图片的最大宽度
'minHeight' => 50, // 图片的最小高度
'maxHeight' => 200, // 图片的最大高度
],
],
],
],
],
6. Upload the scene of the topic selection material, the file extension is the zip file, the upload is successful, in line with the expectations, as shown in Figure 2
7. In the scene of the icon set by the base, the file extension is the zip file, and the upload failed, which is in line with expectations, as shown in Figure 3
8. MaxFiles: How many files can be carried by a given attribute. The default is 1, which means that only single file uploads are allowed. If the value is greater than one, the input value must be an array containing the most uploaded file elements of MaxFiles. In the case of the icon set by the base, the number of uploaded files should only be 1. Now maxfiles: 2, you can upload up to 2 files at most, because when maxfiles: 1, the response fails, as shown in Figure 4
9. In different scenarios, the number of files can only be 1 in some scenarios, and the number of files in some scenarios can be multiple. Now maxfiles: 2, you can upload up to 2 files, as shown in Figure 5
10. Edit \api\rests\asset\uploadaction.php to determine the scene, if it is: config_base_location_icon, upload a single file (that is, the first file), now MaxFiles: 2, you can upload up to 2 files (2 files will be verified, but only the 1st will be uploaded) file), which is in line with the expectations (in fact, the best solution here should be a failure to respond, and the prompt can only upload one file, but it is necessary to implement another uploaded interface, which is redundant, so it is finally decided, or reused), as shown in Figure 6
* @since 1.0
*/
class UploadAction extends Action
{
/**
* @var string the scenario to be assigned to the new model before it is validated and saved.
*/
public $scenario = Model::SCENARIO_DEFAULT;
/**
* @var string the name of the view action. This property is need to create the URL when the model is successfully created.
*/
public $viewAction = 'view';
/**
* Uploads a new model.
* @return array the model newly uploaded
* @throws ServerErrorHttpException 如果创建目录失败,将抛出 500 HTTP 异常
* @throws ServerErrorHttpException if there is any error when creating the model
* @throws Exception if the directory could not be created (i.e. php error due to parallel changes)
*/
public function run()
{
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id);
}
$request = Yii::$app->request;
$scenario = $request->post('scenario', $this->scenario);
/* 验证场景的范围(['default', 'config_base_location_icon']) */
if (!in_array($scenario, [$this->scenario, Upload::SCENARIO_CONFIG_BASE_LOCATION_ICON])) {
throw new UnprocessableEntityHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '226076'), ['scenario' => $scenario])), 226076);
}
/* @var $model Upload */
$model = new Upload(['scenario' => $scenario]);
// 将 UploadedFile 实例数组赋值给 Upload::files
$model->files = UploadedFile::getInstances($model, 'files');
if ($model->validate()) {
$assetService = new AssetService();
/* 判断场景,如果为:config_base_location_icon,则上传单个文件(即第 1 个文件) */
if ($scenario == Upload::SCENARIO_CONFIG_BASE_LOCATION_ICON) {
// 将 UploadedFile 实例赋值给 Upload::files
$model->files = [$model->files[0]];
}
$result = $assetService->uploadTempAssets($model->files);
return ['code' => 10000, 'message' => Yii::t('success', '126033'), 'data' => ['items' => $result]];
} elseif ($model->hasErrors()) {
$response = Yii::$app->getResponse();
$response->setStatusCode(422, 'Data Validation Failed.');
$firstError = '';
foreach ($model->getFirstErrors() as $message) {
$firstError = $message;
break;
}
return ['code' => 226004, 'message' => Yii::t('error', Yii::t('error', Yii::t('error', '226004'), ['first_error' => $firstError]))];
} elseif (!$model->hasErrors()) {
throw new ServerErrorHttpException('Failed to upload the object for unknown reason.');
}
}
}





