Laravel: conflict between model name and built-in facade - laravel

I have a Model in my Laravel app called Event. As I just discovered, this creates a conflict between my model and Illuminate\Support\Facades\Event, a built-in facade. The obvious solution here is to either change the name of my Model, which is not ideal because there is really no other name I could give my Model that makes any sense, or to rename the alias in app.php for Illuminate\Support\Facades\Event, which I'd like to avoid for fear of breaking anything that may rely on that alias in the future (I'm afraid I may forget).
It's been suggested that perhaps I could use namespaces, which I attempted as follows:
app/models/Event.php
namespace Models; #<-- I've also tried using "\Models" here
class Event extends \Eloquent{
app/database/seeds/DatabaseSeeder.php
Models\Event::create(); #<-- again, I've also used "\Models\Event"
All 4 combinations above have yielded a Class 'Models\Event' not found error when I run php artisan db:seed.
Perhaps I simply don't understand namespaces properly, but the more pressing issue is how to solve my problem. If it can be solved using namespaces as suggested, great, but I'm open to any other ideas as well.

I made this mistake early on as well, not necessarily understanding the role of namespace throughout the entire app.
The namespace should mark the business logic within the domain or responsibility of the app itself, so giving a namespace of Models isn't necessarily useful. Instead create a root namespace named after the app, your company, you, or whatever you like, then provide a Model sub-namespace.
For example:
namespace MyGreatApp\Models;
class Event extends \Eloquent{ }
Then you would reference this model under:
use MyGreatApp\Models\Event;
$event = new Event();
In the long run this is a cleaner and more organized approach. This does mean moving your models into a different folder, though. But there's nothing wrong with that. At least that way you know you have all your custom code in your MyGreatApp namespace. :)

Related

Customizable model file for a Laravel 5 package

I'm developing a Laravel 5 package where I have a "Member" model which currently extends App\User model. I would like to know the best practice to let any developer use a custom "Member" model instead of the one from the package. This is for example to allow a developer use another table.
One approach that seems to work without having done a deep test with it is to make an alias in my package service provider in the register() method:
$MemberModel = 'MyVendor\MyPackage\Member';
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$loader->alias('MyMember', $MemberModel);
In this case I have to:
Replace all entries in the code from the original class to the alias
Delete all php "use" entries related to it
Get the value of $MemberModel from a config file or the database
But I don't know if it is a good way to solve it or It may cause any conflict.
Is there any other and better approach for this goal? Thanks in advance!
I finally had to test by myself this approach without haven't read the solution anywhere else, but anyway everything seems to work fine in my source code.
If anyone is looking for doing anything similar, the code example in my question works because the $MemberModel is defined with a value. If you want to get that value from a Model instance, as me, you have to add that code in the boot() method of the service provider.

How do you reference a model in a laravel controller? [duplicate]

This question already has answers here:
Troubleshooting referencing a model in a laravel controller
(2 answers)
Closed 6 years ago.
I'm finding the distinction between "Controller" and "Model" in laravel 5.2 to be very blurry.
I use artisan to create a RESTful controller, and in the store method, I try to create a new object.
// store in the database
$car = new App\Models\CarModel;
Then I get the error as follows:
Class 'carfreak\Http\Controllers\App\Models\CarModel' not found
So it all seems to come down to the namespace of the controller, but I don't understand it.
The name space describes the controller, right?
So why is my reference the model, being built on the controllers path? It shouldn't have anything to do with it... right?
EDIT: After trying various suggestions, I've concluded there are three things to look at:
Each class has a namespace set, correctly describing the folder where the class is located
In the controller, have the statement "Use app\models\CarModel"
refer to the model in the controller.
Each seems to be correct, but I still get the error that it cannot find the model
This is a namespace problem in php.
You just use like this.
$car = new \App\Models\CarModel;
or
use App\Models\CarModel;
....
class {
$car = new CarModel;
}
First of all check name space in Model file , Define name space in model file
namespace App\Http\Models;
And then use
use App\Http\Models\CarModel;
Well, here it is. I solved it by asking myself this question: If I'm having so much trouble namespacing, referencing and organising my models, then maybe I can get artisan to do it for me.
The post that got me thinking differently was Mansoor Akhtar's advice here: How do I instruct artisan to save model to specific directory?
Get artisan to make the model in the right place first time.
php artisan make:model Models/CarModel
In the Controller, reference the model correctly
use name-of-app\Models\CarModel;
There may or may not be cache flushing involved in my problem. I was eventially restarting my XAMPP after every change to ensure no caching was involved. I also tried
php artisan cache:clear
You'll need to add a use statement to the top of your class.
Try:
use carfreak\Models\CarModel;
class ...
This assumes that your model is in the carfreak\Models namespace, and in a Models folder within your App / carfreak folder, otherwise you'll just need use carfreak\CarModel;.
I believe you have just ran the artisan command to create the model and you didn't move the CarModel file to Models folder. (Correct me if I'm wrong)
So in your controller add this before class declaration:
use carfreak\CarModel;
Then anywhere in your controller you can access the model like this:
$car = new CarModel;

