PageRenderTime 60ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/helpers/FileHelper.php

https://gitlab.com/nitm/yii2-filemanager
PHP | 196 lines | 152 code | 20 blank | 24 comment | 27 complexity | 6ae332f7e3db9059ce148c889c053355 MD5 | raw file
  1. <?php
  2. namespace nitm\filemanager\helpers;
  3. use yii\web\UploadedFile;
  4. use yii\helpers\Inflector;
  5. use yii\helpers\FileHelper as FileHelperBase;
  6. use nitm\filemanager\models\File;
  7. use nitm\helpers\ArrayHelper;
  8. use nitm\helpers\Network;
  9. use kartik\icons\Icon;
  10. use nitm\filemanager\helpers\Storage;
  11. /*
  12. * This is the directory interface class that finds directory information and returns it
  13. */
  14. class FileHelper extends FileHelperBase
  15. {
  16. protected static $_helper;
  17. public static function writeFile($data, $path)
  18. {
  19. return static::getHelper()->save($data, $path);
  20. }
  21. public static function delete($path)
  22. {
  23. return static::getHelper()->delete($path);
  24. }
  25. public static function getHelper()
  26. {
  27. if (!isset(static::$_helper)) {
  28. static::$_helper = new \nitm\filemanager\helpers\storage\Local;
  29. }
  30. return static::$_helper;
  31. }
  32. public static function exists($directory)
  33. {
  34. $directory = static::resolveFile($directory);
  35. return is_dir($directory) && is_readable($directory);
  36. }
  37. public static function saveInternally($fileModel, $uploads, $options=[])
  38. {
  39. $ret_val = [];
  40. $saveOptions = [
  41. 'method' => 'move'
  42. ];
  43. extract($options);
  44. $pathId = md5(is_null($id) ? uniqid() : $id);
  45. $name = File::getSafeName($name);
  46. //Increase the count for the files for this model $model
  47. $idx = ($count = $fileModel->getCount()->one()) != null ? $count->count() : 0;
  48. foreach ($uploads as $uploadedFile) {
  49. if ($uploadedFile->hasError) {
  50. $ret_val[] = new File();
  51. continue;
  52. }
  53. if ($uploadedFile->type == File::URL_MIME) {
  54. list($uploadedFile, $size) = UploadHelper::getFromUrl(file_get_contents($uploadedFile->tempName));
  55. } else {
  56. $size = getimagesize($uploadedFile->tempName);
  57. }
  58. //We're counting starting from 1
  59. $idx++;
  60. $file = new File(['scenario' => 'create']);
  61. $fileContentType = substr($uploadedFile->type, 0, strpos($uploadedFile->type, '/'));
  62. $directory = rtrim(implode(DIRECTORY_SEPARATOR, array_filter([rtrim(static::getDirectory($fileContentType), DIRECTORY_SEPARATOR), $name, $id])), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
  63. $file->setAttributes([
  64. 'width' => $size[0] || 0,
  65. 'height' => $size[1] || 0,
  66. 'type' => $uploadedFile->type,
  67. 'file_name' => $uploadedFile->name,
  68. 'remote_type' => $name,
  69. 'remote_id' => $id,
  70. 'slug' => File::getSafeName($name)."-$id-$fileContentType-$idx",
  71. 'signature' => File::getHash($uploadedFile->tempName),
  72. 'url' => $directory.implode('-', array_filter([Inflector::slug($uploadedFile->baseName), md5($uploadedFile->name)])).".".$uploadedFile->extension,
  73. 'size' => $uploadedFile->size
  74. ], false);
  75. $originalPath = $file->url;
  76. $tempFile = new File([
  77. 'url' => $uploadedFile->tempName,
  78. 'type' => $uploadedFile->type
  79. ]);
  80. $existing = File::find()->where([
  81. "signature" => $file->signature,
  82. 'remote_type' => $name,
  83. 'remote_id' => $id
  84. ])->one();
  85. if ($existing instanceof File) {
  86. //If an file already exists for this file then swap files
  87. $file = $existing;
  88. \Yii::trace("Found dangling $name file ".$file->slug);
  89. $tempFile->id = $file->getId();
  90. // self::createThumbnails($file, $file->type, $file->getRealPath());
  91. $existing->remote_id = $id;
  92. $existing->save();
  93. $ret_val[] = $file;
  94. } else {
  95. if (!Storage::exists($file->url, $fileContentType) && $file->signature) {
  96. //This file doesn't exist yet
  97. $file->remote_id = $id;
  98. $fileDir = dirname($file->getRealPath());
  99. if (!Storage::containerExists($fileDir, $fileContentType)) {
  100. Storage::createContainer($fileDir, true, [], $fileContentType);
  101. }
  102. $url = Storage::save($tempFile, $file->getRealPath(), [], false, $file->getRealPath(), $fileContentType);
  103. if (filter_var($url, FILTER_VALIDATE_URL)) {
  104. $proceed = true;
  105. $file->url = $url;
  106. } elseif (Storage::exists($file->getRealPath(), $fileContentType)) {
  107. $proceed = true;
  108. } else {
  109. $proceed = false;
  110. }
  111. if ($proceed) {
  112. if ($file->save()) {
  113. \Yii::trace("Saved $fileContentType ".$file->slug);
  114. /**
  115. * Need top fix creating thumbnail sbefore uploading to AWS
  116. */
  117. $tempFile->setAttributes([
  118. 'id' => $file->getId(),
  119. 'remote_id' => $file->remote_id,
  120. 'remote_type' => $file->remote_type
  121. ]);
  122. $tempFile->setOldAttributes($file->getAttributes());
  123. $tempFile->id = $file->id;
  124. // self::createThumbnails($file, $file->type, $file->url);
  125. $file->populateRelation('metadata', $tempFile->metadata);
  126. $ret_val[] = $file;
  127. } else {
  128. \Yii::error("Unable to save file informaiton to database for ".$file->slug."\n".json_encode($file->getErrors()));
  129. }
  130. } else {
  131. \Yii::trace("Unable to save physical file: ".$file->slug);
  132. }
  133. } else {
  134. //This file exists already lets attach it and update the thumbnails if necessary.
  135. if ($file->save()) {
  136. $ret_val[] = $file;
  137. self::createThumbnails($file, $file->type, $file->url);
  138. }
  139. }
  140. }
  141. if (!Network::isValidUrl($uploadedFile->tempName)) {
  142. unlink($uploadedFile->tempName);
  143. }
  144. }
  145. return $ret_val;
  146. }
  147. /*---------------------
  148. Protected Functions
  149. ---------------------*/
  150. /*
  151. * Get the proper directory
  152. * @param string $directory
  153. * @return string
  154. */
  155. protected static function resolveFile($directory)
  156. {
  157. $directory = ($directory[strlen($directory)-1] == DIRECTORY_SEPARATOR) ? $directory : $directory.DIRECTORY_SEPARATOR;
  158. return \Yii::getAlias($directory);
  159. }
  160. public static function getDirectory($fileContentType, $getAlias = false)
  161. {
  162. $dir = \Yii::$app->getModule('nitm-files')->getPath($fileContentType);
  163. if ($getAlias) {
  164. $dir = \Yii::getAlias($dir);
  165. }
  166. return $dir;
  167. }
  168. /*
  169. * Is this file an file?
  170. */
  171. protected static function isImage($file)
  172. {
  173. $finfo = finfo_open(FILEINFO_MIME_TYPE);
  174. return array_shift(explode('/', finfo_file($finfo, $file))) == $fileContentType;
  175. }
  176. }