marcosdipaolo's avatar

General methods and a method accepting instances of different possible models as parameter

Sorry for the blury title. This is the thing:

1st question: If a build a model that is useful for all controllers, where should I place it?. For ex. the method public function uploadImg(). Many controllers need to upload an image, so it s a method which is useful for the whole app, not a certain controller.

2nd question: If that method might be useful for upload images, it would surely need a instance of an object to store the image's urls at the right row and table, e.g. Post $post, or User $user.

If I'm consistent enough to let all models with an img column share the same image columns names at the table, say "img_url" and "thumb_ur" for thumbnails, is it posible to receive as a parameter a variable that might contain instances of different models? for example this code below (notice I'm using several methods that are not to be found in this snippet, and also the "Intervention Image" library):

<?php
public static function uploadImg($model_Instance, Request $request, $width, $prefix) 
    {
        if ($request->hasFile('image')) {
            $model_Instance->deleteImg($hero);
            $ext = $request->image->extension();
            $now = time();
            $photo_path = "/img/{$prefix}/" . "{$prefix}_" . Post::slug($request->title) . "_" . $now . "." .$ext;
            $thumb_path = "/img/{$prefix}/thumbs/" . "{$prefix}thumb_" . Post::slug($request->title) . "_" . $now . "." .$ext;
            $foto = \Image::make($request->image);
            $thumb = \Image::make($request->image)->resize(150, NULL, function($c){
                $c->aspectRatio();
                $c->upSize();
            });
            if ($foto->width() > $width) {
                $foto->resize($width, NULL, function($constraint){
                $constraint->aspectRatio();
                });
            }

            $foto->save(storage_path('app/public') . $photo_path);
            $thumb->save(storage_path('app/public') . $thumb_path);
        }
        else {
                     
            $photo_path = $model_Instance->img ?? NULL;
            $thumb_path = $model_Instance->thumb ?? NULL;
        }
        return ['photo_path' => $photo_path , 'thumb_path' => $thumb_path];
    }

This is a desperate try to make this code reusable instead of copying the whole method into two different models

0 likes
3 replies
Snapey's avatar

Well im going to stop you there whilst you confirm that you have considered spatie media library and ruled it out.

It makes adding media handling as easy as adding a trait to any model.

As regards the general principle of adding services that are useful to the application as a whole, then service provider classes are commonly used, but its easy enough to add classes in any folder you like

1 like
marcosdipaolo's avatar

Oh!!, thanks a lot @Snapey I will surely check out that library!. unfortunately this project is almost finished, I'll stick with the intervention image for this one. Have you tried it? http://image.intervention.io/

And what about 2nd question? can a method receive as a parameter a variable $model_instance which can be an instance of different models depending where nd what you're calling it for?

Snapey's avatar
Snapey
Best Answer
Level 122

spatie library uses intervention also. its not about image manipulation its about creating a single model for all images and then attaching those images to the relevant model

Yes you can pass a model into this code, but a better approach might be a trait on the model that can then just use $this to reference the model

1 like

Please or to participate in this conversation.