Laravel constants in class Facades

I have a class called Awesome and have used the ServiceProvider and the Facade to register it to the app. Now I can use it as Awesome::Things().
I want to add constants to this class, so I tried
<?php namespace Helper\Awesome;
class Awesome()
{
public static $MOVIE = 'I love the Lego Movie!";
}
but when I call Awesome::$MOVIE, I get Access to undeclared static property: Helper\\Aesome\\Facades\\AwesomeFacade::$MOVIE
Can someone help?
The short version is -- you don't really want to do that. Laravel facades aren't mean to be used like normal classes, and if your application uses them that way you'll likely confuse future developers.
Warning out of the way. When you create a "facade" in Laravel, you're actually creating a class alias. When you added Awesome to the alias list in app/config/app.php, at some point code like the following ran
class_alias('Helper\Aesome\Facades\AwesomeFacade','Awesome');
That means whenever you use a global non-namespaced class Awesome, PHP substitutes Helper\Aesome\Facades\AwesomeFacade. If you wanted to add constants, you'd need to add them to this class.
Laravel's able to pass through methods because of the base Facade class implements a __callStatic method that passes on your call to the actual service implementation object. Facades don't pass on static constant access. Additionally, PHP does not (appear to?) have similar magic methods for passing along requests for constants.
If you're curious about the in depth version of this answer, I'm currently writing a series on Laravel's object system, including some in-depth information about the facade implementation.

Joomla how can i create model from other component

I'm a beginner in joomla. I create own component and would like to use model from other component (exactly contentbuilder).
I find few different ways how to create model but my problem is that
class ContentbuilderModelEdit extends JModel
use JPATH_COMPONENT_ADMINISTRATOR in it. When i create model ContentbuilderModelEdit i get warnings in lines that using JPATH_COMPONENT_ADMINISTRATOR constant.
Is it possible to create model using that constant from other component?
Thanks for your answers
Alas no. The JPATH_COMPONENT and JPATH_COMPONENT_ADMINISTRATOR are defined constants, and cannot be changed.
Sometimes the developers do this instinctively (it's easy) without realizing the kind of limitation they're putting on other developers. You might consider contacting the developers and propose such a change; if they accept, you won; if they don't, write a sed script that performs the changes (replacing it with JPATH_SITE and JPATH_ADMINISTRATOR . '/components/com_contentbuilder', and apply it after each update.
Or, copy their model into your component and rename it if it supports it.
:)
To call a model from another component you need firstly to include the path of this model:
JModelLegacy::addIncludePath(JPATH_SITE . '/components/comp1/models', 'Comp1Model');
Secondly you have to create an instance of your model:
$model = JModelLegacy::getInstance('Model1', 'Comp1Model');
After that you should be able to use the methods of your model.
ref link

No need to extend class/library in codeigniter

I would like to check if my assumption about codeigniter is right ?
We would normally extend a class when we are trying to include more functionality to the core, such as MY_Controller extends Controller, MY_Model extends Model etc...
But for example, if we are in the checkout library retrieving some checkout info(eg, product_id), we can just $this->load->library('product_lib',array('product_id'=>$product_id)) and we can easily $this->product_lib->product_name etc... from the checkout library right?
The $this->load thing is kind of equivalent to "hard code" checkout library to extend product_lib(class checkout_lib extends product_lib) to be able to use whatever methods/variables there is in the product_lib.
Please enlighten me.
In CodeIgniter $this->load is like having a resource manager (e.g. resourceManager->load("path/to/file")) and it takes care of loading the library, and passing any arguments you specify and such, easily allowing you to quickly get to using it.
So if you have a variable named product_name in your product_lib then yes calling $this->product_lib->product_name will be accessing that variable.
Really it just places the library into an array with the library name as the key and the instance of the library as the value so calling $this->product_lib is really calling something similar to $loadedLibraries['product_lib'] and returning the instance.
I hope that answers what you are asking, I'm quite tired and could have miss understood you question.
I think you misunderstood the OO paradigm and the way CI work.
$this->load is same with instantiate an object of the library/model, or load the helper file. CI have some sort of management to see if the helper/library/model already uploaded or not.
In other hand, the extends is used when defining a class, to tell PHP that the class will be inherit the parent class properties and method. A class is a blue print of object it will produce.
Maybe you can start by understanding the OO concept first. You can read this as a start, and see the reference used there.

Resources