How to add helpers in own laravel packages? (Call to undefined function) - laravel

In my composer.json I have written:
"autoload": {
"psr-4": {
"Pmochine\\MyOwnPackage\\": "src/"
},
"files": [
"src/helpers.php"
]
},
But somehow even after composer dump-autoload the functions are not loaded. I get "Call to undefined function". To create the package I used a package generator. Maybe it has something to do that it creates a symlink in the vendor folder?
Inside helpers I have written
<?php
if (! function_exists('myowntest')) {
function myowntest()
{
return 'test';
}
}

In the package service provider, try adding this:
// if 'src/helpers.php' does not work, try with 'helpers.php'
if (file_exists($file = app_path('src/helpers.php'))) {
require $file;
}

What you are doing is best practise and should work. I took the composer.json from barryvdh/laravel-debugbar as an example. https://github.com/barryvdh/laravel-debugbar/blob/master/composer.json
{
"name": "barryvdh/laravel-debugbar",
"description": "PHP Debugbar integration for Laravel",
"keywords": ["laravel", "debugbar", "profiler", "debug", "webprofiler"],
"license": "MIT",
"authors": [
{
"name": "Barry vd. Heuvel",
"email": "barryvdh#gmail.com"
}
],
"require": {
"php": ">=5.5.9",
"illuminate/support": "5.1.*|5.2.*|5.3.*|5.4.*|5.5.*",
"symfony/finder": "~2.7|~3.0",
"maximebf/debugbar": "~1.13.0"
},
"autoload": {
"psr-4": {
"Barryvdh\\Debugbar\\": "src/"
},
"files": [
"src/helpers.php"
]
}
}
My guess is that you are not requiring your own package the correct way in the main composer.json?

Just need to call in your main project
composer update you/your-package
Source

The only thing that has worked for me is to run composer remove <vendor>/<package> and require it back again. The files section was ignored otherwise.
This seems to happen while developing locally the package and making changes on the composer.json file.

Related

Autoloading of classes of a local TYPO3 extension

In my following composer.json I am requiring extensions, which are in the same Git repository as the whole project. So I add in the repositories section and later I do composer req vendor/site_package:#dev in order to require my local extension.
Now I realized, that some classes of the extension are not autoloaded.
Do I need to additional add the autoload part as shown below in the composer.json of the project?
{
"name": "site-package",
"description": "Base composer.json",
"repositories": [
{
"type": "path",
"url": "./packages/*"
}
],
"require": {
"typo3/cms-backend": "^10.4",
"typo3/cms-belog": "^10.4",
"typo3/cms-beuser": "^10.4",
"typo3/cms-core": "^10.4",
...
"vendor/site_package": "#dev",
"georgringer/news": "^8",
...
},
"autoload": {
"classmap": [
"public/typo3conf/ext/site_package/Classes"
],
"psr-4": {
"Vendor\\SitePackage\\": "public/typo3conf/ext/site_package/Classes"
}
},
"extra": {
"typo3/cms": {
"root-dir": "public",
"web-dir": "public"
}
},
"config": {
"vendor-dir": "vendor",
"bin-dir": "bin"
},
"scripts": {
"typo3-cms-scripts": [
"typo3cms install:generatepackagestates",
"typo3cms install:fixfolderstructure"
],
"post-autoload-dump": [
"#typo3-cms-scripts"
]
}
}
In ext:site_package I have the following autoload section as well:
"autoload": {
"psr-4": {
"Vendor\\SitePackage\\": "Classes",
}
},
Do I need both? Why?
You should never mix those 2 composer.json.
As you already follow the approach of having a directory packages (which is a good thing) each extension inside there needs an own composer.json file which of course also needs a section
"psr-4": {
"Vendor\\MyExt\\": "Classes"
}
By requiring this package, this autoload information will be used.
If you would still have the custom extension inside typo3conf/ext/my_ext, that composer.jsonfile would not be taken into account and you need something like
"psr-4": {
"Vendor\\MyExt\\": "typo3conf/ext/myext/Classes"
}
The autoload part is only needed in your site package composer.json. It's not necessary to put it also in the composer.json in your root folder.
Please refer to the documentation how the composer.json of your site package should look like.
If you still have problems with autoloading, try composer dump-autoload or remove the extension and require it again. And make sure to check the upper-/lowercase of your namespace. It's case sensitive. If you change that after you required the site package, you need to remove and require the package again.

How to add a package to a custom laravel package?

