user1094128
user1094128

Reputation: 461

How do I access a global model instance in laravel 4?

In Laravel 4, how do I create an instance of a model and make it globally available? Even in views. I'm looking to do something similar to the way you get the User instance using Auth::User->name (the syntax I mean, not storing in a session) but in this case it would be ModelName::DefaultEntity->attribute.

A little more detail...

I am writing an application that will house multiple websites - a bit like a CMS. So I have a Website model. Each Website model will have a URL attribute so that when a user visits the URL the application can retrieve the Website model from the database and brand the website appropriately e.g. Title, logo, theme, etc...

I would like the current Website model to be available everywhere without having to create a new instance of Website in every controller/method. So in my layouts and views I could just say something like:

{{ Website::Website()->name }}

or

{{ CurrentWebsite::name }}

I have achieved the first one by making a static method in the Website model:

public static function current()
{
    return Website::find(1); // just to test it for now
} 

But with that, it will have to do a database query every time I say:

{{ Website::current()->name }}

Plus it doesn't feel right.

Can anyone help?

Kind regards,

Robin

Upvotes: 0

Views: 1221

Answers (3)

Antonio Carlos Ribeiro
Antonio Carlos Ribeiro

Reputation: 87719

What you already have is good, but if you just want prevent that query from executing every time, you can cache it:

public static function current()
{
    return Website::remember(10)->find(1); // just to test it for now
}

Adding a listener to your routes.php:

 DB::listen(function($sql, $bindings, $time) { var_dump($sql); var_dump($bindings); });

And executing it:

{{ Website::current()->name }}

Will show the query in the first execution but not in the second, because it's cached.

Upvotes: 0

MrNomNom
MrNomNom

Reputation: 17

  1. Create normal class. Like CurrentWebsite or Website or whatever.

    class Website {
        public function a() {
          //your code
        }
     }
    
  2. Create facade (WebsiteFacade.php)

    use Illuminate\Support\Facades\Facade;
    
    class WebsiteFacade extends Facade {
    
        protected static function getFacadeAccessor() { return 'website'; }
    
    }
    
  3. Create Service Provider

        use Illuminate\Support\ServiceProvider;
    
        class WebsiteServiceProvider extends ServiceProvider {
    
        public function register()
        {
             $this->app->bind('website', function()
             {
                  return new Website();
              });
        }
        } 
    

4.Go to your config/app.php and add folowing:

 'providers' => array(
      'WebsiteServiceProvider'
 )

and

 'aliases' => array(
      'WebsiteFacade'
 )

5.Refrech auto loader. And Now you can access Website class anywhere like this:

    Website::a();

Upvotes: 1

Rob Gordijn
Rob Gordijn

Reputation: 6511

You probably are looking for 'a shared container bind'. See the docs here.

<?php
App::singleton('foo', function()
{
    return Website::whereCode('whoop')->first();
});

App::make('foo'); // every where you need it

Upvotes: 2

Related Questions