I'm trying to call a seeder from a parent directory within my Laravel 9 project. My seeder locations are:
Database/Seeders/Production/Permissions/UserManagement/UserPermissionsTableSeeder
Database/Seeders/Production/Permissions/PermissionsGeneratorTableSeeder
It's my UserPermissionsTableSeeder seeder that I need to call my PermissionsGeneratorTableSeeder from:
<?php
namespace Database\Seeders\Production\Permissions\UserManagement;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class UserPermissionsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run($companyId = null)
{
$roles = [
'super_admin' => [
'user_index',
'user_show',
'user_store',
'user_update',
'user_destroy'
],
'admin' => [
'user_index',
'user_show',
'user_store',
'user_update'
]
];
$this->call(
Database\Seeders\Production\Permissions\PermissionsGeneratorTableSeeder::class,
false,
['roles' => $roles]
);
}
}
When I attempt to pass the full path to the call method, I get the following error path:
Target class [Database\Seeders\Production\Permissions\UserManagement\Database\Seeders\Production\Permissions\PermissionsGeneratorTableSeeder] does not exist.
What am I missing?
UPDATE
Here's the PermissionsGeneratorTableSeeder class:
<?php
namespace Database\Seeders\Production\Permissions;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
class PermissionsGeneratorTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run($roles = [])
{
if (!$roles) {
return;
}
foreach ($roles as $key => $permissions) {
$role = Role::query();
$role = $role->where('name', $key);
if ($key != 'super_admin') {
$role = $role->where('company_id', $companyId);
}
$role = $role->first();
if (!$role) {
continue;
}
foreach ($permissions as $permission) {
$discoveredPermission = Permission::where('name', $permission)->first();
if ($discoveredPermission) {
$discoveredPermission->assignRole($role);
continue;
}
$permissionCreated = Permission::create([
'name' => $permission,
'guard_name' => config('auth.defaults.guard')
]);
$permissionCreated->assignRole($role);
}
}
}
}
In your call method just add a \ to start of the class full path and you're good to go
$this->call(
\Database\Seeders\Production\Permissions\PermissionsGeneratorTableSeeder::class,
false,
['roles' => $roles]
);
Related
I am developing an application in laravel and when I perform the test with insomnia (post), it presents the following "Class illuminate\Support\Facades\Storage" not found .
follow my code below
WarningController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use illuminate\Support\Facades\Storage;
use illuminate\Support\Facades\Validator;
use App\Models\Warning;
use App\Models\Unit;
class WarningController extends Controller
{
public function addWarningFile(Request $request)
{
$array = ['error' => ''];
$validator = validator::make($request->all(), [
'photo' => 'required|file|mimes:jpg,png'
]);
if (!$validator->fails()) {
$file = $request->file('photo')->store('public');
$array['photo'] = asset(Storage::url($file));
} else {
$array['error'] = $validator->errors()->first();
return $array;
}
return $array;
}
}
Validator.php
<?php
namespace Illuminate\Support\Facades;
class Validator extends Facade
{
/**
* Get the registered name of the component.
*
* #return string
*/
protected static function getFacadeAccessor()
{
return 'validator';
}
}
This is my PlayerController, Player & Session Model and Resource.
I want to use the input (sessionId from SessionsTable) to fetch user from the room with the same id (userSession) and return an array in this format: [{userId:1, userName: stacki, userVote:8},{...},...]
I already asked [here][1] to achieve this and now im stuck with this error.
What do I have to change in order to solve this issue? Simply adding ->first() does not solve my issue, I need more than one record.
namespace App\Http\Controllers;
use App\Player;
use Illuminate\Http\Request;
use App\Http\Resources\Players as PlayerResource;
class PlayerController extends Controller
{
public function index(Request $request)
{
$room = $request->input('sessionId');
$currentPlayers = Player::where('userSession', $room)->get();
return PlayerResource::collection($currentPlayers);
}
public function create()
{ }
public function update()
{ }
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Player extends Model
{
protected $fillable = [];
public $sortable = [
'userId',
'userName',
'userVote'
];
public function sessions()
{
return $this->hasMany('App\Session');
}
public function players(){
return $this->belongsToMany('App\Session');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Session extends Model
{
protected $fillable = [];
public function user(){
return $this->belongsToMany('App\Player');
}
public function creator()
{
return $this->hasOne('App\Player', 'userId');
}
}
class Players extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'userId' => $this->sessionId,
'userName' => $this->userName,
'userVote' => $this->userVote
];
}
}
`
[1]: https://stackoverflow.com/questions/58062014/display-db-entries-in-json-array-in-controller-laravel-php
Your Player class might extends the Illuminate\Http\Resources\Json\JsonResource instead of ResourceCollection.
This should solve your problem.
use Illuminate\Http\Resources\Json\JsonResource;
class Players extends JsonResource
{
/**
* Transform the resource collection into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'userId' => $this->sessionId,
'userName' => $this->userName,
'userVote' => $this->userVote
];
}
}
Hope it helps.
For my Laravel app I'm trying to create a Unit test that atttempts to get a count of all of the states I have in my State filter. The test does not need a user or roles or permissions to be able to run however with my test it extends this TestCase file. When I run my test its reporting that the roles table does not exist.
Does anyone have any ideas on what I should do?
<?php
namespace Tests;
use App\Models\User;
use App\Models\Role;
use App\Models\Permission;
use PHPUnit\Framework\Assert;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Foundation\Testing\TestResponse;
abstract class TestCase extends \Illuminate\Foundation\Testing\TestCase
{
use CreatesApplication;
protected $authorizedUser;
protected $unauthorizedUser;
/**
* The base URL to use while testing the application.
*
* #var string
*/
protected $baseUrl = 'http://ringside.app';
protected function setUp()
{
parent::setUp();
TestResponse::macro('data', function ($key) {
return $this->original->getData()[$key];
});
Collection::macro('assertContains', function ($value) {
Assert::assertTrue($this->contains($value), 'Failed asserting that the collection contains the specified value.');
});
Collection::macro('assertNotContains', function ($value) {
Assert::assertFalse($this->contains($value), 'Failed asserting that the collection does not contain the specified value.');
});
Collection::macro('assertEquals', function ($items) {
Assert::assertEquals(count($this), count($items));
$this->zip($items)->each(function ($pair) {
list($a, $b) = $pair;
Assert::assertTrue($a->is($b));
});
});
$this->setupUnauthorizedUser();
$this->setupWrestlerStatuses();
}
/**
* Creates an authorized user of the included permissions.
*
* #param array $slugs
* #return void
*/
protected function setupAuthorizedUser($slugs)
{
$this->authorizedUser = factory(User::class)->create();
$role = factory(Role::class)->create();
if (is_array($slugs)) {
foreach ($slugs as $slug) {
$permission = factory(Permission::class)->create(['slug' => $slug]);
$role->givePermissionTo($permission);
}
} else {
$permission = factory(Permission::class)->create(['slug' => $slugs]);
$role->givePermissionTo($permission);
}
$this->authorizedUser->assignRole($role);
}
protected function setupUnauthorizedUser()
{
$this->unauthorizedUser = factory(User::class)->create();
$role = factory(Role::class)->create();
$this->unauthorizedUser->assignRole($role);
}
}
<?php
namespace Tests\Unit\Utilities;
use Tests\TestCase;
class StateTest extends TestCase
{
/** #test */
public function it_can_get_all_states()
{
$this->assertEquals(50, count(State::all()));
}
}
I'm developing in a system using Laravel 5.3 and I"m trying to update custom validation rules. The architecture is currently as follows:
ProfileStoreRequest --> ProfileValidator
ClientStoreRequest --> ClientValidator
...
What I'm basically trying to do here is to have only one object named "StoreRequest" which will call the correct validator depending on the route which is being called. Here's what I have so far:
In my routes:
Route::group([
'prefix' => 'manage',
'namespace' => 'Manage',
'validators' => [
'manage.profile.storeAjax' => [
'name' => "required|max:40",
'color' => "integer|digits_between:0,7",
'service' => "integer", //digits_between:3,10
'company_id' => "required|integer|exists:companies,id,deleted_at,NULL",
'site_id' => "integer|siteIdExists"
]
]], function () {
Route::post('/site/storeAjax', 'SiteController#storeAjax')->name('manage.site.storeAjax');
Route::post('/company/storeAjax', 'CompanyController#storeAjax')->name('manage.company.storeAjax');
Route::post('/employee/store', 'EmployeeController#store')->name('manage.employee.store');
Route::post('/employee/addProfile', 'EmployeeController#addProfile')->name('manage.employee.addProfile');
Route::post('/employee/removeProfile', 'EmployeeController#removeProfile')->name('manage.employee.removeProfile');
Route::post('/employee/addSite', 'EmployeeController#addSite')->name('manage.employee.addSite');
Route::post('/employee/removeSite', 'EmployeeController#removeSite')->name('manage.employee.removeSite');
Route::post('/message/storeAjax', 'MessageController#storeAjax')->name('manage.message.storeAjax');
Route::post('/profile/storeAjax', 'ProfileController#storeAjax')->name('manage.profile.storeAjax');
Route::post('/timeEntry/storeAjax', 'TimeEntryController#storeAjax')->name('manage.timeEntry.storeAjax');
});
Next is my StoreRequest:
namespace App\Http\Requests;
use App\Http\Validators\ProfileValidator;
use Auth;
//use App\Model\TimeEntry;
use DateUtil;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
class StoreRequest extends AbstractRequest {
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize() {
// prj(__METHOD__);
$authorized = parent::authorize();
if ($authorized) {
$user = Auth::user();
if ($user && $user->can('write')) {
return true;
} else {
return false;
}
}
return false;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules() {
parent::rules();
return $this->route()->getAction()['validators'][$this->route()->getName()];
}
/**
* User messages
*
* #return array
*/
public function messages() {
$messages = array_merge(parent::messages(), [
'exists' => 'The selected :attribute is invalid for this time entry id.'
]);
return $messages;
}
public function validate()
{
parent::validate();
}
}
And of course, all of my custom validators are registered using service providers (here's an example with a profileValidator):
profileServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Validator;
class ProfileServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot() {
Validator::extend('siteIdExists', 'App\Http\Validators\ProfileValidator#validateSiteIdExists');
}
/**
* Register any application services.
*
* #return void
*/
public function register() {
//
}
}
ProfileValidator.php
namespace App\Http\Validators;
use App\Model\Site;
use Mockery\Exception;
class ProfileValidator
{
public function validateSiteIdExists($attribute, $value, $parameters, $validator)
{
if ($value == -1)
return true;
else
{
return Site::where(
[
['id', '=', $value],
['company_id', '=', $validator->getData()['company_id']]
]
)->whereNull('deleted_at')->exists();
}
}
}
So basically, my StoreRequest is capable of loading its validation rules from the route... however, no matter how hard I try, I can't figure how to bind the validator I want. Can anyone help me?
I am using laravel 5.4 to create a web app.
I have created a trait to implement events for created, updated, deleted and restored eloquent events.
I have created a trait as below:
<?php
namespace App\Traits;
use Auth;
use App\Master\Activity;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
/**
* Class ModelEventLogger
* #package App\Traits
*
* Automatically Log Add, Update, Delete events of Model.
*/
trait ActivityLogger {
/**
* Automatically boot with Model, and register Events handler.
*/
protected static function boot()
{
parent::boot();
foreach (static::getRecordActivityEvents() as $eventName) {
static::$eventName(function (Model $model) use ($eventName) {
try {
$reflect = new \ReflectionClass($model);
return Activity::create([
'user_id' => Auth::user()->id,
'content_id' => $model->id,
'content_type' => get_class($model),
'action' => static::getActionName($eventName),
'description' => ucfirst($eventName) . " a " . $reflect->getShortName(),
'details' => json_encode($model->getDirty()),
'ip_address' => Request::ip()
]);
} catch (\Exception $e) {
Log::debug($e->getMessage());//return true;
}
});
}
}
/**
* Set the default events to be recorded if the $recordEvents
* property does not exist on the model.
*
* #return array
*/
protected static function getRecordActivityEvents()
{
if (isset(static::$recordEvents)) {
return static::$recordEvents;
}
return [
'created',
'updated',
'deleted',
'restored'
];
}
/**
* Return Suitable action name for Supplied Event
*
* #param $event
* #return string
*/
protected static function getActionName($event)
{
switch (strtolower($event)) {
case 'created':
return 'create';
break;
case 'updated':
return 'update';
break;
case 'deleted':
return 'delete';
break;
case 'restored':
return 'restore';
break;
default:
return 'unknown';
}
}
}
But when I am implementing it in my Model like:
<?php
namespace App\Master;
use App\Traits\ActivityLogger;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class LeadSource extends Model
{
use ActivityLogger;
use SoftDeletes;
protected $table = 'lead_source';
protected $primaryKey = 'lead_source_id';
protected $dates = ['deleted_at'];
protected $fillable = [
'name', 'created_by', 'created_ip', 'updated_by', 'updated_ip'
];
}
Then in my controller i am calling created/update as usual via eloquent model. But the events aren't fired up and not recording anything in the activity table.
Below is my Migration for activity table:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateActivityTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('activity', function (Blueprint $table) {
$table->increments('activity_id');
$table->unsignedInteger('user_id');
$table->unsignedInteger('content_id');
$table->string('content_type', 255);
$table->string('action', 255);
$table->text('description')->nullable();
$table->longText('details')->nullable();
$table->ipAddress('ip_address')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('activity');
}
}
Please advise what is the issue?
I found the solution, all ok with Model and Migration, it was the trait where it was making issue. There were a no. of things wrong and which was preventing it to work properly.
And the most important thing which was wrong is the Log, I did;t included proper class for it and that caused the issue.
Here is the corrected code for the trait file only.
<?php
namespace App\Traits;
use Auth;
use Request;
use App\Master\Activity;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
/**
* Class ModelEventLogger
* #package App\Traits
*
* Automatically Log Add, Update, Delete events of Model.
*/
trait ActivityLogger {
/**
* Automatically boot with Model, and register Events handler.
*/
protected static function bootActivityLogger()
{
foreach (static::getRecordActivityEvents() as $eventName) {
static::$eventName(function ($model) use ($eventName) {
try {
$reflect = new \ReflectionClass($model);
return Activity::create([
'user_id' => Auth::id(),
'content_id' => $model->attributes[$model->primaryKey],
'content_type' => get_class($model),
'action' => static::getActionName($eventName),
'description' => ucfirst($eventName) . " a " . $reflect->getShortName(),
'details' => json_encode($model->getDirty()),
'ip_address' => Request::ip()
]);
} catch (\Exception $e) {
Log::debug($e->getMessage());
}
});
}
}
/**
* Set the default events to be recorded if the $recordEvents
* property does not exist on the model.
*
* #return array
*/
protected static function getRecordActivityEvents()
{
if (isset(static::$recordEvents)) {
return static::$recordEvents;
}
return [
'created',
'updated',
'deleted',
'restored'
];
}
/**
* Return Suitable action name for Supplied Event
*
* #param $event
* #return string
*/
protected static function getActionName($event)
{
switch (strtolower($event)) {
case 'created':
return 'create';
break;
case 'updated':
return 'update';
break;
case 'deleted':
return 'delete';
break;
case 'restored':
return 'restore';
break;
default:
return 'unknown';
}
}
}
Please check and advise if anything wrong or could be done in better way.