Class 'App\Model\Users' not found in Codeigniter4 - php

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()');
}
}

Related

Call to undefined method CodeIgniter\Database\MySQLi\Connection::like()

I have i like query in my model but it doesn't work
Model:
<?php namespace App\Models;
use CodeIgniter\Model;
class SearchModel extends Model
{
protected $table = 'sport_tbl';
protected $primaryKey = 'id';
protected $returnType = 'array';
public function search($word)
{
$this->db->like('title', $word);
$res = $this->db->get('sport_tbl')->result_array();
return $res;
}
}
Controller:
<?php namespace App\Controllers\api;
use App\Controllers\BaseController;
use App\Models\SearchModel;
class Search extends BaseController
{
public function index()
{
$searchModel = new SearchModel();
$data['allnews'] = $searchModel->search('test');
return view('welcome_message', $data);
}
}
And this is error:
Call to undefined method CodeIgniter\Database\MySQLi\Connection::like()
You are basically using the old query builder style from Codeigniter 3 instead of Codeigniter 4.
In Codeigniter 4 your code should look like this.
<?php namespace App\Models;
use CodeIgniter\Model;
class SearchModel extends Model
{
protected $table = 'sport_tbl';
protected $primaryKey = 'id';
protected $returnType = 'array';
public function search($word)
{
$db = \Config\Database::connect();
$builder = $db->table('sport_tbl');
$builder->like('title', $word);
return $builder->get()->getResultArray();
}
}
In this case your controller should be just the same.
However there's another way of doing the same without creating a new database object and using the same one that is being automatically created for you.
<?php namespace App\Models;
use CodeIgniter\Model;
class SearchModel extends Model
{
protected $table = 'sport_tbl';
protected $primaryKey = 'id';
protected $returnType = 'array';
public function search($word)
{
$this->like('title', $word);
return $builder->get()->getResultArray();
}
}
In this case your controller should be a bit different:
<?php namespace App\Controllers\api;
use App\Controllers\BaseController;
use App\Models\SearchModel;
class Search extends BaseController
{
public function index()
{
$searchModel = new SearchModel();
$data['allnews'] = $searchModel->search('test')->getAll();
return view('welcome_message', $data);
}
}
The second version of the code is actually better because that way your can have as many functions you want in your model and then just call them in a chain statement always returning $this.

CodeIgniter 4 Models preloading

I am new to PHP OOP and CodeIgniter and I need help. I am using CodeIgniter 4 and trying to preload model logas_model in BaseController.php:
<?php
namespace App\Controllers;
/**
* Class BaseController
*
* BaseController provides a convenient place for loading components
* and performing functions that are needed by all your controllers.
* Extend this class in any new controllers:
* class Home extends BaseController
*
* For security be sure to declare any new methods as protected or private.
*
* #package CodeIgniter
*/
use App\Models\Admin\logas_model;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class BaseController extends Controller
{
/**
* An array of helpers to be loaded automatically upon
* class instantiation. These helpers will be available
* to all other controllers that extend BaseController.
*
* #var array
*/
protected $helpers = ['form', 'session', 'html', 'number'];
protected $logas;
/**
* Constructor.
*/
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
//--------------------------------------------------------------------
// Preload any models, libraries, etc, here.
//--------------------------------------------------------------------
///$this->session = \Config\Services::session();
$this->logas = new logas_model();
}
}
Model logas_model code:
<?php namespace App\Models\Admin;
use CodeIgniter\Model;
use Config\Services;
class logas_model extends Model
{
protected $table = 'veiksmai_logs';
protected $primaryKey = 'id';
protected $returnType = 'array';
protected $useSoftDeletes = true;
protected $useTimestamps = TRUE;
protected $createdField = 'created_at';
protected $updatedField = 'updated_at';
protected $deletedField = 'deleted_at';
protected $allowedFields = ['uid', 'veiksmas'];
public function get_all_veiksmai()
{
return $this->select("CONCAT(`user`.`vardas`, ' ', `user`.`pavarde`) AS `user_vardas_pavarde`, `veiksmai_logs`.`veiksmas`, `veiksmai_logs`.`created_at`, `veiksmai_logs`.`id`")
->join('user', 'user.id = veiksmai_logs.uid')
->orderBy("`veiksmai_logs`.`created_at`", 'DESC')
->findAll();
}
public function add_veiksmas($veiksmas)
{
$session = Services::session()->get();
$data = [
'uid' => $session['uid'],
'veiksmas' => $veiksmas
];
return $this->insert($data);
}
}
And then, in other controller, which extends Controller, I am trying to use that preloaded model by using it's function like this:
$this->logas->add_veiksmas('Created User.');
Full that Controller code:
<?php namespace App\Controllers\Admin;
use App\Models\Admin\vartotojai_model;
use CodeIgniter\Controller;
class Vartotojai extends Controller
{
private $vartotojai;
public function __construct()
{
$this->vartotojai = new vartotojai_model();
}
public function index()
{
$this->logas->add_veiksmas('Created User.');
$this->data['vartotojai'] = $this->vartotojai->get_all_vartotojai();
echo view('templates/Admin/Header', ['title' => 'Vartotojai']);
echo view('Admin/Vartotojai/Index', $this->data);
echo view('templates/Admin/Footer');
}
}
But it is not working.
What am I doing wrong?
Change Controller
class Vartotojai extends Controller
{
into BaseController
class Vartotojai extends BaseController
That may be because you have not extended BaseController to Vartotojai controller.
class Vartotojai extends BaseController
Please try this.
Kindly note: whenever you are preloading(Models, helpers, libraries e.t.c), you need to extend the BaseController on all the controllers that will be using that model.In your case you preloaded the model correctly but you did not extend your controller to the BaseController. Use the below format in your controllers:
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
class ClassName extends BaseController
{
//your functions and code
}
?>

Dynamic type-hint in Laravel for Form Request

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);
}
}

