You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
5.6 KiB

  1. <?php
  2. namespace App\Models;
  3. use App\Models\File;
  4. use App\Models\Model;
  5. use App\Models\SoftDeletes;
  6. use App\Models\ReportableRelation;
  7. use Illuminate\Validation\Rule;
  8. use Illuminate\Http\UploadedFile;
  9. use Spatie\MediaLibrary\HasMedia;
  10. use Spatie\MediaLibrary\InteractsWithMedia;
  11. use Spatie\MediaLibrary\MediaCollections\Models\Media;
  12. class Project extends Model implements HasMedia
  13. {
  14. use SoftDeletes,
  15. InteractsWithMedia;
  16. const CONVERSION_NAME = 'avatar';
  17. const COLLECTION_NAME = 'avatars';
  18. public static $permissions = ['level'];
  19. protected $table = 'projects';
  20. protected $fillable = [
  21. 'business_id', 'name', 'slug', 'private', 'budget', 'color', 'active', 'description', 'has_avatar', 'start', 'finish','members'
  22. ];
  23. protected $reportable = [
  24. 'business_id', 'name', 'slug', ['members' => 'project_user']
  25. ];
  26. protected $fillable_relations = ['members'];
  27. public $detach_relation = false;
  28. public function rules()
  29. {
  30. return [
  31. 'name' => 'required|string|min:2|max:225',
  32. 'slug' => ['required', 'string', 'min:2', 'max:225',
  33. Rule::unique($this->table, 'slug')
  34. ->where('business_id', request('business_id'))
  35. ->whereNull('deleted_at')
  36. ->ignore($this->id)],
  37. 'order' => 'nullable|numeric|min:0',
  38. 'private' => 'nullable|boolean',
  39. 'color' => 'nullable|string|min:2|max:255',
  40. 'active' => 'nullable|boolean',
  41. 'description' => 'nullable|string|min:2|max:1000',
  42. // 'members' => empty($this->id) ? '' : 'required|array'
  43. ];
  44. }
  45. protected $casts = [
  46. 'private' => 'boolean',
  47. 'start' => 'date',
  48. 'finish' => 'date',
  49. 'has_avatar' => 'boolean',
  50. ];
  51. public function getValueOf(?string $key)
  52. {
  53. $values = [
  54. 'business_id' => $this->business_id,
  55. 'project_id' => $this->id,
  56. 'sprint_id' => null,
  57. 'workflow_id' => null,
  58. 'status_id' => null,
  59. 'system_id' => null,
  60. 'actor_id' => auth()->id(),
  61. 'user_id' => null,
  62. 'task_id' => null,
  63. 'subject_id' => $this->id,
  64. ];
  65. if ($key && isset($values, $key)) {
  66. return $values[$key];
  67. }
  68. return $values;
  69. }
  70. public function members()
  71. {
  72. $permissions = self::$permissions;
  73. return $this->belongsToMany(
  74. User::class, 'project_user', 'project_id', 'user_id',
  75. 'id', 'id', __FUNCTION__
  76. )->using(ReportableRelation::class)
  77. ->withPivot($permissions);
  78. }
  79. public function tasks()
  80. {
  81. return $this->hasMany(Task::class, 'project_id', 'id');
  82. }
  83. public function business()
  84. {
  85. return $this->belongsTo(Business::class, 'business_id', 'id');
  86. }
  87. public function systems()
  88. {
  89. return $this->hasMany(System::class, 'project_id', 'id');
  90. }
  91. public function sprints()
  92. {
  93. return $this->hasMany(Sprint::class, 'project_id', 'id');
  94. }
  95. public function files()
  96. {
  97. return $this->hasMany(File::class, 'user_id', 'id');
  98. }
  99. public function updateRelations()
  100. {
  101. // members
  102. // if (!empty($this->filled_relations['members']) || $this->detach_relation) {
  103. // $this->dirties['members'] = $this->members()->sync($this->filled_relations['members'], $this->detach_relation);
  104. // }
  105. }
  106. public function reportActivity()
  107. {
  108. // foreach ($this->dirties as $name => $value) {
  109. // return \post('task', 'task/v1/log', [
  110. // 'user_id' => Auth::id(),
  111. // 'business_id' => $this->business_id,
  112. // 'loggable_id' => $this->id,
  113. // 'loggable_type' => $this->getTypeId(),
  114. // 'action' => $this->getAction(), // id of the action
  115. // 'data' => [$name => [
  116. // 'original' => $value['original'],
  117. // 'diff' => $value['diff'],
  118. // ]],
  119. // ]);
  120. // }
  121. }
  122. public function getPermissions($user_id)
  123. {
  124. return $this->members->where('id',$user_id)->first();
  125. }
  126. public function registerMediaCollections(): void
  127. {
  128. $this->addMediaCollection(static::COLLECTION_NAME)
  129. ->acceptsMimeTypes([
  130. 'image/jpeg',
  131. 'image/png',
  132. 'image/tiff',
  133. 'image/gif',
  134. ])
  135. ->useDisk('public')
  136. ->singleFile();
  137. }
  138. public function registerMediaConversions(Media $media = null): void
  139. {
  140. $this->addMediaConversion(static::CONVERSION_NAME)
  141. ->width(200)
  142. ->height(200)
  143. ->queued()
  144. ->nonOptimized()
  145. ->performOnCollections(static::COLLECTION_NAME);
  146. }
  147. public function saveAsAvatar(UploadedFile $avatar): void
  148. {
  149. $this->addMedia($avatar)->toMediaCollection(static::COLLECTION_NAME);
  150. $this->update([
  151. 'has_avatar' => true,
  152. ]);
  153. @unlink($this->getFirstMedia(static::COLLECTION_NAME)->getPath());
  154. }
  155. public function deleteAvatar(): void
  156. {
  157. $path = $this->getFirstMedia(static::COLLECTION_NAME)->getPath();
  158. $this->getFirstMedia(static::COLLECTION_NAME)->delete();
  159. $this->update([
  160. 'has_avatar' => false,
  161. ]);
  162. @unlink($path);
  163. }
  164. public function getAvatarUrl(): ?string
  165. {
  166. if ($url = $this->getFirstMediaUrl(static::COLLECTION_NAME, static::CONVERSION_NAME)) {
  167. return $url;
  168. }
  169. return null;
  170. }
  171. }