/behaviors/FileAttachmentBehavior.php
https://gitlab.com/nitm/yii2-filemanager · PHP · 177 lines · 138 code · 12 blank · 27 comment · 23 complexity · ff8064eed971a808f561c803896c265d MD5 · raw file
- <?php
- namespace nitm\filemanager\behaviors;
- use yii\db\ActiveRecord;
- use yii\db\Expression;
- use yii\db\Query;
- use yii\web\UploadedFile;
- use nitm\helpers\ArrayHelper;
- use nitm\helpers\DateFormatter;
- use nitm\filemanager\models\File;
- use nitm\filemanager\models\Image;
- use nitm\filemanager\helpers\UploadHelper;
- use nitm\filemanager\helpers\FileHelper;
- use nitm\filemanager\helpers\ImageHelper;
- class FileAttachmentBehavior extends \yii\base\Behavior
- {
- public $attributes = ['file'];
- public $instanceName = 'file_name';
- public $attachFromStdIn = false;
- public $attachFromBase64 = false;
- public $automatic = true;
- /**
- * {@inheritdoc}
- */
- public function attach($owner)
- {
- parent::attach($owner);
- $this->attachBehaviors();
- }
- public function attachBehaviors()
- {
- foreach ($this->attributes as $attribute) {
- $this->owner->addMethod('set'.$attribute, function () use ($attribute) {
- $args = array_merge(func_get_args());
- if (count($args) == 1) {
- //Most likely just the data is coming in. If that is the case then we need to pad th arguments to the attach file function so that the data is the last argument
- array_unshift($args, $attribute, null, $attribute);
- }
- if ($this->owner->isNewRecord) {
- $this->owner->on(ActiveRecord::EVENT_AFTER_INSERT, function () use ($args) {
- call_user_func_array([$this, 'attachFile'], $args);
- });
- } else {
- call_user_func_array([$this, 'attachFile'], $args);
- }
- });
- }
- }
- /**
- * [attachFile description]
- * @param [type] $name [description]
- * @param [type] $id [description]
- * @param [type] $instanceName [description]
- * @param [type] $uploads [description]
- * @return [type] [description]
- */
- public function attachFile($name = null, $id = null, $instanceName = null, $uploads = null)
- {
- $ret_val = null;
- if ($this->automatic) {
- if (!$this->attachBase64Image($name, $id, $uploads)) {
- try {
- $ret_val = $this->attachFromUpload($name, $id, $instanceName, $uploads);
- } catch (\Exception $e) {
- $ret_val = $this->attachFromStdIn($name, $id, $uploads);
- }
- }
- } else {
- if ($this->attachFromStdIn) {
- $ret_val = $this->attachFromStdIn($name, $id, $uploads);
- } elseif ($this->attachFromBase64) {
- $ret_val = $this->attachFromBase64($name, $id, $uploads);
- } else {
- $ret_val = $this->attachFromUpload($name, $id, $instanceName, $uploads);
- }
- }
- if ($ret_val) {
- /**
- * Attachment methods will return an array of saved files
- * Need to determine if this relation is singular or multiple to set the right value.
- */
- $ret_val = $this->owner->getRelation($name)->multiple ? (array)$ret_val : array_shift($ret_val);
- $this->owner->populateRelation($name, $ret_val);
- }
- return $ret_val;
- }
- /**
- * [attachBase64Image description]
- * @param [type] $name [description]
- * @param [type] $id [description]
- * @param [type] $uploads [description]
- * @return [type] [description]
- */
- public function attachBase64Image($name = null, $id = null, $uploads = null)
- {
- /**
- * Taken from: https://stackoverflow.com/questions/11511511/how-to-save-a-png-image-server-side-from-a-base64-data-string
- * */
- if ($uploads) {
- $file = UploadHelper::getFromBase64($uploads);
- if (is_null($file)) {
- return false;
- }
- $uploads = [$file];
- $name = $name ?: strtolower(substr(\nitm\helpers\Classes::getCallerName(), 1));
- $relation = $this->owner->{'get'.$name}();
- $fileModel = $this->owner instanceof File ? $this->owner : $this->owner->$name();
- return self::saveInternally($fileModel, $uploads, [
- 'name' => $name,
- 'id' => $id
- ], $relation);
- } else {
- return false;
- }
- }
- public function attachFromUpload($name = null, $id = null, $instanceName = null, $uploads = null)
- {
- //Start at strlen('set') or 3 places
- $name = $name ?: strtolower(substr(\nitm\helpers\Classes::getCallerName(), 1));
- $id = $id ?: $this->owner->id;
- $instanceName = $instanceName ?? $this->instanceName;
- $relation = $this->owner->{'get'.$name}();
- $fileModel = $this->owner instanceof File ? $this->owner : $this->owner->$name();
- $uploads = $uploads ?: UploadedFile::getInstances($fileModel, $instanceName);
- if ($uploads == [] || empty($uploads)) {
- $uploads = UploadedFile::getInstancesByName($instanceName);
- if (empty($uploads) && ($instanceName !== $this->instanceName)) {
- $uploads = UploadedFile::getInstancesByName($this->instanceName);
- }
- } else {
- $uploads = is_array($uploads) ? $uploads : [$uploads];
- }
- return self::saveInternally($fileModel, $uploads, [
- 'name' => $name,
- 'id' => $id
- ], $relation);
- }
- public function attachFromStdIn($name = null, $id = null, $uploads = null)
- {
- if (!is_array($uploads)) {
- $file = UploadHelper::getFromStdIn();
- if (is_null($file)) {
- return false;
- }
- $uploads = [$file];
- }
- $name = $name ?: strtolower(substr(\nitm\helpers\Classes::getCallerName(), 1));
- $relation = $this->owner->{'get'.$name}();
- $fileModel = $this->owner instanceof File ? $this->owner : $this->owner->$name();
- return self::saveInternally($fileModel, $uploads, [
- 'name' => $name,
- 'id' => $id
- ], $relation);
- }
- protected function saveInternally($fileModel, $uploads, $options = [], $relation = null)
- {
- if ($fileModel instanceof Image) {
- $relation = $relation ?: 'image';
- $ret_val = ImageHelper::saveInternally($fileModel, $uploads, $options);
- } else {
- $relation = $relation ?: 'file';
- $ret_val = FileHelper::saveInternally($fileModel, $uploads, $options);
- }
- return $ret_val;
- }
- }