converting string class name to an object in laravel - php

i have this trait which i want to use dependency injection
<?php
namespace App\Http\Controllers\Admin;
trait ControllerTrait{
public function index($this->model $payroll){
return $this->model->paginate(20);
}
}
the controller which uses this trait
namespace App\Http\Controllers\Admin;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Payroll;
class PayrollController extends Controller
{
use ControllerTrait;
public $model = "Payroll";
}
$model now is a string how to convert it to an object in calling index method of the trait

I don't believe dynamic type-hinting is possible, nor is it necessary in this instance.
I imagine this is what you're looking for.
namespace App\Http\Controllers\Admin;
trait ControllerTrait{
public function index() {
return ('\App\\'.$this->model)::paginate(20);
}
}

You can use "call_user_func" function which can call function in your model.
public $model = "Payroll";
call_user_func($model . "::index");
Hope this will help.

I think you can use it as a string in php
$controllerClassName = 'TODOS\CONTROLLERS\\' . ucfirst($this->_controller) . 'Controller';
which is a string and i used it to create instances
$controller = new $controllerClassName();

Related

Method in trait not able to be called from controller

I'm trying to use a trait to handle image upload on my Laravel application, but none of the functions in my Trait can be called from the controller.
It throws a BadMethodCallException and says that the function couldn't be found.
I've tried using really simple functions to test if it is a problem with the trait or whether the function itself has an issue, but even a simple return function that only contains
return "sampletext";
has the same issue.
The path of the trait is under App/Traits/UploadTrait
and I've already checked the spelling on the use statement in my controller, which says use App\Traits\UploadTrait;
namespace App\Traits;
trait UploadTrait
{
public function test(){
return "testtext";
}
}
And the controller has
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use App\User;
use App\Profile;
use App\Traits\UploadTrait;
use Image;
class UserProfileController extends Controller
{
...
protection function updateProfile($args, Request $request){
...
return $this->test();
...
Of course I expect the function in my trait to be called, but this does not happen.
You need to use the trait inside your controller and move the $this->test() inside a class function:
<?php
use App\Traits\UploadTrait;
class UserProfileController extends Controller
{
use UploadTrait; // <-- Added this here
public function index()
{
return $this->test(); // <-- Moved this into a function
}
}
You have to put the use keyword to use that trait and its methods in the class
trait UploadTrait
{
public function test(){
return "testtext";
}
}
class Controller{
}
class UserProfileController extends Controller
{
use UploadTrait;
}
$ob = new UserProfileController();
echo $ob->test();
You can make a function to and call the trait function.
More Details
Use trait inside the class like:
use my/path/abcTrait;
Class My class{
use abcTrait;
}
Now, you can call trait functions with $this->functionName () in functions.

Accessing method in another namespace

I'm trying to, from my controller, access a method in a model that is in another namespace and the only way I could do this was to make the method static. Is this the right way to do it, or is there any neater approach?
PagesController.php (controller):
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Helpers\ConnectedHost;
class PagesController extends Controller
{
/*
* REMOVED CODE HERE FOR READABILITY
* Below is where I instantiate the "connectedHost"-object
*/
$hosts[$hostKey] = new ConnectedHost($hostAttributes['ipv4'], $hostAttributes['mac']);
}
/* REMOVED CODE HERE FOR READABILITY AS WELL */
ConnectedHost.php (helper-file):
namespace App\Helpers;
class ConnectedHost
{
public $ipv4, $mac;
public function __construct($ipv4, $mac)
{
$this->ipv4 = $ipv4;
$this->mac = $mac;
// This is where I call the getName-function staticly,
$this->name = \App\Host::getName();
}
}
Host.php (model):
namespace App;
use Illuminate\Database\Eloquent\Model;
class Host extends Model
{
// The method below is declared static
public static function getName()
{
$name = 'wenzzzel';
return $name;
}
}
If you are directly accessing the method from model like
$data = \App\ModelName::methodName();
Then your method should be static.
if your method is not static you can access like,
$model = new \App\ModelName();
$data = $model->methodName();

PHP/Laravel - How to initiate a class with it's dependencies in a trait

I would like to use a method from a class that I have in one trait. The class that I need looks like this:
namespace App\Http\Controllers;
use App\Libraries\Content\ContentInterface;
use Illuminate\Http\Request;
use App\Http\Requests;
use Corcel\Post;
use EllipseSynergie\ApiResponse\Laravel\Response;
use App\Transformers\IndexTransformer;
class ImportController extends Controller
{
private $indexable;
function __construct(Response $response, ContentInterface $contentInterface)
{
$this->indexable = \Config::get('middleton.wp.content.indexable_types');
$this->response = $response;
$this->contentInterface = $contentInterface;
}
public function updateOrCreateInventory($remoteId)
{
$this->contentInterface->updateOrCreateInventory($remoteId);
}
}
I would like to use the updateOrCreateInventory method in a trait that I have or to be more specific in it's method :
namespace App\Libraries\Content;
use App\Inventory;
use GuzzleHttp\Client;
use App\Http\Controllers\ImportController;
trait SupplementaryFormatter
{
private static function getInventoryUrl($id)
{
if (is_numeric($id)) {
$inventory = Inventory::where('remote_id', $id)->first();
if(!$inventory) {
ImportController::updateOrCreateInventory($id);
} else {
return '/' . $inventory->url;
}
}
return $id;
}
}
But, I am not sure how can I initiate the class in the trait with it's dependencies, because when I import the Response and ContentInterface class to a trait and try to pass it to the constructor of the ImportController class, like so:
(new ImportController(new Response, new ImportController))->updateOrCreateInventory($id);
I get an error that I am not passing dependencies to Response and ImportController. How can I make this work?
Have you tried to use app()->make()?
If not, try it:
if(!$inventory) {
$controller = app()->make(ImportController::class);
$controller->updateOrCreateInventory($id);
} else {
return '/' . $inventory->url;
}
Also, I don't think you are doing it in the right way. I think you should move the function updateOrCreateInventory to some service and in your trait create a instance of this service.

Call the UI function in controller class in laravel

UI Code: in resources\views\DistributorRegistration.php
<?php
class DistributorRegitrationForm
{
public function distributorRegitrationFormHtml(){
return '<h1>Hello</h1>';
}
}
?>
In Controler Class.....
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use resources\views\DistributorRegistration;
class DistributorRegistration extends Controller
{
function VestigePOS_GRNHandler(Request $request){
$id = $request->input('id');
return view(DistributorRegitrationForm::distributorRegitrationFormHtml()) ;
}
}
When I call this controller in routes
Fatal error: Class 'App\Http\Controllers\DistributorRegitrationForm' not found
Which file contains the class DistributorRegitrationForm? I'm missing an use App\...\DistributorRegitrationForm; in the controller, if it's not in the same namespace.
Calling DistributorRegitrationForm::distributorRegitrationFormHtml() won't work, unless the method becomes a static method (public static function).
You have some typos in there ;-)

Laravel, namespaces and PSR-4

I'm trying to set up PSR-4 within a new Laravel 4 application, but I'm getting some troubles achieving what I want when it comes to build controllers.
Here's what I have now :
namespace MyApp\Controllers\Domain;
class DomainController extends \BaseController {
public $layout = 'layouts.default';
public function home() {
$this->layout->content = \View::make('domain.home');
}
}
I'm not so fond of using \View, \Config, \Whatever to use Laravel's classes. So I was wondering if I could put a use Illuminate\View; to be able to use View::make without putting a \.
Unfortunately, while doing this, I'm getting the following error : Class 'Illuminate\View' not found.
Could somebody help with this please ?
The problem in your case is that View is not located in Illuminate namespace but in Illuminate\View namespace, so correct import would be not:
use Illuminate\View;
but
use Illuminate\View\View;
You can look at http://laravel.com/api/4.2/ to find out which namespace is correct for class you want to use
Assuming BaseController.php has a namespace of MyApp\Controllers\Domain
namespace MyApp\Controllers\Domain;
use View;
class DomainController extends BaseController {
public $layout = 'layouts.default';
public function home() {
$this->layout->content = View::make('domain.home');
}
}
If BaseController.php has other namespace, i.e MyApp\Controllers
namespace MyApp\Controllers\Domain;
use MyApp\Controllers\BaseController;
use View;
class DomainController extends BaseController {
public $layout = 'layouts.default';
public function home() {
$this->layout->content = View::make('domain.home');
}
}
If, for instance, you controller needs to use another base class from Laravel, lets say Config.
namespace MyApp\Controllers\Domain;
use MyApp\Controllers\BaseController;
use View;
use Config;
class DomainController extends BaseController {
public $layout = 'layouts.default';
public function home() {
$this->layout->content = View::make('domain.home')->withName(Config::get('site.name'));
}
}
The use of View::make() takes advantage of the Laravel facades. To properly reference the facade, instead of directly referencing the class that gets resolved out of the iOC container, I would use the following:
use Illuminate\Support\Facades\View;
This will reference the View facade that is being used when calling View::make()

Categories