I'm developing a Role-Permission package in Laravel and I want to use this package;
Laravel permission github
Problem is I can not use some functions in the main project when I install this package in my own package. example "HasRoles"
My packages composer.json file
"require": {
"spatie/laravel-permission": "dev-master"
},
"autoload": {
"psr-4": {
"Modul\\Permission\\": "src"
}
},
"extra": {
"laravel": {
"providers": [
"Spatie\\Permission\\PermissionServiceProvider"
]
}
}
main project composer file
{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"require": {
"php": "^7.1.3",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.8.*",
"laravel/tinker": "^1.0"
},
"require-dev": {
"beyondcode/laravel-dump-server": "^1.0",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^3.0",
"phpunit/phpunit": "^7.5"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Modul\\Permission\\": "packages/modul/permission/src"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"#php artisan package:discover"
],
"post-root-package-install": [
"#php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"#php artisan key:generate --ansi"
]
}
}
and my User model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable
{
use Notifiable;
use HasRoles;
when I serve its show this error message...
Symfony \ Component \ Debug \ Exception \ FatalErrorException
(E_UNKNOWN) Trait 'Spatie\Permission\Traits\HasRoles' not found
What am I doing wrong here?
[1]: https://i.stack.imgur.com/KRUT0.png
The problem is you are just autoloading your packages files into your project. This way your project's composer doesn't know anything about your package's dependencies (hence why spatie/permission package is not being installed).
The correct way to do this is to require your package into your project. Usually you would create a repository for your project, register it at https://packagist.org as modul/permission and then run composer require modul/permission for you project.
But if your package is still not fully developed, I would recommend you require it not from packagist, but from the so-called path repository. Inside your project's composer.json add the following section:
{
...
"repositories": [
{
"type": "path",
"url": "packages/modul/permission"
},
]
...
}
This will make composer look into your packages/modul/permission directory for your package when you require it. So do this and remove manual autoload of your package's source files from your project's composer.json (composer will use your package's autoload section to bind /src to Module\Permission namespace):
"psr-4": {
"App\\": "app/",
"Modul\\Permission\\": "packages/modul/permission/src" <--- remove this line
}
Lastly, run composer require modul/permission. Composer will find it inside the path repository we specified for him and symlink the packages/modul/permission directory to vendor/modul/permission and install it's dependencies as well.
Now you can edit your package inside packages/modul/permission folder. Once it's done be sure to publish it online on github/packagist, so that it can be remotely available from packagist repository to everyone, not just from your local path one.
Related
acknowledgement:
First of all this is my first post for help, as i went trough a lot of articles on stackoverflow and other resources and just could not find solution.
Problem sounds familiar but i just can't figure it out, maybe because im stuck on it for 2 days now. Another note, this is my first package so yes im not 100% sure what im doing.
Structure:
- laravel-project
- ...
- packages
- my-custom-package
- src
- MyCustomPackageServiceProvider.php
- composer.json
- public
- resources
- routes
- ...
- composer.json
So it is basic Laravel 5.8 + inside added package folder for local package devolment (it has been moved to repo as well)
Current Code (simplified as its actual work project):
File: laravel-project/packages/my-custom-package/composer.json
{
"name": "company/my-custom-package",
"type": "library",
"require": {
"php": ">=7.2",
},
"require-dev": {
"ext-curl": "*"
},
"authors": [
{
"name": "John Smith",
"email": "jsmith#test.tv"
}
],
"autoload" : {
"prs-4": {
"Company\\MyCustomPackage\\": "src/"
}
},
"minimum-stability": "dev"
}
File: laravel-project/packages/my-custom-package/src/MyCustomPackageServiceProvider.php
<?php
namespace Company\MyCustomPackage;
use Illuminate\Support\ServiceProvider;
class MyCustomPackageServiceProvider extends ServiceProvider {
public function boot()
{
$this->loadRoutesFrom(__DIR__ . '/routes/web.php');
$this->loadMigrationsFrom(__DIR__ . '/database/migrations');
}
public function register()
{
}
}
File: laravel-project/composer.json
{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"repositories": [
{
"type": "path",
"url": "~/testlaravel/packages/my-custom-package",
"options": {
"symlink": true
}
}
],
"require": {
"php": "^7.1.3",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.8.*",
"laravel/tinker": "^1.0",
"guzzlehttp/guzzle": "^6.3.3",
"company/my-custom-package": "dev-master"
},
"require-dev": {
"beyondcode/laravel-dump-server": "^1.0",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^3.0",
"phpunit/phpunit": "^7.5"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories"
]
},
"autoload-dev": {
"prs-4": {
"Company\\MyCustomPackage\\": "~/testlaravel/packages/my-custom-package/src"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"#php artisan package:discover --ansi"
],
"post-root-package-install": [
"#php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"#php artisan key:generate --ansi"
]
}
}
Explanation: ~/testlaravel/ is folder path inside Vagrant machine for project originaly url was "packages/my-custom-package" buti changed for this extended version just in pure attempt of making it work.
File: config/app.php (added service provider)
Company\MyCustomPackage\MyCustomPackageServiceProvider::class
Issue:
First i made this thing localy and it worked i was following for quick setup instructions from
"Create Laravel Composer Package from scratch to upload on packagist" Author: Bitfumes, and package worked, I could run composer update, then i added to app.php my package and i could run custom route and it all worked.
After that i moved package to git repo, and required it in same way only changed "repositories" field to
"repositories": [
{
"type": "vcs",
"url": "git#git.fulllink.co:john/my-custom-package.git"
}
]
and when you run composer update, you can see that afterwards inside vendor/ files you have Company folder with package inside it, BUT if you leave config/app.php service provider it starts to complain that there is
*Class 'Company\MyCustomPackage\MyCustomPackageServiceProvider' not fo und*
After some f*** around i found out that yes my autoload_classmap (cant remember original post) did not contain my package , so today i decided to try again local and see the difference, does it been added to map file, and now i get same error when requiring local package and i can't make it work anymore.
I been deleting vendor folder and lock file , composer dump-autoload, but that doesnt help. Im just thinking is thgere anything else supercached?
!!UPDATE!!
Im not even more confused. In composer.json (project one i tested on actual project repo now where is required another 2 local git repos). So i have now 4 packages in vendor/Company/{4 packages} , i compared all 4 package composer.json and i can't find any major difference but all of them have been loaded to autoload mapping except mine. Only major difference i can see, those two packages doesnt use ServiceProvider.php file , but i dont see how that impacts or changes things.
I could not install barryvdh/laravel-dompdf using composer require barryvdh/laravel-dompdf.
The error I got was:
[Invalid argument exception] Could not find a matching version of barryvdh/laravel-dompdf. Check the package spelling, your version constraint and that the package is available in a stability which matches your minimum-stability (dev).
So in order to fix the error, I included barryvdh/laravel-dompdf: master#dev in composer.json and did a composer update. This time it gave me the error:
The requested package barryvdh/laravel-dompdf could not be found in any version. there may be a typo in the package name
Below is my composer.json:
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": "^7.1.3",
"fideloper/proxy": "^4.0",
"guzzlehttp/guzzle": "^6.3",
"laravel/framework": "5.7.*",
"laravel/tinker": "^1.0",
"barryvdh/laravel-dompdf": "master#dev"
},
"repositories":
[
{
"type": "composer",
"url": "https:\/\/www.phpclasses.org\/"
},
{
"packagist": false
}
],
"require-dev": {
"beyondcode/laravel-dump-server": "^1.0",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^2.0",
"phpunit/phpunit": "^7.0"
},
"autoload": {
"classmap": [
"database/seeds",
"app/includes",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"laravel": {
"dont-discover": [
]
}
},
"scripts": {
"post-root-package-install": [
"#php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"#php artisan key:generate"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"#php artisan package:discover"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
},
"minimum-stability": "dev",
"prefer-stable": true
}
What do you think I am missing here?
Usually, it is advisable not to edit composer.json directly when installing third-party packages. You can remove the line "barryvdh/laravel-dompdf": "master#dev" from your file, and run this command from your project root directory instead:
composer require barryvdh/laravel-dompdf
It installs the latest stable third-party package and automatically updates both composer.json and composer.lock files.
UPDATE: To solve the problem with your composer.jsonfile, change the repositories key to this:
"repositories" :
[
{
"type": "composer",
"url": "https://packagist.org"
},
{
"packagist": false
}
]
Use
"barryvdh/laravel-dompdf": "^0.8.4",
instead of
"barryvdh/laravel-dompdf": "master#dev"
The package got installed after removing the repositories section from my composer.json.
Thank you all for the help
Remove this line in your composer.json file
"require": {
"barryvdh/laravel-dompdf": "master#dev"
},
After, run this command in your command prompt
composer require barryvdh/laravel-dompdf
This will download the package and the dompdf + fontlib libraries also. This will generate the latest version for your project
Please Check this: barryvdh/laravel-dompdf
Composer version 1.6.3
I only performed:
composer require "hieu-le/active:~3.5"
I installed an extension package, but the fact was unexpected and here the error:
vagrant#homestead:~/Projects/cunzai$ composer require "hieu-le/active:~3.5"
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing hieu-le/active (3.5.1): Downloading (100%)
Writing lock file
Generating optimized autoload files
Fatal error: Uncaught TypeError: Argument 1 passed to Composer\Autoload\ClassLoader::addClassMap() must be of the type array, integer given, called in phar:///usr/local/bin/composer/src/Composer/Autoload/AutoloadGenerator.php on line 760 and defined in phar:///usr/local/bin/composer/vendor/composer/ClassLoader.php:92
(1)phar:///usr/local/bin/composer/src/Composer/Autoload/AutoloadGenerator.php(760): Composer\Autoload\ClassLoader->addClassMap(1)
(2)phar:///usr/local/bin/composer/src/Composer/Autoload/AutoloadGenerator.php(303): Composer\Autoload\AutoloadGenerator->getStaticFile('c4e4dd9af67a9f1...','/home/vagrant/P...', '/home/vagrant/P...', '/home/vagrant/P...', 50600)
(3)phar:///usr/local/bin/composer/src/Composer/Installer.php(302): Composer\Autoload\AutoloadGenerator->dump(Object(Composer\Config),Object(Composer\Repository\InstalledFilesystemRepository),Object(Composer\Package\RootPackage), Object(Composer\Installer\InstallationManager), '/home/vagrant/P...', true)
(4)phar:///usr/local/bin/composer/src/ in phar:///usr/local/bin/composer/vendor/composer/ClassLoader.php on line 92
After the error, I also tried to install another extension package. The fact is also wrong. So I'm sure it's not an extension package. The Laravel framework and the composer can't be the cause of the error, but I can't think of a place. I hope There are grateful solutions posted to this problem.
composer.json:
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": ">=7.0.0",
"fideloper/proxy": "~3.3",
"hieu-le/active": "~3.5",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0",
"mews/captcha": "~2.0"
},
"require-dev": {
"barryvdh/laravel-debugbar": "~3.1",
"filp/whoops": "~2.0",
"fzaninotto/faker": "~1.4",
"mockery/mockery": "~1.0",
"phpunit/phpunit": "~6.0",
"symfony/thanks": "^1.0"
},
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"laravel": {
"dont-discover": [
]
}
},
"scripts": {
"post-root-package-install": [
"#php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"#php artisan key:generate"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"#php artisan package:discover"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
}
}
What finally worked for me was:
In composer.json, change the version of streams-platform to "anomaly/streams-platform": "1.3.219",, and add all of these lines to the bottom of the "require" section:
"teamtnt/laravel-scout-tntsearch-driver": "3.0.6",
"teamtnt/tntsearch": "1.3.1",
"michelf/php-markdown": "^1.8"
Then run:
composer dump-autoload
I'm using Laravel Homestead Vagrant on Virtualbox on Windows 10.
I used Git Bash to alternately run composer update directly in my project folder on Windows and then also after using SSH to get into that same project folder within the Ubuntu virtual machine.
My Homestead.yaml file uses type: "nfs".
When I run
phpunit command it throws all info from phpunit help with PHPUnit 3.7.21 by Sebastian Bergmann. So I suggest it should work, but not yet;
when I run
phpunit ExampleTest.php
PHP Fatal error: Class 'Tests\TestCase' not found in C:\xampp7\htdocs\projects\heroes\tests\Feature\ExampleTest.php on line 8
In Laravel I've got 'tests' folder with
TestCase.php
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
}
folder 'Feature' with
ExampleTest.php
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
and folder 'Unit'
In Laravel root folder I've got
composer.json
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": "^7.1.3",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.6.*",
"laravel/tinker": "^1.0",
"laravelcollective/html": "^5.4.0",
"laravelcollective/html": "~5.0"
},
"require-dev": {
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^2.0",
"phpunit/phpunit": "^7.0"
},
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"classmap": [
"tests/TestCase.php"
],
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"laravel": {
"dont-discover": [
]
}
},
"scripts": {
"post-root-package-install": [
"#php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"#php artisan key:generate"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"#php artisan package:discover"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
},
"minimum-stability": "dev",
"prefer-stable": true
}
I just simply need to start unit testing
It looks like your using phpunit installed globally in your system, which is super old and it is not connected with your project autoloading. You should use phpunit installed in your project by Composer:
vendor/bin/phpunit
When I run
vendor\bin\phpunit
It works, however It would be nice if somebody explained why
You can use this
./vendor/bin/phpunit
like this it will run phpunit from the root of your application
First install PHP Unit using this comand
composer require --dev phpunit/phpunit
After that check whether it is installed or not
./vendor/bin/phpunit --version
More Details visit - https://technicalguide.net/how-to-use-phpunit-in-laravel/
I have multiple composer.json having multiple seperate dependency and want to install all the dependency in the both composer.json using single composer install command.
The location is like this:
| - composer.json
| - Custom
| - Package1
| - composer.json
First composer.json
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": ">=5.6.4",
"barryvdh/laravel-debugbar": "^2.3",
"laravel/framework": "5.4.*",
"laravel/tinker": "~1.0",
"laravelcollective/html": "^5.4.0"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "~5.7",
"symfony/css-selector": "3.1.*",
"symfony/dom-crawler": "3.1.*"
},
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"post-root-package-install": [
"php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"php artisan key:generate"
],
"post-install-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postInstall",
"php artisan optimize"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan optimize"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
}
}
Second composer.json inside Package1 directory
{
"name": "custom/package1",
"description": "",
"require": {
"php": ">=5.6",
"composer/installers": "~1.0",
"lavary/laravel-menu": "1.7.1"
},
"autoload": {
"psr-4": {
"Custom\\Package1\\": ""
}
}
}
I want to install the lavary/laravel-menu inside the Package1 to the main vendor directory where all the default packages are installed.
|- vendor //<==want here
| - composer.json
| - Custom
| - Package1
| - vendor //<== not here
| - composer.json
I have tested this solution:
https://stackoverflow.com/a/27735674
like this:
{
"config": {
"vendor-dir": "../../vendor/"
}
}
This installs the packages but we need to get into the second composer.json instead of main composer.json and removes the installed package from first composer.json.
How can i install the all the dependency from the main composer.json without getting into the second or multiple composer.json in single vendor directory?
After some research and suggestion i figured out there are multiple ways to achieve this solution.
Using external package to maintain the dependency.
Thanks to rickdenhaan to let me know about
Composer Merge Plugin
https://github.com/wikimedia/composer-merge-plugin
First we need to require this package:
composer require wikimedia/composer-merge-plugin
Then my composer.json becomes like this:
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": ">=5.6.4",
"barryvdh/laravel-debugbar": "^2.3",
"laravel/framework": "5.4.*",
"laravel/tinker": "~1.0",
"wikimedia/composer-merge-plugin": "^1.4"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "~5.7",
"symfony/css-selector": "3.1.*",
"symfony/dom-crawler": "3.1.*"
},
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"post-root-package-install": [
"php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"php artisan key:generate"
],
"post-install-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postInstall",
"php artisan optimize"
],
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"php artisan optimize"
]
},
"config": {
"preferred-install": "dist",
"sort-packages": true,
"optimize-autoloader": true
},
"extra": {
"merge-plugin": {
"include": [
"Custom/*/composer.json"
],
"recurse": true,
"replace": false,
"ignore-duplicates": true,
"merge-dev": true,
"merge-extra": false,
"merge-extra-deep": false,
"merge-scripts": true
}
}
}
Now,
run
composer install
or
composer update
Then your composer.json in each of the directory will be merged into default vendor directory.
Next solution could be to publish the package to the packagist and require in the composer.json and during composer install all the dependency will be installed.
Like the Asgardcms has done.
Adding the private repository to the composer.json.
Configuring composer.json with private bitbucket mercurial repository
This option needs to add the composer.json of metapackage to the main composer.json file.
(I am not sure about the option but thanks to JParkinson1991 Someone who knows this solution could add explaination on this option. Adding just to let someone know this solution exists.)
Here is the example solution:
PHP & Composer, how do I combine composer.json files
In this the first solution suits my case. Hope this helps someone who spent alot of time searching.
Here is an alternative way that hopefully serves the use case of multiple composer JSON files.
Generally, we want to use multiple JSON files to differentiate production & development packages.
Packages that require in development only, we can use with require-dev
Here is an example of composer file:
{
"name": "name",
"type": "library",
"description": "Dummy Description",
"autoload": {
"psr-4": {
"Vendor\\Cache\\":"cache/",
}
},
"require-dev": {
"phpunit/phpunit": "^9",
"yoast/phpunit-polyfills": "^1.0"
}
}
So now if we want to use only production packages then use below command:
composer install --no-dev (It will not install packages that is inside require-dev)
If we need both development & production packages then use below command.
composer install (It will install all the packages)
It is just a suggestion. Hopefully, it may be helpful.