Using Laravel Facades with UserFrosting - php

Have recently starting using UserFrosting to as part of a project and I'm having some problems using Facades within UserFrosting and would appreciate some help if possible.
I am attempting to use the File facade from within a UserFrosting controller to create a folder on the local filesystem using the following code
use Illuminate\Support\Facades\File;
......
$directoryCreated = File::makeDirectory($directoryPath);
However at runtime i get the following error
PHP Fatal error: Call to a member function makeDirectory() on null in /var/www/test-app/userfrosting/vendor/illuminate/support/Facades/Facade.php on line 210
It seems that the UserFrosting app does not recognise the File facade (or any other facacde - i also tried Storage) and it has not been registered with the app.
Is it possible to use the facade classes with UserFrosting?
If so do I have to register them somewhere within the UserFrosting app config?
Any direction pointers would be greatly appreciated.
Thanks in advance!

From the Facade documentation:
Laravel "facades" serve as "static proxies" to underlying classes in the service container...
So, it looks like Laravel's facades depend on Laravel's service container. You can read more about how Laravel sets up the default facades here: https://www.sitepoint.com/how-laravel-facades-work-and-how-to-use-them-elsewhere/#how-laravel-aliases-the-facades
Unfortunately, UserFrosting does not use Laravel's service container. Rather, it uses Slim, which has its own service container. In Slim v2 (which UF 0.3.1 uses), the Slim application itself is the service container.
You can define services for UF in initialize.php. So, you might try something like:
$app->filesystem = new \Illuminate\Filesystem\Filesystem();
Then later, you can use the filesystem service like:
$app->filesystem->makeDirectory($directoryPath);

You could try to use Slim's container to allow the Facade to resolve its accessor (it will use array access on the container to resolve it). You would have to make sure that the binding the facade uses exists. You can take a look at the Service Provider that corresponds to the service you want to use to know how its setting up the binding.
The File facade is accessing the binding 'files' (Illuminate\Filesystem\Filesystem).
\Illuminate\Support\Facades\Facade::setFacadeApplication($container);
\Illuminate\Support\Facades\File::makeDirectory(...);
Its worth a shot, but its mostly the binding that is being resolved that is important.

Related

Laravel Binding Service Provider Concept

Im currently learning how laravel framework builded and came to service provider section. in class DatabaseServiceProvider which extends ServiceProvider class i see this line of code :
$this->app->singleton('db.factory', function ($app)
{
return new ConnectionFactory($app);
});
im confuse what is app in $this->app, whether app is an object from application class instance and if it does when it is instantiated so it can be used from DatabaseServiceProvider class since i dont see its instantiation process. thnks before for answering this newbie question.
In Laravel, the app variable is a service container. Think of it like a heart of the framework. Everything you use from Facades to DB connections is stored in there.
Moreover, you can store your own objects in the container by using the method you specified ($this->app->singleton()). There are actualy many more ways to interact with the container. The best way to research this is to look into Laravel's documentation (Laravel Service Container)
The app object is being instantiated on Laravel bootstrap so you can't see it in the service provider. Though I was curious enough to dig deep into the framework to find it. The class itself is located in Illuminate\Foundation\Application and is instantiated in bootstrap/app.php.

Where to Place My Package in Lumen Framework

If I want to use some custom class in Lumen, where should I place them? The Laravel official document does not mention this in any of application structure, service container or package development. Actually I found the document quite confusing to some extents.
For example, I want to set up a service called Invitation, I know I need to register this class in InvitationServiceProvider but where should I place the Invitation.php which the actual class exists in? This package is used for some specific application thus I do not want to put it in composer packagist.
BTW, the version of Lumen Framework is 5.2.
So finally I created a folder named Service under app and just pull all the libraries inside...

Extending of Symfony container

is it possible overwrite/extend Symfony\Component\DependencyInjection\Container::get() method? I want automatic creating service, when it is not contain in container, but class of service exists.
For example:
Name of service is My.MyBundle.Model.FooRepository
Service with this name doesnt exists, but when i call:
$container->get('My.MyBundle.Model.FooRepository');
check class_exists for \My\MyBundle\Model\FooRepository and when its exists, add to container and return it. Dependencies of this new services will be resolve by kutny/autowiring-bundle.
This feature can be extended only for some namespaces or interfaces and in production enviroment can be cached, but for developing will be great helper.
Any idea?
This is not directly answering your question but maybe it's answering your need: if you want to have "auto-wiring" inside your Symfony project, you can use PHP-DI inside Symfony. PHP-DI is an alternative container that can do auto-wiring (which Symfony does not).
Have a look at the Symfony 2 integration documentation to see if it can fit your bill.

Dependency injection in a symfony console command? Not full Symfony application

I've seen this How can i inject dependencies to Symfony Console commands? but that answer doesn't really give enough information and is already explained here http://symfony.com/doc/current/cookbook/console/console_command.html
The problem is a containerAwareCommand doesn't work with the setup here http://symfony.com/doc/current/components/console/introduction.html
In order to use containerAwareCommand from what I can tell, I need my application to use
Symfony\Bundle\FrameworkBundle\Console\Application
instead of
Symfony\Component\Console\Application
But using the frameworkBundle Application class requires an instance of KernelInterface and won't allow me to pass in a name and version to my application.
Here is what I have that won't work with containerAwareCommands
#!/usr/bin/env php
<?php
require __DIR__.'/../src/vendor/autoload.php';
$app = new Symfony\Component\Console\Application('spud', '0.0.1');
$app->add(new Isimmons\Spudster\Console\Commands\SayHelloCommand);
$app->run();
The command it's self runs but I get an error when trying to use getContainer
Call to undefined method Symfony\Component\Console\Application::getKernel()
On a related topic which will probably come up next, The documentation for registering a class in the container shows using a app/config/config.php file. But I don't have an app directory since this is not a full symfony application. My base directory in which all of the app except for the file above is located, is src/lib. If I can figure out the first part above, will symfony be able to find the config file at src/lib/config/config.php?
You can use Consolefull application.
Consolefull is a simple library to work with Symfony Console Component and Symfony Dependency Injection Component

Advice needed for Laravel 4 project structure

I'm quite new to Laravel 4 (Laravel is my first PHP MVC framework) and need a little help structuring my project.
1/ I need to include the the json-rpc classes found here jsonrpcphp.org in my project and am not quite sure the best place to put these.
2/ Where is the best place to do my initial setup/connection to my data source? Should this be inside of my controller or should this be placed elsewhere?
require_once 'jsonRPCClient.php';
$connection = new jsonRPCClient('http://user:password#127.0.0.1');
I think and pretty sure the best way to do it is to create a Service
Put anywhere securely and can be easily accessed via composer. Look into how add autoloading to composer http://getcomposer.org/doc/01-basic-usage.md#autoloading
as I said, create a service. look into Laravel IoC Container http://laravel.com/docs/ioc and How to define Service Provider
see example: DatabaseServiceProvider
Related: optional for nice syntax create a Facade for it.

Categories