I'm building a custom Laravel package which requires the guzzlehttp/guzzle package. Below is my composer.json file:
{
"name": "lomse/awesomePackage",
"description": "this an awesome package",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Selom",
"email": "awesome#gmail.com"
}
],
"minimum-stability": "dev",
"require": {
"guzzlehttp/guzzle": "^6.3"
},
"autoload": {
"psr-4": {
"Lomse\\AwesomePackage\\": "src/"
}
}
}
Below is the content of my AwesomeProvider.php file:
<?php
namespace Lomse\AwesomePackage;
use GuzzleHttp\Client;
use Illuminate\Support\ServiceProvider;
class AwesomeProvider extends ServiceProvider
{
public function boot(){
}
public function register()
{
$this->app->singleton(Awesome::class, function ($app) {
return new Awesome(new Client); //Class 'GuzzleHttp\Client' not found
});
}
}
I keep getting Class 'GuzzleHttp\Client' not found.
What am I doing wrong?
So, this turns out to be quite simple. I highlighted the steps to take in order to solve this. Hope this helps anyone who is having the same issue.
I had to push my code to a repo lomse/awesome-package on Github
then specified preferred-install as dist in the ./lomse/awesome-package/package.json config property`:
"config": {
"preferred-install": "dist"
}
The full code is
{
"name": "lomse/awesome-package",
"description": "this an awesome package",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Selom",
"email": "awesome#gmail.com"
}
],
"minimum-stability": "dev",
"require": {
"guzzlehttp/guzzle": "^6.3"
},
"autoload": {
"psr-4": {
"Lomse\\AwesomePackage\\": "src/"
}
},
"config": {
"preferred-install": "dist"
}
}
In the root package.json, specify the repository of your package as follow:
"repositories": [
{
"type": "git",
"url": "git#github.com:lomse/awesome-package.git"
}
]
Also add your package repo to the package.json require property as shown below:
"lomse/awesome-package": "dev-master"
From your root directory, run the code below to update your dependencies. This will clone the lomse/awesome-package repo into your vendor folder and install any other dependencies required by your package:
composer update -vvv
-vvv is for debugging purposes

laravel 5.5 package developing need to use composer require vendor_name/package_name

I developed a Laravel 5.5 package with package auto discovery and pushed it at git hub
https://github.com/adamibrahim/authconfirm
when i run
$ composer require "adamibrahim/authconfirm" : "v0.1.1"
I got an error
could not find package adamibrahim/authconfirm at any version for your min ...
do i need to register my repository somewhere so i can use composer require command ?
here is my package composer.json
{
"name": "adamibrahim/authconfirm",
"type": "library",
"description": ":Laravel 5.5 Auth modifications to confirm the auth email",
"keywords": [
"Laravel5.5",
"Auth",
],
"homepage": "https://github.com/adamibrahim/authconfirm",
"license": "MIT",
"authors": [
{
"name": ":Adam Ibrahim",
"email": ":adamibrahim1701#gmail.com",
"homepage": ":author_website",
"role": "Developer"
}
],
"require": {
"illuminate/support": "~5.1",
"php" : "~5.6|~7.0"
},
"require-dev": {
"phpunit/phpunit" : ">=5.4.3",
"squizlabs/php_codesniffer": "^2.3"
},
"autoload": {
"psr-4": {
"Adamibrahim\\Authconfirm\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Adamibrahim\\Authconfirm\\": "tests"
}
},
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"config": {
"sort-packages": true
}
}
Well, it's not enough just to create Github repository to use it via composer. You should create account at https://packagist.org/ and add your package in there to make it available via composer require.
In addition you should setup Packagist integration on Github at:
https://github.com/adamibrahim/authconfirm/settings/installations
to make sure after changes in Github Packagist will see those changes.

Delegating to Local composer.json

With my clean Laravel 5.3 installation, I can run composer install to install the dependent packages.
Now, I've an internal package with its own composer.json, like below:
{
"name": "bar/foo",
"description": "A package for handling foo",
"licence": "MIT",
"authors": [
{
"name": "A. Foo",
"email": "a#foo.bar"
}],
"minimum-stability": "dev",
"require": {},
"autoload": {
"psr-4": {
"Foo\\Bar\\": "packages/foo/Bar/src"
}
}
}
So I prefer to autoload from the package itself, instead of autoloading from the main composer.json.
My questions:
Running composer dumpa from packages/foo/Bar doesn't take effect for autoloading. After Generating autoload files, Laravel doesn't know namespace Foo\Bar
Is there a way to run composer dumpa for all recursive composer.jsons?
You need to add the following section to your global composer.json
"repositories": [
{
"type": "path",
"url": "packages/*/*"
}
]
You also need to add the packages to the require object in composer.json

Laravel framework like package, dump-autoload not working

For a project I'm working on I would like to create a 'Core' package containing multiple smaller packages, like laravel does with it's framework.
The folder structure would be something like this,
Package1: gybrus/core/src/Gybrus/Package1
Package2: gybrus/core/src/Gybrus/Package1
After doing some research I've noticed this could be achieved with composer if I'm not mistaken but this is also where it breaks for me.
Currently I have multiple composer.json files, but after running the 'php artisan dump-autoload' command the classes aren't added to the autoload files.
Therefore I'm wondering if the Laravel framework adds some extra magic to make this happen.
Thanks in advance!
This is my current setup, I've changed the package names for the sake of not advertising something ;)
The first composer file is in the 'core' folder next to the 'src' folder.
{
"name": "gybrus/core",
"description": "The Core",
"keywords": ["core"],
"authors": [
{
"name": "Kevin Dierkx",
"email": "email#email.com"
}
],
"require": {
"php": ">=5.3.0",
"laravel/framework": "4.0.x"
},
"replace": {
"gybrus/package1": "self.version"
},
"require-dev": {
"mockery/mockery": "dev-master",
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-0": {
"Gybrus": "src/"
}
},
"minimum-stability": "dev"
}
The second composer file is in the package1 folder:
{
"name": "gybrus/package1",
"authors": [
{
"name": "Gybrus",
"email": "email#email.com"
}
],
"require": {
"php": ">=5.3.0",
"illuminate/support": "4.0.x"
},
"autoload": {
"psr-0": {"Gybrus\\Package1": ""}
},
"target-dir": "Gybrus/Package1",
"minimum-stability": "dev"
}
Found the cause of my problem!
The first script tells composer that it should autoload the namespace 'Gybrus' starting in the 'src' folder, after some testing this works as intended.
Where the above setup breaks is the following line:
return Finder::create()->files()->in($workbench)->name('composer.json')->depth('< 3');
This tells the Finder to stop looking for composer.json files that are deeper than 2 folders.
Nothing weird so far.
Where is goes wrong is here, I symlinked the workbench packages into the workbench folder.
This causes the weird problem that the composer.json files are actually deeper than they should be, which in result stop the loading of the composer.json files and breaking the autoloading for these packages.
A quick fix would be to either don't symlink or run composer install from inside the package.

Resources