Laravel config subfolder not recognized on new server - heroku

I have some config files of US state counties, for example:
config/
state/
alabama/
counties.php
alaska/
counties.php
...
And on my development localhost server, I call them with:
Config::get('state/alabama/counties');
and it works, it loads an array of counties which I display somewhere.
But when I deploy this app on the Heroku, they won't show up.
I was thinking that it maybe has a problem with treating the config/state/subfolder as an environment config?
I do have a config/staging subfolder, in which I have new DB config stuff, and it works with no problem,
but on the Heroku app, the states just won't show up.

Have you added this directory to your autoload mapping in composer.json and then run composer dump-autoload? Without this, Laravel doesn't know to load your new files in to consideration.
Composer is a CLI-run file that exists in the Root of each laravel installation. composer.json is the config file for Composer - it uses this to manage your dependencies.
There's a section in composer.json called "autoload." These are the files that will automatically be loaded each time the app boots. Mine looks like this:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/core"
]
For each folder that didn't exist before and that I wanted Laravel to understand, I added an entry here. Then, I ran composer dump-autoload and Laravel "understood" where the files I wanted to use were.
Each time you add a file, class, repository - anything that you want Laravel to automatically use, you'll have to run composer dump-autoload.
P.S: If composer dump-autoload doesn't work, try composer.phar dump-autoload.

Related

Laravel package class not found

I have installed laravel packages on staging server and packages working fine. But when i take pull on staging server, it is showing me error that package class not found.
Steps I have followed to resolve issue
I have check in vendor folder as well as in config/app.php, but I got class declaration and package folder is there.
After this when I update composer, my issue get resolved.
Is there any other file which should i look for class defination?
Perform a composer update, then composer dump-autoload.
If the above doesn't solve the problem, change the classmap in your composer.json file such that it contains the project-relative path to your php files:
"autoload-dev": {
"classmap": [
"tests/TestCase.php",
"database/seeds/UserTableSeeder.php" //include the file with its path here
]},
and soon after, perform a composer dump-autoload, and it should work now

Create own laravel package

I try to create own laravel package.
I created package folder in my project in root directory.
Than created simplexi/greetr/src folders in package.
I added to autoload "Simplexi\Greetr\": "package/simplexi/greetr/src" in composer.json in main project, and used command composer dump-autoload.
Than in src folder I created RiakServiceProvider, added this provider to config=>app.php to providers array.
Then in boot method I added next code:
$this->publishes([__DIR__ . '../config/myconf.php' => config_path() . '/']);
And executed next command:
php artisan vendor:publish --provider="\Simplexi\Greetr\RiakServiceProvider"
Than I got Publishing complete.
But file myconf.php didn't copy to app/config.
Also I checked file myconf.php in my package/simplexi/greetr/config folder and it exists.
Can anyone tell me what the problem might be?
publishes() expect two parameters. Try something like this:
$this->publishes([
__DIR__.'/../config/myconf.php' => config_path('myconf.php'),
], 'config');

composer.json: change the vendor-dir dynamically through a script

