Where to put a non controller or model method in a Laravel App

1.4k views Asked by At

I have a PHP Laravel app that has an Elequent Model for EmailTokenUrlLogin and a Controller to login a user by accessing a URL with a token value in the URL.

I would like to have a function that will create a new Model/DB record to generate the token for a user and be able to call this function from any other Controller or Model in my app.

Right now I have it in my Login Controller however I am not happy with this as it requires either a POST request to post all the required function parameters or else a GET request with a long complicated URL of parameters.

So I want my function below generateShortLifeEmailTokenUrl($user_id, $email, $expireType, $expireNumber = '') to live somewhere in the app in which I can call it from anywhere.

Where would a function like below best be located and how to make it callable from other models and controllers?

public function generateShortLifeEmailTokenUrl($user_id, $email, $expireType, $expireNumber = '')
{
    if(Auth::user()->isAdmin){

        // generate a new token
        // ... other logic here......

        // create model and DB record and return the created token value
        $emailTokenUrlLoginData = new EmailTokenUrlLogin;
        $emailTokenUrlLoginData->user_id = $user_id;
        $emailTokenUrlLoginData->email = $email;
        $emailTokenUrlLoginData->token = $createToken();
        $emailTokenUrlLoginData->expireType = $expireType;
        $emailTokenUrlLoginData->expireNumber = $expireNumber;
        $emailTokenUrlLoginData->save();

        // return generated token
        return $emailTokenUrlLoginData->token;            
    }

}
3

There are 3 answers

3
Alexey Mezenin On

If you're working with this function a lot, you can create global helper:

if (! function_exists('generateShortLifeEmailTokenUrl')) {
    function generateShortLifeEmailTokenUrl($user_id, $email, $expireType, $expireNumber = '')
    {
        ....
    }
}

Put it in helpers.php and add this to composer.json to load the helpers:

"autoload": {
    ....
    "files": [
        "app/someFolder/helpers.php"
    ]
},
0
LorenzSchaef On

This really depends on how sophisticated you want to your code to be.

If you really just need this in one controller action, you can just place the code there. Or you can create a private method on that controller that does the job. Advanced programmers will consider this a bad practice, but for a small application it's good enough.

Alexeys suggestion with the global function works as well, but is considered an even worse practice because it's global. If you make all your functions global, your global scope and namespace will be full of unrelated stuff that will eventually get in the way of each other. Again, for a small application you will probably be fine, though.

Now, if you're curious about what a better practice would be: the keywords are services and dependency injection. That's not something I'm going to explain right here, but there are lots of resources on the web that will help you understand how these concepts work and what the benefits are.

Laravel has built in support for depencency injection, you can read all about it in the documentation.

1
mopsyd On

Put it in a trait, and bind the trait to any other class where it is needed. You will not need to make it public that way, and can access it anywhere it is needed. Trait methods are compiled into the class as if there were native class methods, but can be overruled within the class as needed.

See: http://php.net/manual/en/language.oop5.traits.php

Trait EmailTokenTrait {
    protected function generateShortLifeEmailTokenUrl($user_id, $email, $expireType, $expireNumber = '')
{
    ...
}

Bind the trait to whatever class:

<?php
namespace \some\namespace;

class SomeClass {

    use \EmailTokenTrait;

    protected function someFunction() {
        $token = $this->generateShortLifeEmailTokenUrl($user_id, $email, $expireType);
    }
}

Then autoload the trait.

"autoload": {
    ....
    "files": [
        "app/traits/EmailTokenTrait.php"
    ]
},