Laravel programatically calling artisan command from web.php in production - php

I have below route:
Route::get('/beneficiaries/seed', function () {
echo "<p>Database seeding started...</p>";
$exitCode = Artisan::call('db:seed');
echo "<p>Database seeding completed.</p>";
});
In my local environment, when I visit '/beneficiaries/seed', it seeds the database. But if I do the same in production, it doesn't. I just copied the seeder classes and route file.
DatabaseSeeder:
class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(BeneficiariesTableSeeder::class);
}
}
BeneficiariesTableSeeder:
class BeneficiariesTableSeeder extends Seeder
{
public function run()
{
//seeding logic...
}
}
Why my production Artisan command doesn't get executed? (I haven't used database transaction. Even w/o it, local db gets seeded since there is no err is raised.)

When you run php artisan db:seed in production, there is a warning that asks you whether you're sure to seed the database in production.
This warning confirmation in production is the reason why Artisan::call('db:seed') isn't working in production.
To circumvent the warning, you can use the --force flag like so: php artisan db:seed --force.
Solution
To do the same in code, use Artisan::call('db:seed', ['--force' => true]);

Related

Php Artisan and Tinker not finding laravel project classes

I happened to open two instances of Laragon at the same time. After that php artisan migrate started throwing strange errores like "Interface not found" when that interface is actually there and was correctly imported. Tried different migrations and also throws random errors. I even tried with an old (already migrated) migration, copy pasted the code and it also didn't work. Always related to classes/interfaces not being found.
I've just noted that a simple test:
<?php
use App\Book;
use Illuminate\Database\Migrations\Migration;
class BookTest extends Migration
{
public function up()
{
echo Book::HARDCOVER;
}
}
doesn't work; it says: 'Class 'App\Book' not found' . The book class is there and was imported from phpstorm with a simple click. So, php artisan isn't finding any of my project classes.
I've just confirmed that tinker can't find the classes either.
Ok, I've just noticed that if I change in the book class the namespace to '\App\Models\Store' (where the file actually is) and I do from tinker something like \App\Models\Store\Book::HARDCOVER, then it actually works. The thing I don't get is why it's now (suddenly) needing me to update the name space to work...
Don't know how but my composer version was 2 so I had to downgrade to 1.10 and all works again.

How to load seeders from Laravel packages, without publishing them?

I'm developing some packages for Laravel (for internal use).
It is logical for a package, to have its own seeders.
For example, let's suppose we are creating a package called Company\Geo that has the data of countries and continents and flags, etc.
It's a good UX that this package should have 100% self-contained seeder classes to populate the database tables with the data.
However, I'm stuck at running seeders from packages. This is my package directory strcuture:
- host => (a laravel app to test the package)
- WebSite
- packages
- Company
- FirstPackage
- database
- migrations
- seeders
- FirstSeeder.php
- src
- Models
- Http
- Controllers
And here is my FirstSeeder.php code:
<?php
namespace Company\FirstPackage\Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\App;
class FirstSeeder extends Seeder
{
public function run()
{
// code to seed
}
}
And here is my composer.json of the Company\FirstPackage package:
"autoload": {
"classmap": [
"/database/migrations"
],
"psr-4": {
"Company\\FirstPackage\\": "src/",
"Company\\FirstPackage\\Database\\": "database/"
}
},
Yet when I run php artisan db:seed --class=FirstSeeder I get this error:
Target class [Database\Seeders\FirstSeeder] does not exist.
How can I call seeders of my package, without publishing them to the host package?
I have just read the source code. I believe you got to do this:
// Pls use double backward slashes.
php artisan db:seed --class=php artisan db:seed --class=Company\\Package\\Database\\Seeder\\FirstSeeder
You might want to take a look at the Illuminate\Database\Console\Seeds\SeedCommand::getSeeder() method.
You can use the same logic that is used in ServiceProvider. This way you can simply run: php artisan db:seed and it should run any seeders you have in your packages.
protected function loadSeeders($seed_list){
$this->callAfterResolving(DatabaseSeeder::class, function ($seeder) use ($seed_list) {
foreach ((array) $seed_list as $path) {
$seeder->call($seed_list);
// here goes the code that will print out in console that the migration was succesful
}
});
}
then you can create a list using a function that gets every class name you are using in your package. And put it inside, like this
$seed_list[] = 'Vendor/Name/Directory/ClassName'
// inside your service provider
boot()
{
$this->loadSeeders($seed_list)
}
this is just a copy past please see
https://laracasts.com/discuss/channels/laravel/best-way-to-load-seeds-and-routes-from-a-package