laravel 5.4 - return post exact model in eloquent model

I have a Post model and two TextPost and PhotoPost models extending from it.
I want to do something like Post::find(1); and if the record with id=1 have type=photo attribute, it should return me an instance of PhotoPost model otherwise should be an instance of TextPost model. how can do this in laravel 5.4? my classes are as below:
Post.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $fillable = ['file_id', 'file', 'bot_id', 'text'];
public function bot()
{
return $this->belongsTo(Bot::class);
}
}
TextPost.php
namespace App;
use App\Traits\TextPostTrait;
class TextPost extends Post
{
use TextPostTrait;
protected $table = 'posts';
protected $fillable = ['bot_id', 'text'];
protected $attributes = ['type' => 'text'];
}
PhotoPost.php
namespace App;
use App\Traits\PhotoPostTrait;
class PhotoPost extends Post
{
use PhotoPostTrait;
protected $table = 'posts';
protected $attributes = ['type' => 'photo', 'image_watermark'];
}
PhotoPostTrait.php
namespace App\Traits;
use App\Scopes\PhotoPostScope;
trait PhotoPostTrait
{
public static function bootPhotoPostTrait()
{
static::addGlobalScope(new PhotoPostScope());
}
}
TextPostTrait.php
namespace App\Traits;
use App\Scopes\TextPostScope;
trait TextPostTrait
{
public static function bootSettingsTrait()
{
static::addGlobalScope(new TextPostScope());
}
}
TextPostScope.php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\ScopeInterface;
class TextPostScope implements ScopeInterface
{
public function apply(Builder $builder, Model $model)
{
$builder->where('type', 'text');
}
public function remove(Builder $builder, Model $model)
{
}
}
PhotoPostTrait.php
namespace App\Scopes;
use \Illuminate\Database\Eloquent\Model;
use \Illuminate\Database\Eloquent\Builder;
use \Illuminate\Database\Eloquent\Scope;
class PhotoPostScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
$builder->where('type', '=', 'photo');
}
public function remove(Builder $builder, Model $model)
{
}
}
so I use globalScopes to categorize my post types. so basically I store them in a single table. so I should add the $table='posts'; so that laravel does not take it as a seperate model. and using traits to boot the scope. and inside the scopes I will make sure the record is a Photo or a Text.
EDIT
I found a solution by JarekTkaczyk at https://laracasts.com/discuss/channels/eloquent/multiple-models-to-same-table
But I want to know does laravel a native solution for this problem?

Multiple construct functions

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;
}

Categories