how does a cakePHP controller have a model property built in? - php

If I have a controller as follows.
<?php
class LoginController extends AppController{
public function index(){
}
}
?>
I could access Login model as $this->Login . How does the LoginController class have access to the Login model? We did not define any property named Login in the LoginController class. How does this happen?

CakePHP will dynamically create a model object for you if it cannot
find a corresponding file in /app/Model. This also means that if you
accidentally name your file wrong (for example, post.php or posts.php
instead of Post.php), CakePHP will not recognize any of your settings
and will use the defaults instead.
Model.php, automatically selects a database table name based on a pluralized lowercase object,The table is required to have at least 'id auto_increment' primary key.
You can see for cakephp/lib/Cake/Model/Model.php

Related

Load user settings with Laravel 5.6

I'd like to be able to modify the Auth->user() data that Laravel 5.6 uses. I have table called settings with a column called user_id in it that corresponds to a user id.
I tried modifying app\User.php and adding a __construct function:
public function __construct() {
$this->settings = Settings::where('user_id',
Auth->user->id()
)->first();
}
And I created a file app\Settings.php with the following:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class settings extends Model
{
protected $table = "settings";
}
However I'm getting a user error on the Auth->user()->id line in User.php, although I'm sure thats the correct way to reference it?
How can I load the data from the settings table to the User class?
You can just use load() method to lazy load the relation:
auth()->user()->load('settings');
You need to do this just once per request, in a middleware for example. Then you'll be able to use the data in any part of your app:
{{ auth()->user()->settings->theme }}
Of course, to make this work you need to define relationship in the User model, for example:
public function settings()
{
return $this->hasOne(Settings::class);
}

Laravel on some kind of Model Ready method

