I'm trying to initizalize a couple of helper classes into my laravel controller only problem is I have 3 things to initialize but only one constructor message for exmaple:
<?php
use UG\Validation\Forms\Login as LoginForm;
class SessionsController extends \BaseController {
protected $loginForm;
public function __construct(LoginForm $loginForm)
{
$this->loginForm = $loginForm;
}
That is to help validate the forms but now I also want to add a repository to help me with keeping eloquent out of my controller
<?php
use UG\Repositories\User as User;
class SessionsController extends \BaseController {
protected $user;
public function __construct(User $user)
{
$this->user = $user;
}
now the problem Im facing is that both these methods need to go in my controller but I only have one _construct method. So how would I go about this
Just put both classes in the constructor:
class SessionsController extends \BaseController {
protected $user;
protected $loginForm;
public function __construct(User $user, LoginForm $loginForm)
{
$this->user = $user;
$this->loginForm = $loginForm;
}
Related
I've created a Base Controller and I want to dynamically type-hint the store method to use the proper Form Request class. How can I do that?
Here's my base controller (simplified):
class BaseController extends Controller
{
protected $baseClass;
protected $baseResourceClass;
protected $baseStoreRequestClass;
public function index()
{
$items = $baseClass::paginate(10);
return $baseResourceClass::collection($items);
}
// the $baseStoreRequestClass doesn't work, and that's what I'm trying to figure it out
public function store(**$baseStoreRequestClass** $request)
{
$validatedFields = $request->validated();
$newItem = $baseClass::create($validatedFields);
return new $baseResourceClass($newItem);
}
}
Then, from the controller that will extend, I would have just to declare the 3 variables. Example:
class UserController extends BaseController
{
protected $baseClass = '\App\User';
protected $baseResourceClass = '\App\Http\Resources\UserResource';
protected $baseStoreRequestClass = '\App\Http\Requests\StoreUser';
}
class ProductController extends BaseController
{
protected $baseClass = '\App\Product';
protected $baseResourceClass = '\App\Http\Resources\roductResource';
protected $baseStoreRequestClass = '\App\Http\Requests\StoreProduct';
}
How could I make the $baseStoreRequestClass works?
You can't specify a dynamic type as a function parameter. It's just not valid PHP syntax. Here's what I suggest. Your base class would be the boilerplate:
class BaseController extends Controller
{
protected $baseClass;
protected $baseResourceClass;
public function index()
{
$items = $baseClass::paginate(10);
return $baseResourceClass::collection($items);
}
public function store(FormRequest $request) // Or other base request object you might create
{
$validatedFields = $request->validated();
$newItem = $baseClass::create($validatedFields);
return new $baseResourceClass($newItem);
}
}
Then each subclassed controller would need an explicit request type:
class UserController extends BaseController
{
protected $baseClass = '\App\User';
protected $baseResourceClass = '\App\Http\Resources\UserResource';
public function store(StoreUser $request) {
return parent::store($request);
}
}
I am working with the latest version of codeigniter framework. Something is wrong with my code, it gives me an error like:
Class 'App\Model\Users' not found
Controller
Filename: Auth.php
<?php
namespace App\Controllers;
use CodeIgniter\RESTful\ResourceController;
use App\Model\Users as CodeIgniterUsers;
class Auth extends ResourceController
{
public function login()
{
$model = new CodeIgniterUsers();
var_dump($model);
}
public function register()
{ }
}
Model
File name: Users.php
<?php
namespace App\Model;
use CodeIgniter\Model;
class Users extends Model
{
protected $db;
protected $table = 'user';
protected $returnType = 'array';
protected $allowedFields = ['name', 'email', 'password'];
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
}
If you haven't change your directory names in app, you need to change namespaces from App\Model\Users (without "s" at the end) to App\Model\User.
Namespaces should follow directory structure, unless you change (or extends) CI4's core classes or at least app/Config/Autoload.php
Extends your model with CI_Model for it will be recognized .
class Auth_model extends CI_Model {
//you can always put function construct
public function __construct (){
parent::__construct ();
}
}
In controller :
class User extends CI_Controller {
public function __construct () {
parent:: __construct();
//you can load here the model that you will just often so will load it everytime to use it in a function
$this->load->auth_model('model-name(exam- public function test_uer()');
}
}
I have some problem and little misunderstanding Laravel SP (ServiceProvider). I have abstract class Repository and her Interface:
abstract class Repository implements RepositoryInterface {
private $model;
private $parser;
public function __construct() {
$this->model = new $this->model_name();
} }
interface RepositoryInterface {
public function create(array $attributes);
public function update($id, array $attributes);
public function delete($id);
public function all();
public function find($id);
public function filter(array $parameters, $query=null);
public function query(array $parameters, $query=null); }
and some child UserRepository for example:
class UserRepository extends Repository implements UserRepositoryInterface {
protected $model_name = "App\Models\User";
public function __construct() {
parent::__construct();
}
public function activation($user_id) {
return "user";
}
public function deactivation($user_id) {
return "user";
} }
and simple ModelParser class:
class ModelParser {
protected $parameters;
protected $model;
public function __construct($model) {
$this->model = $model;
} }
This work fine, but I would pass ModelParser as DI in my construct of abstract Repository with parameter $model. I dont have idea. How should I do it ?
I use it like this:
class UserController extends Controller {
private $repository;
public function __construct(UserRepository $repository) {
$this->repository = $repository;
} }
Well it's kinda complicated since your ModelParser requires a $model as it's parameter. And because this $model may vary depends on its repository, it will be too complicated if we're trying to resolve it using Laravel service container binding.
There's an easier approach, we can make the ModelParser class's constructor receive an optional $model parameter. Then we can add an additional method to set this $model property like so:
namespace App\Models;
class ModelParser
{
protected $parameters;
protected $model;
// Make $model parameter optional by providing default value.
public function __construct($model = null) {
$this->model = $model;
}
// Add setter method for $model.
public function setModel($model)
{
$this->model = $model;
return $this;
}
}
And now you can inject the ModelParser into your abstract Repository class. Laravel will easily resolve this ModelParser parameter
namespace App\Models;
use App\Models\ModelParser;
use App\Models\RepositoryInterface;
abstract class Repository implements RepositoryInterface
{
private $model;
private $parser;
// Pass ModelParser instance to your constructor!
public function __construct(ModelParser $parser)
{
$this->model = new $this->model_name();
// Set the parser's model property.
$this->parser = $parser->setModel($this->model);
}
// Rest of your code.
}
And if you're extending the abstract Repository class, you still have to pass this ModelParser to the constructor like so:
namespace App\Models;
use App\Models\ModelParser;
use App\Models\UserRepositoryInterface;
class UserRepository extends Repository implements UserRepositoryInterface
{
protected $model_name = "App\Models\User";
public function __construct(ModelParser $parser)
{
parent::__construct($parser);
}
}
Actually, if you're not planning to pass another parameter or perform something else during the class instantiation, you can simply remove the __construct() method from UserRepository and rely on its parent (the abstract Repository).
Hope this help!
I have a base controller which injects a User model in it's constructor:
class BaseController extends Controller {
public $user;
public function __construct(User $user) {
$this->user = $user;
View::share('user', $this->user);
}
AuthController extends the BaseController
class AuthController extends BaseController {
public function __construct(LDAP $ldap, User $user) {
parent::__construct($user);
$this->ldap = $ldap;
$this->user->setUsername('Username'); //This is not being called
}
How can I access the injected model from the parent controller and call methods on it?
If I use $this->user->setUsername('Username'); from the BaseController the method is called correctly, but not from the child controller.
so i am new in Laravel.
I want to use repository pattern, and here my problem:
here is my interface:
namespace Repositories\User;
interface IUserRepository
{
public function getAllUsers();
}
here my class:
namespace Repositories\User;
use models\User;
class UserRepository implements IUserRepository
{
public function getAllUsers()
{
return User::all();
}
}
here my controller:
class UserController extends \BaseController {
protected $user;
public function __contruct(IUserRepository $user)
{
$this->user = $user;
}
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
$users = $this->user->getAllUsers();
return View::make('index');
}
}
i register it in boostrap\start.php
App::bind('Repositories\User\IUserRepository', 'Repositories\User\UserRepository');
i think it can run smooth but it is a result i get :( :
Call to a member function getAllUsers() on a non-object
$users = $this->user->getAllUsers();
So why? :(( Thanks for helping!
If you infect that repo, then use namespace:
public function __contruct(Repositories\User\IUserRepository $user)
{
$this->user = $user;
}