I'm using Instagram API library to connect user to Instagram profile and then do smth with it. So, as Instagram API wiki says:
Once you have initialized the InstagramAPI class, you must login to an account.
$ig = new \InstagramAPI\Instagram();
$ig->login($username, $password); // Will resume if a previous session exists.
I have initialized InstagramAPI class and then I called $ig->login('username', 'password');. But I have to call it in every function where I need to work with Instagram.
So how could I save this object $ig for using it in the future in other controllers without calling login() any more? Can I save $ig object into the session or cookie file?
P.S. I think saving into the session is not safe way to solve the issue.
UPD: I was trying to save $ig object into the session, however the size is large and session become stop working as well.
Regarding the register method you asked in the comments section, all you need to create a new service provider class in your app\providers directory and declare the register method in there for example:
namespace App\Providers;
use InstagramAPI\Instagram;
use Illuminate\Support\ServiceProvider;
class InstagramServiceProvider extends ServiceProvider
{
public function register()
{
// Use singleton because, always you need the same instance
$this->app->singleton(Instagram::class, function ($app) {
return new Instagram();
});
}
}
Then, add your newly created InstagramServiceProvider class in providers array inside the config/app.php file for example:
'providers' => [
// Other ...
App\Providers\InstagramServiceProvider::class,
]
Now on, in any controller class, whenever you need the Instagram instance, all you need to call the App::make('InstagramAPI\Instagram') or simply call the global function app('InstagramAPI\Instagram') or even you can typehint the class in any method/constructor etc. Some examples:
$ig = App::make('InstagramAPI\Instagram');
$ig = App::make(Instagram::class); // if has use statement at the top fo the class
$ig = app('...');
In a class method as a dependency:
public function someMethod(Instagram $ig)
{
// You can use $ig here
}
Hope this helps but read the documentation properly, there will get everything documented.
Related
whenever we call a Facade Method it involves Facade design pattern and it called for some hidden class by using Facade. for instance for File, if we call
File::get(public_path().'test.txt');
this will call the method in class
Illuminate\Filesystem\Filesystem
and in this class we will have get($path) method.
Now my question is how Facade Abstract Class is related to File and Filesystem and where Laravel is telling them to call get in Filesystem. is there some kind of register which i am missing ?? i want to find complete link.
If you go in your config/app.php, you will notice that there's an array called aliases which looks like this
'aliases' => [
//
//
//
//
'File' => Illuminate\Support\Facades\File::class,
];
So, basically whenever you call File, the Service Container will try to resolve an instance of Illuminate\Support\Facades\File::class which is just a Facade.
If you look into Illuminate\Support\Facades\File::class, you will see that it contains only one method:
class File extends Facade
{
/**
* Get the registered name of the component.
*
* #return string
*/
protected static function getFacadeAccessor()
{
return 'files';
}
}
As you can see, it extends the Facade class and whenever a Facade is being resolved, Laravel will try to find a key in the Service Container that is equal to whatever is returned by getFacadeAccessor().
If you check the source of Illuminate\Filesystem\FilesystemServiceProvider, you will see this:
$this->app->singleton('files', function () {
return new Filesystem;
});
As you can see, the key files is being bounded to a FileSystem implementation. So, that's how Laravel knows how to resolve the File facade.
I'm writing a web app using Laravel 5.6. I need a list of all the connections the current session user have, in all the views.
I tried something like this
View::share('connections', Connection::getList(Auth::id()))
I put this code inside the boot function of AppServiceProvider. But the problem arises when the user isn't already logged in, because at that time Auth::id() is set to null.
The connection list is not generated when the user logs in. This throws the following error:
connections variable is not defined.
This target can achieve through different method,
1. Using BaseController
The way I like to set things up, I make a BaseController class that extends Laravel’s own Controller, and set up various global things there. All other controllers then extend from BaseController rather than Laravel’s Controller.
class BaseController extends Controller
{
public function __construct()
{
//its just a dummy data object.
$user = User::all();
// Sharing is caring
View::share('user', $user);
}
}
2. Using Filter
If you know for a fact that you want something set up for views on every request throughout the entire application, you can also do it via a filter that runs before the request — this is how I deal with the User object in Laravel.
App::before(function($request)
{
// Set up global user object for views
View::share('user', User::all());
});
OR
You can define your own filter
Route::filter('user-filter', function() {
View::share('user', User::all());
});
and call it through simple filter calling.
Update According to Version 5.*
3. Using View Composer
View Composer also help to bind specific data to view in different ways. You can directly bind variable to specific view or to all views. For Example you can create your own directory to store your view composer file according to requirement. and these view composer file through Service provide interact with view.
View composer method can use different way, First example can look alike:
You could create an App\Http\ViewComposers directory.
Service Provider
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
public function boot() {
view()->composer("ViewName","App\Http\ViewComposers\TestViewComposer");
}
}
After that, add this provider to config/app.php under "providers" section.
TestViewComposer
namespace App\Http\ViewComposers;
use Illuminate\Contracts\View\View;
class TestViewComposer {
public function compose(View $view) {
$view->with('ViewComposerTestVariable', "Calling with View Composer Provider");
}
}
ViewName.blade.php
Here you are... {{$ViewComposerTestVariable}}
This method could help for only specific View. But if you want trigger ViewComposer to all views, we have to apply this single change to ServiceProvider.
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
public function boot() {
view()->composer('*',"App\Http\ViewComposers\TestViewComposer");
}
}
Reference
Is it possible to share and change some variable between multiple views? For example, I want to have a variable $user that will be shared between all views. When a user logs the variable is set up, when the user logs out, the variable is unset. I was unable to achieve requested using
the following combination:
in AppServiceProvider:
view()->share('var', 1);
in the controller:
$var = view()->shared('var');.
$var ++;
view()->share('var', var);
return view(''', 'var'=>$var)
Every time when the page is reloaded $var is always the same (2).
I want to have a variable $user that will be shared between all views
You should use auth()->user() to get authenticated user instance in any view.
But if you don't want to use it for some reason, you could share the variable between multiple views with a view composer.
share() method will be useful only if you want to share a variable with all views. To make it work, put view()->share('key', 'value') to the boot() method of a service provider.
Also, the code in your controller looks like you want to share data not between views, but between requests. Use session for that.
To save the data:
session(['key' => 'value']);
To get the data in another request:
session('key');
It would be better to add another service provider. Take a look at my provider:
<?php
namespace App\Providers;
use Request;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider
{
public function boot()
{
$this->globalThings();
//call another globals' function here
}
public function register()
{
//
}
/**
* Get the golbals
*/
private function globalThings()
{
view()->composer(array('*.*'),function($view){
//get the data however you want it!
$view->with('global', Model::where('field','value')->get());
});
}
And don't forget to add the service provider to list of provider is config/app.php
App\Providers\ViewComposerServiceProvider::class,
I see from the CakePHP 3.2 documentation that to configure a session I need to use write(), so I tried that in my controller like this:
use App\Controller\AppController;
use Cake\Core\Configure;
class RatingsController extends AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Paginator');
Configure::write('Session', ['defaults' => 'php']);
}
}
But this doesn't seem to set up a $_SESSION array if executed in my controller.
I thought I had a workaround by setting up Auth, and thereby was able to access $_SESSION, but then when I open the controller by adding $this->Auth->allow(); to the init above, the session variable no longer exists.
Where do I need to configure Cake to start a session?
CakePHP binds sessions to the Request, e.g. set a value to a key in your Controller:
$this->request->session()->write('defaults', 'php')
Then, e.g. in your Template read the Session by key:
$this->request->session()->read('defaults')
My basic aim is to extend the package class and override a method in it.
I have used Fnatte's ans as a reference : How to extend laravel 4 core?
Sentry2 is a package that i am using for authentication in larval 4.
A user can be logged in using Sentry::login($credentials)
I want to override the login method of the Sentry package and remove the check for activating the user(i have commented it in the code below)
public function login(UserInterface $user, $remember = false)
{
#prevent throwing error if not activated !
// if ( ! $user->isActivated())
// {
// $login = $user->getLogin();
// throw new UserNotActivatedException("Cannot login user [$login] as they are not activated.");
// }
$this->user = $user;
// Create an array of data to persist to the session and / or cookie
$toPersist = array($user->getId(), $user->getPersistCode());
// Set sessions
$this->session->put($toPersist);
if ($remember)
{
$this->cookie->forever($toPersist);
}
// The user model can attach any handlers
// to the "recordLogin" event.
$user->recordLogin();
}
Steps i have done till now :
1. Created a app/lib folder and added my extension class CustomSentry in it.
2. Added the app/lib folder to composer.json class map
app/lib/CustomSentry.php :
use Cartalyst\Sentry\Sentry;
use Cartalyst\Sentry\Users\UserInterface;
class CustomSentry extends Sentry{
public function login(UserInterface $user, $remember = false){
$this->user = $user;
// Create an array of data to persist to the session and / or cookie
$toPersist = array($user->getId(), $user->getPersistCode());
// Set sessions
$this->session->put($toPersist);
if ($remember)
{
$this->cookie->forever($toPersist);
}
// The user model can attach any handlers
// to the "recordLogin" event.
$user->recordLogin();
}
}
4. Created a service provider app/lib/CustomSentryServiceProvider
use Cartalyst\Sentry\SentryServiceProvider
class CustomSentryServiceProvider extends SentryServiceProvider{
//What should i put it here?
}
5. Register the service provider in app/config/app.php
'CustomSentryServiceProvider'
6. Use it as :
Sentry::login($credentials);
Well i figured out the answer to the question.
The better way to extend the class would be to use the same name. Since i am already using namespacing it would help reduce the confusion.
Assuming my apps name is MyApp i will only need to replace:
Cartalyst\Sentry
by:
MyApp\Cartalyst\Sentry
the rest of the SentryService provider can be copied as it is.
Then i can call the login method the normal way
Sentry::login($credentials)
I have doubts, because you have to copy whole package/Sentry. Did you tried to extend the Sentry class? This this the best way to do what you want to achieve.