diff --git a/database/migrations/phinx/20241021194747_embiggen_mime_type.php b/database/migrations/phinx/20241021194747_embiggen_mime_type.php new file mode 100644 index 0000000000..44c79c535d --- /dev/null +++ b/database/migrations/phinx/20241021194747_embiggen_mime_type.php @@ -0,0 +1,17 @@ +table('media') + ->changeColumn('mime', 'string', ['limit' => 128]) + ->update(); + } + + public function down() + { + } +} diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php index 39ca7bf843..471283b23e 100644 --- a/resources/lang/en/validation.php +++ b/resources/lang/en/validation.php @@ -33,6 +33,7 @@ 'role_cannot_be_empty' => 'The role list must be NULL or an array with at least 1 role', 'tag_field_type_cannot_be_private' => 'Tag fields cannot be private.', 'tag_field_must_be_array' => 'Incorrect format for tags property.', + 'media_field_must_be_array' => 'Incorrect format for media property.', 'field_required' => ':field is required', 'array' => ':field must be an array', 'integer' => ':field must be an integer', diff --git a/src/Ushahidi/Modules/V3/Validator/Media/Create.php b/src/Ushahidi/Modules/V3/Validator/Media/Create.php index c8d154d248..4ca941cb0c 100644 --- a/src/Ushahidi/Modules/V3/Validator/Media/Create.php +++ b/src/Ushahidi/Modules/V3/Validator/Media/Create.php @@ -69,8 +69,8 @@ public function validateMime($validation, $mime) if (!$mime) { $validation->error('mime', 'mime_not_empty'); - } elseif (!in_array($mime, $allowed_mime_types)) { - $validation->error('mime', 'mime_type_not_allowed'); - } + } //elseif (!in_array($mime, $allowed_mime_types)) { + // $validation->error('mime', 'mime_type_not_allowed'); + // } } } diff --git a/src/Ushahidi/Modules/V5/Actions/Media/Handlers/CreateMediaCommandHandler.php b/src/Ushahidi/Modules/V5/Actions/Media/Handlers/CreateMediaCommandHandler.php index 859619d988..55283a7962 100644 --- a/src/Ushahidi/Modules/V5/Actions/Media/Handlers/CreateMediaCommandHandler.php +++ b/src/Ushahidi/Modules/V5/Actions/Media/Handlers/CreateMediaCommandHandler.php @@ -35,7 +35,7 @@ protected function isSupported(Command $command) public function __invoke(Action $action) { $this->isSupported($action); - $this->validateFileData($action->getMediaEntity()); + // $this->validateFileData($action->getMediaEntity()); return $this->media_repository->create($action->getMediaEntity()); } diff --git a/src/Ushahidi/Modules/V5/Actions/Post/Handlers/AbstractPostCommandHandler.php b/src/Ushahidi/Modules/V5/Actions/Post/Handlers/AbstractPostCommandHandler.php index da33bc4dd8..35bd1d30d2 100644 --- a/src/Ushahidi/Modules/V5/Actions/Post/Handlers/AbstractPostCommandHandler.php +++ b/src/Ushahidi/Modules/V5/Actions/Post/Handlers/AbstractPostCommandHandler.php @@ -32,6 +32,7 @@ protected function savePostValues(Post $post, array $post_content, int $post_id) { $errors = []; $post->valuesPostTag()->delete(); + $post->valuesMedia()->delete(); foreach ($post_content as $stage) { if (!isset($stage['fields'])) { continue; @@ -40,7 +41,7 @@ protected function savePostValues(Post $post, array $post_content, int $post_id) $for_delete = false; $type = $field['type']; if (!isset($field['value'])) { - if ($type === 'tags') { + if ($type === 'tags' || $type === 'media') { continue; } $for_delete = true; @@ -50,22 +51,22 @@ protected function savePostValues(Post $post, array $post_content, int $post_id) // The reason is when a field value input is updated and then left empty (as long it's not required) // the user wants to override the existing input value with an empty value. if (!isset($field['value']['value'])) { - if ($type === 'tags') { + if ($type === 'tags' || $type === 'media') { continue; } $for_delete = true; } - - if ($type === 'tags') { - // To Do : delete the tags $type === 'tags' ? 'tag' : $type; $this->savePostTags($post, $field['id'], $field['value']['value']); continue; } - + if ($type === 'media') { + $this->savePostMedia($post, $field['id'], $field['value']['value']); + continue; + } $class_name = "Ushahidi\Modules\V5\Models\PostValues\Post" . ucfirst($type); if (!class_exists($class_name) && @@ -170,6 +171,22 @@ protected function savePostValues(Post $post, array $post_content, int $post_id) return $errors; } + protected function savePostMedia($post, $attr_id, $media) + { + if (!is_array($media)) { + throw new \Exception("$attr_id: media format is invalid."); + } + foreach ($media as $media_id) { + $post->valuesMedia()->create( + [ + 'post_id' => $post->id, + 'form_attribute_id' => $attr_id, + 'value' => $media_id + ] + ); + } + } + protected function savePostTags($post, $attr_id, $tags) { diff --git a/src/Ushahidi/Modules/V5/Http/Resources/MediaCollection.php b/src/Ushahidi/Modules/V5/Http/Resources/MediaCollection.php new file mode 100644 index 0000000000..5cd9f25044 --- /dev/null +++ b/src/Ushahidi/Modules/V5/Http/Resources/MediaCollection.php @@ -0,0 +1,32 @@ +collection; + } + + public function count() + { + return count($this->collection); + } +} diff --git a/src/Ushahidi/Modules/V5/Http/Resources/MediaResource.php b/src/Ushahidi/Modules/V5/Http/Resources/MediaResource.php new file mode 100644 index 0000000000..264ebdbaff --- /dev/null +++ b/src/Ushahidi/Modules/V5/Http/Resources/MediaResource.php @@ -0,0 +1,26 @@ + $this->id, + 'media_id' => $this->value, + ]; + } +} diff --git a/src/Ushahidi/Modules/V5/Http/Resources/PostValueCollection.php b/src/Ushahidi/Modules/V5/Http/Resources/PostValueCollection.php index 622113fb18..4189735b29 100644 --- a/src/Ushahidi/Modules/V5/Http/Resources/PostValueCollection.php +++ b/src/Ushahidi/Modules/V5/Http/Resources/PostValueCollection.php @@ -59,12 +59,14 @@ public function toArray($request) return $value->form_attribute_id == $field['id']; })->values(); - if ($field['type'] !== 'tags') { - $field['value'] = $field['value']->first(); - } else { + if ($field['type'] === 'tags') { $field['options'] = $field['options'] ? new CategoryCollection($field_obj->options) : $field['options']; + } elseif ($field['type'] === 'media') { + $field['value'] = $this->makeMediaValue($field['value']); + } else { + $field['value'] = $field['value']->first(); } if (!empty($field['value'])) { @@ -73,6 +75,8 @@ public function toArray($request) $field['value'] = $field['value']->toArray($field['value']); } elseif ($field['type'] === 'tags') { $field['value'] = $this->makeCategoryValue($field['value']); + } elseif ($field['type'] === 'media') { + $field['value'] = $field['value']->toArray($field['value']); } else { $field['value'] = $this->makeValue($field['value']); } @@ -114,6 +118,13 @@ private function makeCategoryValue($value) }); } + private function makeMediaValue($values) + { + return $values->map(function ($item, $key) { + return $item->getOriginal(); + }); + } + private function convertBooleanTaskValues($Task) { } diff --git a/src/Ushahidi/Modules/V5/Models/Media.php b/src/Ushahidi/Modules/V5/Models/Media.php index 721627533f..3d5be7ee38 100644 --- a/src/Ushahidi/Modules/V5/Models/Media.php +++ b/src/Ushahidi/Modules/V5/Models/Media.php @@ -80,9 +80,9 @@ function ($attribute, $value, $fail) { ]; if (!$value) { return $fail(trans('validation.mime_not_empty')); - } elseif (!in_array($value, $allowed_mime_types)) { - return $fail(trans('validation.mime_type_not_allowed')); - } + } //elseif (!in_array($value, $allowed_mime_types)) { + // return $fail(trans('validation.mime_type_not_allowed')); + // } } ], diff --git a/src/Ushahidi/Modules/V5/Models/Post/Post.php b/src/Ushahidi/Modules/V5/Models/Post/Post.php index 400a185e68..053661ef1f 100644 --- a/src/Ushahidi/Modules/V5/Models/Post/Post.php +++ b/src/Ushahidi/Modules/V5/Models/Post/Post.php @@ -435,8 +435,10 @@ function ($attribute, $value, $fail) { 'post_content.*.fields.*.type' => [ function ($attribute, $value, $fail) { $get_value = RequestFacade::input(str_replace('.type', '.value.value', $attribute)); - if ($value === 'tags' && !is_array($get_value)) { + if ($value === 'tags' && !is_array($get_value)) { return $fail(trans('validation.tag_field_must_be_array')); + } elseif ($value === 'media' && !is_array($get_value)) { + return $fail(trans('validation.media_field_must_be_array')); } } ], diff --git a/src/Ushahidi/Modules/V5/Models/PostValues/PostMedia.php b/src/Ushahidi/Modules/V5/Models/PostValues/PostMedia.php index 90c49da371..f2f753c9bf 100644 --- a/src/Ushahidi/Modules/V5/Models/PostValues/PostMedia.php +++ b/src/Ushahidi/Modules/V5/Models/PostValues/PostMedia.php @@ -5,11 +5,30 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; +use Ushahidi\Modules\V5\Models\Helpers\HideTime; class PostMedia extends PostValue { public $table = 'post_media'; + /** + * The attributes that should be mutated to dates. + * + * @var array + */ + protected $dates = [ + 'created', + ]; + + /** + * @var array + */ + protected $fillable = [ + 'post_id', + 'form_attribute_id', + 'value' + ]; + /** * Get the error messages for the defined validation rules. * @@ -18,7 +37,7 @@ class PostMedia extends PostValue public function validationMessages() { return []; - }//end validationMessages() + } /** * Return all validation rules @@ -27,12 +46,30 @@ public function validationMessages() */ public function getRules() { - $rules = [ - 'value' => [ - 'numeric', - Rule::exists('media', 'id') - ], + return [ + 'post_id' => 'required|exists:posts,id', + 'value' => 'required|exists:media,id', + 'form_attribute_id' => 'required|exists:form_attribute,id' ]; - return array_merge(parent::getRules(), $rules); - }//end getRules() -}//end class + } + public function attribute() + { + return $this->hasOne('Ushahidi\Modules\V5\Models\Attribute', 'id', 'form_attribute_id'); + } + + public function media() + { + return $this->hasOne('Ushahidi\Modules\V5\Models\Media', 'id', 'value'); + } + + public function post() + { + return $this->hasOne('Ushahidi\Modules\V5\Models\Post\Post', 'id', 'post_id'); + } + + public function getCreatedAttribute($value) + { + $time = HideTime::hideTime($value, $this->survey ? $this->survey->hide_time : true); + return self::makeDate($time); + } +} diff --git a/src/Ushahidi/Modules/V5/Requests/PostRequest.php b/src/Ushahidi/Modules/V5/Requests/PostRequest.php index 0b94bfabd0..18a36a238c 100644 --- a/src/Ushahidi/Modules/V5/Requests/PostRequest.php +++ b/src/Ushahidi/Modules/V5/Requests/PostRequest.php @@ -93,8 +93,10 @@ function ($attribute, $value, $fail) { 'post_content.*.fields.*.type' => [ function ($attribute, $value, $fail) { $get_value = RequestFacade::input(str_replace('.type', '.value.value', $attribute)); - if ($value === 'tags' && !is_array($get_value)) { + if ($value === 'tags' && !is_array($get_value)) { return $fail(trans('validation.tag_field_must_be_array')); + } elseif ($value === 'media' && !is_array($get_value)) { + return $fail(trans('validation.media_field_must_be_array')); } } ], diff --git a/src/Ushahidi/Modules/V5/Requests/SurveyRequest.php b/src/Ushahidi/Modules/V5/Requests/SurveyRequest.php index 43ad1e91aa..4bcc98a5e6 100644 --- a/src/Ushahidi/Modules/V5/Requests/SurveyRequest.php +++ b/src/Ushahidi/Modules/V5/Requests/SurveyRequest.php @@ -157,13 +157,13 @@ public function messages() 'validation.regex', ['field' => trans('fields.tasks.fields.response_private')] ), - + // 'tasks.*.fields.*.response_private' => [ // @TODO add this custom validator for canMakePrivate // [[$this, 'canMakePrivate'], [':value', $type]] // ] - + 'base_language.max' => trans( 'validation.max', [ @@ -173,7 +173,7 @@ public function messages() ) ]; } - + private function postMethodRules() { return [ @@ -237,6 +237,9 @@ private function postMethodRules() 'number', 'relation', 'upload', + 'image', + 'audio', + 'document', 'video', 'markdown', 'tags', diff --git a/tests/Integration/v5/posts/posts.v5.feature b/tests/Integration/v5/posts/posts.v5.feature index 02f4153f11..0fbd392e1c 100644 --- a/tests/Integration/v5/posts/posts.v5.feature +++ b/tests/Integration/v5/posts/posts.v5.feature @@ -136,7 +136,7 @@ Feature: Testing the Posts API "id": 14, "type": "media", "value": { - "value": null + "value": [null] } }, { @@ -391,7 +391,7 @@ Feature: Testing the Posts API "id": 14, "type": "media", "value": { - "value": null + "value": [null] } } ], @@ -618,7 +618,7 @@ Feature: Testing the Posts API "id": 14, "type": "media", "value": { - "value": null + "value": [null] } } ],