PageRenderTime 40ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/behaviors/FileAttachmentBehavior.php

https://gitlab.com/nitm/yii2-filemanager
PHP | 177 lines | 138 code | 12 blank | 27 comment | 23 complexity | ff8064eed971a808f561c803896c265d MD5 | raw file
  1. <?php
  2. namespace nitm\filemanager\behaviors;
  3. use yii\db\ActiveRecord;
  4. use yii\db\Expression;
  5. use yii\db\Query;
  6. use yii\web\UploadedFile;
  7. use nitm\helpers\ArrayHelper;
  8. use nitm\helpers\DateFormatter;
  9. use nitm\filemanager\models\File;
  10. use nitm\filemanager\models\Image;
  11. use nitm\filemanager\helpers\UploadHelper;
  12. use nitm\filemanager\helpers\FileHelper;
  13. use nitm\filemanager\helpers\ImageHelper;
  14. class FileAttachmentBehavior extends \yii\base\Behavior
  15. {
  16. public $attributes = ['file'];
  17. public $instanceName = 'file_name';
  18. public $attachFromStdIn = false;
  19. public $attachFromBase64 = false;
  20. public $automatic = true;
  21. /**
  22. * {@inheritdoc}
  23. */
  24. public function attach($owner)
  25. {
  26. parent::attach($owner);
  27. $this->attachBehaviors();
  28. }
  29. public function attachBehaviors()
  30. {
  31. foreach ($this->attributes as $attribute) {
  32. $this->owner->addMethod('set'.$attribute, function () use ($attribute) {
  33. $args = array_merge(func_get_args());
  34. if (count($args) == 1) {
  35. //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
  36. array_unshift($args, $attribute, null, $attribute);
  37. }
  38. if ($this->owner->isNewRecord) {
  39. $this->owner->on(ActiveRecord::EVENT_AFTER_INSERT, function () use ($args) {
  40. call_user_func_array([$this, 'attachFile'], $args);
  41. });
  42. } else {
  43. call_user_func_array([$this, 'attachFile'], $args);
  44. }
  45. });
  46. }
  47. }
  48. /**
  49. * [attachFile description]
  50. * @param [type] $name [description]
  51. * @param [type] $id [description]
  52. * @param [type] $instanceName [description]
  53. * @param [type] $uploads [description]
  54. * @return [type] [description]
  55. */
  56. public function attachFile($name = null, $id = null, $instanceName = null, $uploads = null)
  57. {
  58. $ret_val = null;
  59. if ($this->automatic) {
  60. if (!$this->attachBase64Image($name, $id, $uploads)) {
  61. try {
  62. $ret_val = $this->attachFromUpload($name, $id, $instanceName, $uploads);
  63. } catch (\Exception $e) {
  64. $ret_val = $this->attachFromStdIn($name, $id, $uploads);
  65. }
  66. }
  67. } else {
  68. if ($this->attachFromStdIn) {
  69. $ret_val = $this->attachFromStdIn($name, $id, $uploads);
  70. } elseif ($this->attachFromBase64) {
  71. $ret_val = $this->attachFromBase64($name, $id, $uploads);
  72. } else {
  73. $ret_val = $this->attachFromUpload($name, $id, $instanceName, $uploads);
  74. }
  75. }
  76. if ($ret_val) {
  77. /**
  78. * Attachment methods will return an array of saved files
  79. * Need to determine if this relation is singular or multiple to set the right value.
  80. */
  81. $ret_val = $this->owner->getRelation($name)->multiple ? (array)$ret_val : array_shift($ret_val);
  82. $this->owner->populateRelation($name, $ret_val);
  83. }
  84. return $ret_val;
  85. }
  86. /**
  87. * [attachBase64Image description]
  88. * @param [type] $name [description]
  89. * @param [type] $id [description]
  90. * @param [type] $uploads [description]
  91. * @return [type] [description]
  92. */
  93. public function attachBase64Image($name = null, $id = null, $uploads = null)
  94. {
  95. /**
  96. * Taken from: https://stackoverflow.com/questions/11511511/how-to-save-a-png-image-server-side-from-a-base64-data-string
  97. * */
  98. if ($uploads) {
  99. $file = UploadHelper::getFromBase64($uploads);
  100. if (is_null($file)) {
  101. return false;
  102. }
  103. $uploads = [$file];
  104. $name = $name ?: strtolower(substr(\nitm\helpers\Classes::getCallerName(), 1));
  105. $relation = $this->owner->{'get'.$name}();
  106. $fileModel = $this->owner instanceof File ? $this->owner : $this->owner->$name();
  107. return self::saveInternally($fileModel, $uploads, [
  108. 'name' => $name,
  109. 'id' => $id
  110. ], $relation);
  111. } else {
  112. return false;
  113. }
  114. }
  115. public function attachFromUpload($name = null, $id = null, $instanceName = null, $uploads = null)
  116. {
  117. //Start at strlen('set') or 3 places
  118. $name = $name ?: strtolower(substr(\nitm\helpers\Classes::getCallerName(), 1));
  119. $id = $id ?: $this->owner->id;
  120. $instanceName = $instanceName ?? $this->instanceName;
  121. $relation = $this->owner->{'get'.$name}();
  122. $fileModel = $this->owner instanceof File ? $this->owner : $this->owner->$name();
  123. $uploads = $uploads ?: UploadedFile::getInstances($fileModel, $instanceName);
  124. if ($uploads == [] || empty($uploads)) {
  125. $uploads = UploadedFile::getInstancesByName($instanceName);
  126. if (empty($uploads) && ($instanceName !== $this->instanceName)) {
  127. $uploads = UploadedFile::getInstancesByName($this->instanceName);
  128. }
  129. } else {
  130. $uploads = is_array($uploads) ? $uploads : [$uploads];
  131. }
  132. return self::saveInternally($fileModel, $uploads, [
  133. 'name' => $name,
  134. 'id' => $id
  135. ], $relation);
  136. }
  137. public function attachFromStdIn($name = null, $id = null, $uploads = null)
  138. {
  139. if (!is_array($uploads)) {
  140. $file = UploadHelper::getFromStdIn();
  141. if (is_null($file)) {
  142. return false;
  143. }
  144. $uploads = [$file];
  145. }
  146. $name = $name ?: strtolower(substr(\nitm\helpers\Classes::getCallerName(), 1));
  147. $relation = $this->owner->{'get'.$name}();
  148. $fileModel = $this->owner instanceof File ? $this->owner : $this->owner->$name();
  149. return self::saveInternally($fileModel, $uploads, [
  150. 'name' => $name,
  151. 'id' => $id
  152. ], $relation);
  153. }
  154. protected function saveInternally($fileModel, $uploads, $options = [], $relation = null)
  155. {
  156. if ($fileModel instanceof Image) {
  157. $relation = $relation ?: 'image';
  158. $ret_val = ImageHelper::saveInternally($fileModel, $uploads, $options);
  159. } else {
  160. $relation = $relation ?: 'file';
  161. $ret_val = FileHelper::saveInternally($fileModel, $uploads, $options);
  162. }
  163. return $ret_val;
  164. }
  165. }