Laravel default helper method and facade doesn't work on custom package

I am developing a custom package where I need an access to the config data. I was able to pull data from config through my blade files, however, when I tried to call it from any custom classes I made, it's throwing an error:
Error: Call to undefined function Acme\Package\config()
What's interesting though, is that, when I tried using the facade Illuminate\Support\Facades\Config, it cannot find the class.
Is there any way I could retrieve data from the config (from the package and/or the app)?
<?php
namespace Acme\Package;
class MyClass {
public function test() {
config('app.name');
}
}
UPDATE: It works when running in the browser (package installed in a Laravel project) but fails when running package's test
UPDATE: If this helps, my package can be found here
Call to the config() is from here
And the test case that fails can be found here
<?php
namespace Acme\Package;
class MyClass {
public function test() {
\Illuminate\Support\Facades\Config::get('app.name');
}
}
Try like this, to use the full namespace to the Config Facade. You could also make a use statement under your namespace to inject the facade and then use Config::get('app.name). The reason it is not working is that your package cannot resolve the namespace of that facade as it is outside of the IoC container
You should try this:
<?php
namespace Acme\Package;
use Config;
class MyClass {
public function test() {
Config::get('app.name');
}
}
Updated answer
Please add below line in config/app.php in aliases section
'Config' => Illuminate\Support\Facades\Config::class,
then run below command
php artisan config:cache
php artisan cache:clear

Laravel 5: class 'Illuminate\Database\Seeder' not found

Problem I'm currently facing to has been posted here already, yet none of them could solve my one.
I'm talking about database seeder located under url like http://HOSTNAME/laravelfiles/database/seeds/UsersTableSeeder.php. Its content is as follows:
<?php
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
// What should be being done, it is being done here :)
}
}
Having opened this file directly (by url given above the code), following error is printed:
Fatal error: Class 'Illuminate\Database\Seeder' not found in /var/www/laravelfiles/database/seeds/UsersTableSeeder.php on line 6
I found possible solution. Doesn't work for me:
composer dump-autoload
<?php
use Illuminate\Database\Seeder;
class UsersTableSeeder extends Seeder
{
}
NOTE: Even the code above produces the same error.
You must run seeder class via command line, not browser.
you should open your command line and change directory to laravel root folder.
then you need to run command:
php artisan db:seed
and check your database.
for more info please check laravel documentation(Laravel Database Seeding)

Laravel Artisan Migrate [BadMethodCallException]

When I try to run php artisan migrate to migrate a missing migration to my database. I get the following exception:
[BadMethodCallException]
Call to undefined method Illuminate\Database\Query\Builder::up()
See down to get the complete log and stack trace.
I run the command on the console local on my own computer. But on my server it does not work either.
I have tried already the following:
1. composer update
2. artisan dump-autoload
3. Delete /vendor and do composer install
This (https://github.com/cartalyst/sentry/issues/257) has not helped because i don't have a compile.php file. (Cause on local development this is disabled by default from laravel.)
If you need more informations like the complete migration code. Please ask.
This is the complete stack trace from the log http://snippi.com/s/lz5z86f (I have put it into a snippet cause it is quite long.)
I had another class which had the same filename like the migration.
Cause of this the exception was thrown. Renaming and executeing artisan dump-autoload helped.
I had the same problem and then I realized that my migrations filename differed from the class name and that fixed the problem for me. Try that one.
Could you show us your migration since the Exception tells you that the method used for creating the tables etc. is not there. In every migration the layout should look something like this:
public function up() {
Schema::create('users', function($table)
{
$table->increments('id');
});
}
public function down() {
Schema::drop('users');
}
Maybe you are calling a Class instead of the ClassSeeder in your DatabaseSeeder or Seeder

Categories