%PDF- %PDF-
Direktori : /home/vacivi36/intranet.vacivitta.com.br/protected/humhub/modules/file/widgets/ |
Current File : /home/vacivi36/intranet.vacivitta.com.br/protected/humhub/modules/file/widgets/Upload.php |
<?php /** * @link https://www.humhub.org/ * @copyright Copyright (c) 2016 HumHub GmbH & Co. KG * @license https://www.humhub.com/licences */ namespace humhub\modules\file\widgets; use humhub\components\ActiveRecord; use humhub\components\Widget; use humhub\modules\file\models\File; use Yii; use yii\base\Model; use yii\helpers\Html; /** * Base upload utility component which combines upload input/button, preview and progress components. * * An `UploadInput` serves as core upload component and is optionally linked to a progress and preview widget. An `UploadButton` * will wrap the input widget in a button and provides some further configurations e.g. to for styling and labels. * * If the `postState` flag is set to true (default), this component will try to fetch submitted files and auto attach them as * input fields to the surrounding form. This will preserve the upload state after failed form validations. * * This behavior may be deactivated or requires manual form cleanup in case the success result also contains the same upload component. * In such a case the `reset` flag can be activated in order to exclude all files no matter of the model or post state. * * ## Example: * * Model: * * ``` * class MyModel extends ActiveRecord * { * public $myFiles; * * public function rules() * { * return [ * [['files'], 'safe'] * ] * } * * public function afterSave($insert, $changedAttributes) * { * $this->fileManager->attach($this->myFiles); * parent::afterSave($insert, $changedAttributes); * } * } * ``` * * Controller: * * ``` * public actionEdit($id) * { * $model = MyModel::findOne(['id' => '$id']); * if($model->load(Yii::$app->request->post()) && $model->save()) { * $this->view->success(); * return $this->redirect(...); * } * * return $this->render(['model' => $model]); * } * ``` * * View: * * ``` * // Create initial upload component * $upload = Upload::forModel($model, $attribute); * * * // Output upload button with additional settings * echo $upload->button(['label' => true]); * * // Output upload progress bar widget * echo $upload->progress(); * * // Output upload file preview widget * echo $upload->preview(); * ``` * * @see UploadInput * @see UploadButton * @see UploadProgress * @see FilePreview * @since 1.3.5 */ class Upload extends Widget { const DEFAULT_SUBMIT_NAME = 'fileList[]'; const DEFAULT_UPLOAD_NAME = 'files[]'; const DEFAULT_ATTRIBUTE_NAME = 'files'; /** * @var Model the model the file array should be */ public $model; /** * @var string model attribute name containing files */ public $attribute; /** * @var string upload input name */ public $name; /** * @var string defines the input name of file items attached to the form after the upload */ public $submitName; /** * @var bool defines weather or not the component will auto attach posted file inputs to the form fetched from the * a post request. */ public $postState = true; /** * @var int|bool max allowed file upload, if set to true a default attachment maximum will be used */ public $max = true; /** * @var bool if set to true the upload component won't include any any file no matter of the model or post state */ public $reset = false; /** * @var string can be set to overwrite default file upload url */ public $url; /** * Static initializer for model based forms. * * @param $model * @param string $attribute * @param array $cfg * @return static * @throws \yii\base\InvalidConfigException */ public static function forModel($model, $attribute = self::DEFAULT_ATTRIBUTE_NAME, $cfg = []) { return static::create(array_merge($cfg, ['model' => $model, 'attribute' => $attribute])); } /** * Static initializer for simple form name based uploads * * @param $submitName * @param string|array $uploadName * @param array $cfg * @return static * @throws \yii\base\InvalidConfigException */ public static function withName($submitName = self::DEFAULT_SUBMIT_NAME, $uploadName = self::DEFAULT_UPLOAD_NAME, $cfg = []) { if(is_array($uploadName)) { $cfg = $uploadName; $uploadName = $submitName; } return static::create(array_merge($cfg, ['submitName' => $submitName, 'name' => $uploadName])); } /** * Static initializer * * @param array $cfg * @return static|object * @throws \yii\base\InvalidConfigException */ public static function create($cfg = []) { $cfg['class'] = static::class; return Yii::createObject($cfg); } /** * @inheritdoc */ public function init() { parent::init(); if (!$this->id) { $this->id = $this->getId(true); } if ($this->max === true) { /** @var \humhub\modules\content\Module $contentModule */ $contentModule = Yii::$app->getModule('content'); if ($contentModule !== null) { $this->max = $contentModule->maxAttachedFiles; } } } /** * @param string * @return $this */ public function submitName($submitName = self::DEFAULT_SUBMIT_NAME) { $this->submitName = $submitName; return $this; } /** * @param string * @return $this */ public function uploadName($uploadName = self::DEFAULT_UPLOAD_NAME) { $this->name = $uploadName; return $this; } /** * Used to define the `postState` flag which manages the input attachment of posted files. * If set to true (default) the upload component will try to fetch uploaded files from the request and attach input * fields to the surrounding form. * * @param bool $postState * @return $this */ public function postState($postState = true) { $this->postState = $postState; return $this; } /** * If condition is true, this upload component won't include any files for the input and preview component. * @param bool $condition */ public function reset($condition = true) { $this->reset = $condition; } /** * Renders a [[UploadButton]] widget for this upload. * * @param array $cfg * @return string * @throws \Exception * @see UploadButton */ public function button($cfg = []) { $cfg = array_merge([ 'id' => $this->id, 'model' => $this->model, 'attribute' => $this->attribute, 'name' => $this->name, 'submitName' => $this->submitName, 'postState' => $this->postState && !$this->reset, 'url' => $this->url ], $cfg); return UploadButton::widget($cfg); } /** * Renders a [[UploadInput]] widgets for this upload. * * The input widget doesn't have to be rendered manually if the result of `button()` was already included. * * @param array $cfg * @return string * @throws \Exception * @see UploadInput */ public function input($cfg = []) { $cfg = array_merge([ 'id' => $this->id, 'model' => $this->model, 'attribute' => $this->attribute, 'name' => $this->name, 'submitName' => $this->submitName, 'postState' => $this->postState && !$this->reset ], $cfg); return UploadInput::widget($cfg); } /** * Renders a progress bar component for this upload. * * The resulting progress bar widget will have an id of the following form: * * `<upload_id>_progress` * * @param array $cfg * @return string * @throws \Exception * @see UploadProgress */ public function progress($cfg = []) { $options = (isset($cfg['options'])) ? $cfg['options'] : []; $options['id'] = $this->id.'_progress'; $cfg['options'] = $options; return UploadProgress::widget($cfg); } /** * Renders a preview component for this upload. * * The resulting preview widget will have an id of the following form: * * `<upload_id>_preview` * * @param array $cfg * @return string * @throws \Exception * @see FilePreview */ public function preview($cfg = []) { $options = (isset($cfg['options'])) ? $cfg['options'] : []; $options['id'] = $this->id.'_preview'; $cfg['options'] = $options; $cfg = array_merge([ 'items' => $this->getPreviewFiles(isset($cfg['showInStream']) ? $cfg['showInStream'] : null), 'model' => $this->model, 'attribute' => $this->attribute, 'edit' => true ], $cfg); return FilePreview::widget($cfg); } /** * Assembles files for the preview widget. * * @param null $showInStream * @return array */ protected function getPreviewFiles($showInStream = null) { if($this->reset) { return []; } $resultMap = []; // Try fetching submitted files for this upload component if postState flag is active if($this->postState) { $resultMap = []; $postFiles = UploadInput::getSubmittedFiles($this->model, $this->attribute, $this->submitName); foreach ($postFiles as $postFile) { $resultMap[$postFile->guid] = $postFile; } } // Add already attached files $modelFiles = $this->getModelFiles($showInStream); if(!empty($modelFiles)) { foreach ($modelFiles as $attachedFile) { $resultMap[$attachedFile->guid] = $attachedFile; } } return array_values($resultMap); } private function getModelFiles($showInStream = null) { if($this->model instanceof ActiveRecord) { return($showInStream === null) ? $this->model->fileManager->findAll() : $this->model->fileManager->findStreamFiles($showInStream); } $result = []; if($this->model && $this->attribute) { $files = Html::getAttributeValue($this->model, $this->attribute); if(is_array($files)) { foreach ($files as $file) { $file = is_string($file) ? File::findOne(['guid' => $file]) : $file; if($file) { $result[] = $file; } } } } return $result; } }