Best practice to modular programming in Laravel 5+ - laravel-5

I'm starting a new project and I want to reuse some parts of it, mainly the stuff related to user registration and authentication. I can copy and paste all of the code but I want to use again. I know there is Package Development in Laravel but it's not easy and feel like there must be a better way.
Some days ago I find a pingpong/modules but I don't know about it. It's third party plugin and don't trust it.
Use this plugin is true? Is this plugin is updated later? What's different between Embedd Package Laravel and pingpong/modules? or Do you have any suggestion?

Pingpong modules seems to be build for the earlier version of Laravel 5 and in how far they are compatible with future versions (and maybe current 5.1.11) I cannot say.
There isn't much activity going look the commit history for 2.1, as of today(18 dec) the last commit was over 6 months ago.
But is the package specifically designed for Laravel? It seems to. They offer a bunch of features which are useful for development. The only unfortunate thing is you get a LOT of code within your own git environment (is it a good thing? I don't know, what do you prefer).
Personally I don't like it in this way for development, I prefer them in the vendor/ folder else it's a pain to update it to newer a version.
Since Laravel 5 Taylor wanted to make package development not too specific anymore, like in Laravel 4. The only thing what you can do (but not have to) to make your package using Laravel is using the ServiceProvider's. The ServiceProvider is the bootstrap into the Laravel application.
If you want to extend or implement your own functionality, fork the repo and build it yourself on top off it and host it (through github/packagist or a private repo using Satis).
Pingpong modules (2.1) is build for Laravel 5 and they you described (Embedded Laravel Package) is more for Laravel 4, because the more specific way you have to write the package.
But, there is alternative?
Whenever you want a more active project/package for development you should tryout Asgard CMS. They are pretty modular and I thought I read somewhere it was inspired by this package (totally not sure).
How about building yourself?
Of course you can build your own packages to achieve the same result. And create it as modular as you want. I created a lot modules for my company and we can create pretty easy a entire system and using and extending/overriding modules. Even small parts from a module can be overwritten to project specific needs.
We have chosen for almost the same structure as the app/ folder which Laravel projects, in case of CMS/API modules.
A packages look like:
tests/
src/
Acme/
Controllers/
Requests/
Models/
Module.php // contains some specifc calculations for example
ModelServiceProvider.php
composer.json
In the composer.json file we autoload: "Module\\": "src/"
And in the config/app.php we register the ModuleServiceProvider. Now we injected the functionality into Laravel's container and can we use it through the app() instance.
But whenever we only want to use the Models with in another project or standalone, we can still use it because the autoloaded features from composer and the way we build the package. Possible to use:
<?php
require_once __DIR__ .'/vendor/autoload.php';
use Module\Models\Module;
$module = new Module;
Edit
The package structure we like to use, to have a section for API or CMS stuff:
tests/
src/
Cms/
Controllers/
Requests/
Api/
Controllers/
Transformers/
Models/
Module.php // contains some specifc calculations for example
Providers/
CmsServiceProvider.php // includes `ModuleServiceProvider`
ApiServiceProvider.php // includes `ModuleServiceProvider`
ModuleServiceProvider.php // contains global stuff like commands etc.
composer.json
and instead of registering ModuleServiceProvider in config/app.php we register the ApiServiceProvider or CmsServiceProvider depending on the wishes of the client/project.

To reuse your classes simply use php namespaces or use to call back your clases.
Using the namespace
namespace Acme\Tools;
class Foo
{
echo "me";
}
You can the call class foo
<?php
$foo = new \Acme\Tools\Foo();
Using Use.
You can also use use Statement as below :
<?php
use \Acme\Tools\Foo;
$foo = new Foo();
Use Middleware
You should also use middleware to filter who should use the scripts ie the Auth middle-ware , which will help you in filtering users , registrations , logins READ MORE http://laravel.com/docs/5.1/middleware
Use Eloquent
Use ORM to create REST apis to your models , its very simple , always let your controller class extend eloquent use Illuminate\Database\Eloquent\Model; ie as :
use Illuminate\Database\Eloquent\Model; .Read More http://laravel.com/docs/5.1/eloquent
Lastly Use Laravel In built Helper functions
There are numerous Laravel In built Helper functions , to use simply go over the documentation to help you

I've used pingpong modules. It a pretty cool package. I'm not sure if it's updated much. But it's a very simple package. The only thing it does is create a folder with almost the same structure as in the app folder + views. But these are modules. You can reuse it if you program them right. The same goes for the other answer from jimmy if you have a good structure you can reuse anything.
EDIT
In the image below you'll see an example of pingpong modules. As you it's pretty much the same structure as the app folder. Maybe more the root folder. Normally it runs start.php and you have a routes.php file int he Http folder. I customized mine a bit. And load the frontend and backend routes within the RouteServiceProvider. This is build with laravel 5.1.

Related

How to use Laravel facades (Cache, Log, Storage) in package outside Laravel

Please point out any naivete or incorrect assumptions I'm making about Laravel, Composer, PHPUnit, etc.
I had a class called SpeechToTextHelper that was inside a Laravel project, and it used facades like this:
use Cache;
use Log;
use Storage;
Then, since I wanted to share it between multiple Laravel projects, I moved it into a separate repo and required it (into the first project) as a dependency via Composer.
The code all seems to run fine.
My question is different from Using Laravel Facades outside Laravel
What I want to know is:
Now that I also want to write PHPUnit tests for SpeechToTextHelper in my new tools repo, I see errors like RuntimeException: A facade root has not been set. and Error: Class 'Log' not found, presumably because this tools repo has no awareness of Laravel. I guess this means my production code has been working just by side-effect.
In my new tools repo (where my SpeechToTextHelper now is), how am I supposed to indicate (maybe somewhere in composer.json?) that the code will only work if Laravel's facades exist and are initiated properly?
How can I fix my separate repo's code so that its tests can run and also so that it ensures that it can only be "required" by a Laravel project?
P.S. https://laravel.com/docs/5.7/facades says "When building a third-party package that interacts with Laravel, it's better to inject Laravel contracts (https://laravel.com/docs/5.7/contracts) [which live in their own GitHub repository] instead of using facades." "If you are building a package, you should strongly consider using contracts since they will be easier to test in a package context."
But I do not see contracts for Log or Storage at all.
I think you are looking for Laravel component repositories
Cache - This component shows how to use Laravel's Cache features in non-Laravel applications.
Log - This component shows how to use Laravel's Log features in non-Laravel applications.
This video shows, how you can use eloquent outside laravel, I think that will give you better idea.
I'm not positive that this is the best approach, so I'd love if others
would provide better answers.
For production code
My composer.json still has this in the "require" section: "laravel/framework": "5.7.*",.
I plan to only ever require this tools library from within a Laravel app. I'm not sure that this is the right way to make that a rule, but my production code at least seems to be working.
For tests
As for tests, what seems to have been necessary was to add these files from https://github.com/laravel/laravel/tree/2a1f3761e89df690190e9f50a6b4ac5ebb8b35a3:
app/Console/Kernel.php
app/Providers/AppServiceProvider.php
app/Providers/AuthServiceProvider.php
app/Providers/EventServiceProvider.php
app/Providers/RouteServiceProvider.php
bootstrap/cache/.gitignore
bootstrap/app.php
bootstrap/autoload.php
config/app.php
config/database.php
config/logging.php
config/view.php
storage/logs/laravel.log
tests/CreatesApplication.php
tests/TestCase.php
Perhaps those are the minimum set of barebones Laravel files without which tests can't run.
Then I made sure that each test class extended tests/TestCase.php. And I adjusted the namespaces.

Laravel 5 namespaces

I just downloaded Laravel 5 and started migrating to it. However, I find the required use of namespaces really annoying.
I don't feel like I am getting much from it, other than cluttering my code.
How can I disable the namespacing requirement?
I don't think you should disable or remove namespaces. The main reason for namespacing is to avoid conflicts with classes that have the same name. As soon as an application gets larger you will have classes that have the same name. Example from the Framework source:
Illuminate\Console\Application and Illuminate\Foundation\Application
Both are called the same. Only because of the namespacing you can import the right class. Of course you could also name them:
ConsoleApplication and FoundationApplication
But while the namespace normally is only used when importing a class at the top of a file:
use `Illuminate\Console\Application`
The name itself is used everywhere in the code. That's something that really clutters up your code, too long class names.
Besides the naming thing, namespaces also encourage better structure and help with knowing where your files are. That's because Laravel's default structure is PSR-4 compliant. That means if you have a controller App\Http\Controllers\HomeController you can be certain that you will find a HomeController.php under app/Http/Controllers.
I am aware of that, but it's not needed in the project I am working on.
Maybe it doesn't make sense for the current project but getting used to namespaces will help you tackle bigger projects in the future
And being a Sublime Text user, which doesn't have autoimport, it really gets to be a pain
I don't know Sublime Text that well, but CodeIntel might have auto import. Otherwise consider switching to another editor / IDE. I can highly recommend JetBrains PhpStorm
In the end, if you still don't want to use namespaces, keep using Laravel 4 or search for another framework that follows less good practices...
Removing namespaces from your app classes
While a totally don't recommend this, it is possible to at least remove some of the namespacing in your application.
For example the default controller namespace App\Http\Controllers can be changed to no namespace at all in RouteServiceProvider:
protected $namespace = '';
And for your models you can just remove the namespace in the file and your good. But keep in mind that without namespaces PSR-4 autoloading won't work anymore. You will have to autoload your files using classmap in composer.json
You can avoid using namespaces for own classes by defining them in the global namespace in your composer.json file. Like this:
"autoload": {
"psr-0": {
"": ["app/Http/Controllers/",
"app/models/",
"app/helpers"
]
},
You will also have to change your app/Providers/RouteServiceProvider.php to:
protected $namespace = '';
for routing to work.

Where does one place Models in a Laravel Package?

I'm currently following the Laravel Package documentation, which uses the workbench tool to create a standard package tree consisting of controller, config, views, etc. folders. Basically, most folders you would get in a standard Laravel app tree.
However, I had a couple of questions:
Why is the models folder absent here? (though the same goes for tests and commands)
Should I just create the folder myself and add it to the composer.json autoload classmap?
What classes should live inside src/<Namespace>/<PackageName>? I have noticed that a ServiceProvider is automatically created here, but I can imagine most other files just existing in the standard package directories.
Wockbench represents just a tool for creating other tools, that is triggered through CLI. Workbench is very abstract concept.
Model folder is absent simply because you don't need model in every new package. For example, if you are creating middleware package or you own filter package.
Every new class can be added to package dependent on its purpose and responsibility. It can be done in more then one way.
Classes that are general enough to go into every package are:
Package Service Provider
Facade
Basic Class
But it is not a black box. Consider for example request class - it is bound very early in the application life cycle, so no provider is needed.

Using php scripts on my views in Laravel 4

I am using the Laravel 4 framework, and I am trying to set up the Facebook authentication system. I have an authentication system I had set up on another site (not using a framework) that used a config.php and process_facebook.php file. I am trying to implement this config.php file into my views. So far, I am including the files in a folder called "includes", within my "app" folder. I am trying to use the following code to implement it:
$app = app();
include($app['path.app'].'/includes/config.php');
My question is, where in the view do I put this code? Do I have to use php tags? (I am using the blad functionality). Your help is appreciated.
Laravel is an MVC framework, the purpose is to organise your code and clean your views. So this shouldn't be in your view.
I think the best way should be :
Create a facebook.php file in the config folder wich contains all your facebook configuration (read http://laravel.com/docs/configuration)
Create a folder named services, helpers or includes (as you want) and put process_facebook.php inside (I bet it contains the methods to deal with facebook API).
Add two lines of configuration to include this new folder
Like that :
// composer.json
"autoload": {
"classmap": [
[...]
"app/services",
]
},
// start/global.php
ClassLoader::addDirectories(array(
[...]
app_path().'/services',
));
Then, you can use your facebook class or methods all over your app.
The route you are taking to include configuration files is not recommended, but it is possible. Please see information about Laravel Configuration Files.
You should be able to use the following in your view:
<?php include(app_path().'/includes/config.php'); ?>
As it is a configuration file, it would be better to use require() instead of include().
In addition, it would also be better to include the file in the necessary controller(s).

Joomla two module using same helper.php

I've built two custom modules for Joomla ("reservation" and "contact") which are working just fine, however time to time I have to upgrade them.
Is it possible to make them to share the same "helper.php" so I could keep code in one place? For example the post function is the same for these two modules. I want the "contact" module to use the "reservation" helper.php post function.
Thanks
You can simply include the reservation module helper inside the contact module and use it.
For example lets say that your modules are mod_reservation and mod_contact, in mod_contact.php you include the reservation helper file and use it like this:
require_once JPATH_SITE.DS."modules".DS."mod_reservation".DS."helper.php";
modReservationHelper::post();
Or you make a custom helper module,, which is needed in order for the other 2 to work. I dont know for sure but I thought you can check for other modules when installing a module. In that check you check for the helper module and if not present you give a error. You could also say that a certain module needs atleast version X.XX.XX of the helper module and if the version is too long also give an error in during the install of the module.

Resources