Well i don't know how to format the title of this post in very clear way, but here's my question:
Say i have
Posts::find('1);
Photos:find('1');
... and so on, every mode db request
now by default i can access db columns, for instance the id: through model->id
$Photos = Photos::find('1')->first();
echo $Photos->id; // will return 1
what i want is that i need all those kind of requests to add a custom field automatically like hashed_id, which is not in the database, which in return will make all models have a hashed_id as well, i know i can add that field to database and then grab it but i need it for different reasons/implementations
i did create a BaseModel and every Model will extend that BaseModel, so Photos extends BaseModel, BaseModel extends Model... and all that etc etc.
but i need some kind of constructor, upon retrieving data to process the data automatically without having to add -let's say- a hash_id() after retrieving the data.
something like, onAfterGet(), onReady()....sort of commands.
i hope my question is clear.
Thanks.
What you're looking for is an Accessor. Accesors can be used to add custom attributes to the model. Combine this with the $appends property and you have exactly what you need. The $appends property adds the custom accessor in every result.
You can do this by creating a base model like you've stated in the question or by using traits. I'll show you an example on how to achieve this using a base model.
Let's create base model called BaseModel. All other models that need this custom attribute will extend this.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class BaseModel extends Model
{
protected $appends = ['hashed_id'];
public function getHashedIdAttribute()
{
return some_hash_function($this->id);
}
}
We have a Image model which extends our BaseModel.
<?php
namespace App;
class Image extends BaseModel
{
}
Now every result from the Image model will have the hashed_id field added by default.
Accesor documenation https://laravel.com/docs/5.4/eloquent-mutators#defining-an-accessor
If I understand you right, all you need to do is to define mutator, for example:
<?php
class Photo extends Model
{
/* ... model implementation ... */
public function getHashedIdAttribute()
{
return md5($this->id);
}
}
Then you can access property like it was in database:
echo Photo::find(5)->hashed_id;

how to create multiple models against multiple function in single controller in CakePHP

i think, In "CakePHP" one model is against each controller but i have multiple functions in single controller and each function represent different page and database table.
i.e
public function manage_categories(){}
public function manage_sub_categories(){}
above 2 functions are in Admin Controller but now the issue is how to create model against each function to represent database. each function has unique attributes in database.
One thing more either model name should be same to controller name "admin" or this name will be same as functions name. while in normal circumstances model name is same to controller name.
"Users" model name is used against "UsersController"
kindly guide me ti resolve above said issue. i tried enough to solve it bot couldn't.
Thanks in advance.
If you have two database tables it would be logical and best practice in terms of SoC to have two controllers instead of throwing a lot different things that don't belong into the same domain into a single controller.
Sometimes when you just want to use a part of data from an associated model you can access it through the associations:
$this->Model->SubModel->foo();
Also you say you have an admin controller which is a working but not very good approach. Instead CakePHP features prefix routing. So an action accessed like /admin/categories/some_action will route to the CategoriesController some_action() action.
"Users" model name is used against "UsersController"
Is wrong, by convention models should be named singular, not plural. Your UsersController won't find an Users model because it's looking for an User model.
And stay away from Model::query(), use the ORM instead as much as you can.
public function manage_categories(){}
public function manage_sub_categories(){}
Should become:
class CategoriesController extends AppController {
public function admin_index() { /*...*/ }
}
class SubCategoriesController extends AppController {
public function admin_index() { /*...*/ }
}
But assuming that sub-categories belong to a category which is the same table I don't see a need for a second model or second controller at all.

Database Table custom naming convention Laravel Eloquent

I'm trying to retrieve data from a table called completion_date using Eloquent. My Model name is Completion and as per laravel documentation, i should declare a (protected) table name or else Eloquent will use 'completions' as the default table name. So i did this declaration.
I'm getting problems with my Controller since i dont know which name to use to refer to my Model when i'm making the View. I'm getting an InvalidArgumentException that View [completion.lsz] not found. if i just use my model name to make the View.
Error:
InvalidArgumentException thrown with message "View [completion.lsz] not found."
Can someone pls help out?
Model
<?php
//Model (file name: Completion)
class Completion extends Eloquent{
protected $table = 'completion_date';
public $timestamps = false;
}
Controller
class CompletionController extends BaseController {
public function index() {
$lsz = Completion::all();
return View::make('completion.lsz', ['completion' => $lsz]);
}
}
Route
Route::get('/Completion', 'CompletionController#index');
View names in Laravel work like a path. The . gets converted to a /
That means, your view resolves to the file app/views/completion/lsz.blade.php (or app/views/completion/lsz.php without Blade)
So you either have to change the name of your directory in the views folder to "completion" or change the view make command to:
View::make('lsz.lsz', ['completion' => $lsz]);
The error message says that the view file completion/lsz.blade.php was not found.
It's not related to the model or database.

Laravel 4 BadMethodCallException upon calling a method of a model

I created a User class in Laravel application as follows:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
...
public function hasAnyRoles()
{
return true;
}
The function there is simplified to always return true for the purposes of this example. I pretty much followed this tutorial here to create this class: http://alexsears.com/article/adding-roles-to-laravel-users. I created a controller next as follows:
class WelcomeController extends Controller
{
public function welcomeAction()
{
$user = User::find(Auth::user()->id);
$result = $user->hasAnyRoles();
return Response::make("Result: ".$result);
}
}
I'm able to successfully login to the system, routes are working as intended, the variable $user is correctly initialized and I can get all the information out of it (username, id, email, etc.) but once I call the $user->hasAnyRoles() method I get:
BadMethodCallException
Call to undefined method Illuminate\Database\Query\Builder::hasAnyRoles()
If I comment out the respective line in the controller it all works but I cannot call any method of that model without getting that error. Any ideas why this is happening?
As stupid as it is, it turns out that the application was reading the User class from a different file. I had a User_backup.php copied in the same directory just in case and this was the file that the class was read from so any changes to User.php were disregarded. I had to remove the backup file and do a composer update in order to get it all working correctly..

Categories