In a project using Composer, shared by many developers and environments, I need to have the vendor-dir config parameter of composer.json to be set dynamically. That is, a script that runs when composer install/update is launched, must be able to change the value of this entry:
//composer.json
"config": {
"vendor-dir": "/var/www/html/......",
I tried the following:
//composer.json
"scripts": {
"pre-install-cmd": "MyBundle\\Composer\\Hook::setVendorDir",
The class Hook has this method:
//MyBundle/Composer/Hook.php
public static function setVendorDir(Event $event)
{
// ... some code set the $vendorDir variable here depending on many thing
$event->getComposer()->getConfig()->merge([
'config' => [
'vendor-dir' => $vendorDir
]
]);
// ...
}
The result is that the file autoloader.php and a composer folder are created in the right vendor directory, but all other packages are still installed in the default vendor directory!
The composer folder I mentioned only contains some PHP files (ClassLoader.php, _autoload\_*.php_, and LICENSE)
Notice: When I change the vendor-dir parameter in composer.json, it works flawlessly.
How may I set vendor-dir dynamically and have it taken into account for every package installations?
You can e.g. write a batch script (Windows) or bash script (Linux) or even a PHP script which you run instead of composer install. The script sets the correct vendor-dir in the composer.json and then runs composer install or whatever.
To set vendor dir just run in your script:
composer config vendor-dir /your/path/to/your/vendor/dir
For more info about composer config see the Composer documentation.

Composer classmap autoload does not load new files in folder

The following problem: I have defined a classmap in my composer.json:
"autoload": {
"classmap": [
"app/controllers",
"app/models",
"app/helper.php"
]
}
However, when I create a new file in the "controllers" or "models" folder, it will not load them and I always have to make a composer dump-autoload.
Is this the correct behavior? I thought the autoloader from composer monitors the folder for new files then?
Yes, this is correct behaviour. If you want new classes to be loaded automatically, you have to use either PSR-0 or PSR-4 autoloading.
Generating the classmap requires Composer to know the filename that contains a certain class. This can only be done by parsing the whole source code in the directory and scanning for classes, interfaces and trait definitions.
This usually is a CPU and I/O intensive task, so it is only done when Composer does install/update or (on demand) dumps the autoloader, it is not done with every require "vendor/autoload.php";.
Note that the classmap autoloading is simply there for old legacy codebases that didn't implement at least PSR-0. It is not intended for new code - unless you want to pay the price to dump the autoloader again and again during development.
Go to the root of your server by SSH. Now do the following:
Run ls to list all the files.
You will see composer.lock file; remove the file with rm composer.lock command.
Now run php composer update command.
Depending on your linux type you may have to run php-cli composer update.
Step 3 will create a new composer.lock file and all your classes will be loaded again. Do this anytime you add new classes.
or:
Run composer dump-autoload command.
As already pointed out this is correct behavior. If you want new classes to be loaded automatically, you have to use either PSR-0 or PSR-4 autoloading.
The classmap autoload type specified is composer.json is mainly used by legacy projects that do not follow PSR-0 or PSR-4. I have recently started working on such a project and wanted to try to automatically run the composer dump-autoload command when a new class is created. This is actually tricky without including all of the composer source inside the project. I came up with this just to remind the developer they need to dump the classmap:
$loader = include_once 'vendor/autoload.php';
if ( ! $loader ) {
throw new Exception( 'vendor/autoload.php missing please run `composer install`' );
}
spl_autoload_register(
function ( $class ) {
if ( 'A_Common_Class_Prefix' === substr( $class, 0, 10 ) ) {
throw new Error( 'Class "' . $class . '"" not found please run `composer dump-autoload`' );
}
},
true
);
This registers another autoloader which is run after composer's autoloader so any classes composer did not find would be passed to it. If the class matches a prefix an exception is throw reminding the developer to re-dump the autoloader and update the classmap.
For me, it somehow did not work too with Yii 1 class-map, when I added - required it along with many other libraries present - I don't remember exactly perhaps I manually edited the file or file permissions were to blame, it was not regenerated for some reason, even when I removed the composer.lock and erased completely the vendor folder - perhaps some cache, as far as I remember, but effectively what helped was to install firstly isolatedly only this single library, it generated class-map, then I added all the other remaining libraries separately at once at second step, viola, everything loadable.

Created package in Laravel workbench, but how to transfer to vendor folder?

Let's say my package in Laravel is test/test.
I created the package in the workbench and it's been working great following Jason Lewis' tutorial. Now I want to move the package out of
the workbench to the vendor directory. This is where all tutorials fall short, even the laravel docs. I didn't want to use git to move the files, so I simply copied the test/test package from the workbench to the vendor directory (and then deleted it from the workbench). I didn't copy the test/test/vendor folder from the workbench (or any other files I noticed in the .gitignore file). I then ran composer install from my new vendor/test/test directory. I then did a composer dump-autoload from the laravel root directory.
Now when I run my application I get an error that I did not get when the package was in the workbench:
Class 'Test\Test\TestServiceProvider' not found
(this is coming from \bootstrap\compiled.php on line 4121)
I also did a php artisan dump-autoload from the laravel root and I get this same error.
Any ideas? Or can someone lead me to a tutorial that takes the package development all the way to it's final resting point in the vendor directory?
Got it working.
I added:
"psr-0": {
"Test\\Test": "vendor/test/test/src/"
}
to the autoload section in composer.json in the laravel root directory so it looks like this:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-0": {
"Test\\Test": "vendor/test/test/src/"
}
},
If I decide to put the package on Packagist later then I might remove this from the autoload and just keep the package referenced in the "require" part of my composer.json. We'll see what happens when I get that far!
I think you can install your packages from your hard drive as from local repository like this:
"repositories": [
{
"type":"vcs",
"url":"/path/to/repo/here"
}
],
"require":{
"me/myrepo":"dev-master"
}

Resources