Laravel - class in namespace not found - php

I have this model class (the filename is Audit.php):
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
abstract class AuditStatus
{
const UNKNOWN = "UNKNOWN";
const ERROR = "ERROR";
const WARNING = "WARNING";
const MSG = "MESSAGE";
const EXCHANGE_UPDATE = "EXCHANGE_UPDATE";
const PRICE_UPDATE = "PRICE_UPDATE";
}
class AuditCodes extends AuditStatus
{
}
class Audit extends Model
{
use HasFactory;
public $timestamps = false;
protected $fillable = ['action', 'msg'];
public static function Add($action, $msg){
(new static)::insert(['action'=>$action, 'msg' => $msg]);
}
}
And im trying to make a new command like this:
<?php
namespace App\Console\Commands;
use App\Models\AuditCodes;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class PriceCreate extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'price:create';
/**
* The console command description.
*
* #var string
*/
protected $description = 'Create prices';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return int
*/
public function handle()
{
dd(AuditCodes::MSG);
}
}
but when I run the command the compiler throws this error:
Error
Class "App\Console\Commands\App\Models\Audit\Audit_Codes" not found
at C:\xampp\htdocs\bintest\app\Console\Commands\PriceCreate.php:46
Can anyone help me on how to declare my class?
Thanks!!!

Try to declare each class in its own file.
I mean if you have three classes: Audit, AuditCodes and AuditStatus
You will also have three different files in App\Models\ directory, like that App\Models\Audit.php, App\Models\AuditCodes.php and App\Models\AuditStatus.php.
It should be solve your problem.

Related

Error in Laravel 8. Undefined constant App\Models\Person::token

namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Person extends Model
{
private static $token = 'PWPu3Wl71N39x3M';
public static function getToken() {
return self::token;
}
}
How can I get token?
I don't want made constant, I need private static $token = 'PWPu3Wl71N39x3M';
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Person extends Model
{
/** #var string */
private const TOKEN = 'text';
/**
* #return string
*/
public static function getToken(): string
{
return self::TOKEN; // text
}
}
/**
* Usage
*/
Person::getToken(); // text

Protected Properties PHP Laravel

How can access properties of a protected object PHP while writing tests. Below is my sample code.
TestCase.php The test fails to run saying that the property is protected. But it can die dumped.
<?php
namespace Tests;
use Illuminate\Http\Response;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
public function getAuthUser()
{
$payload = [
'email' => 'admin#gamil.nl',
'password' => 'password',
];
return $this->json('post', 'api/v1/auth/login', $payload)
->assertStatus(Response::HTTP_OK);
}
}
my sample test
<?php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Http\Response;
class PatientsControllerTest extends TestCase
{
/**
* A basic unit test patient controller.
*
* #return void
*/
public function testPatientFetch()
{
$auth_user = $this->getAuthUser();
dd($auth_user->data);
}
}
my sample code
<?php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Http\Response;
class PatientsControllerTest extends TestCase
{
/**
* A basic unit test patient controller.
*
* #return void
*/
public function testPatientFetch()
{
$auth_user = $this->getAuthUser();
dd($auth_user->data);
}
}
Error received
FAIL Tests\Unit\PatientsControllerTest
⨯ patient fetch
---
• Tests\Unit\PatientsControllerTest > patient fetch
PHPUnit\Framework\ExceptionWrapper
Cannot access protected property Illuminate\Http\JsonResponse::$data
at vendor/phpunit/phpunit/phpunit:98
94▕ unset($options);
95▕
96▕ require PHPUNIT_COMPOSER_INSTALL;
97▕
➜ 98▕ PHPUnit\TextUI\Command::main();
99▕
Tests: 1 failed
Time: 1.05s
You can access and manipulate protected variables with ReflectionClass.
Please try this:
$user = $this->getAuthUser();
$reflectionClass = new ReflectionClass($user);
//If we assume we have a protected variable $data we can get access it with Reflection Class
$property = $reflectionClass->getProperty('data');
$property->setAccessible(true); //Here we are making protected variables accessible
$property->setValue($user, 'New Protected Data');
create getter function for $data
public function get_data(){
return $this->data;
}
unit test to test functions and not properties

Laravel How to Test Static Query Builder Methods?

I have the following single responsibility repository class
<?php
namespace App\Launches\Repositories\Customer;
use App\Launches\Models\Customer\Subscription;
use Illuminate\Support\Collection;
final class GetSubscriptionRepository
{
/**
* #param int $productId
* #return Collection
*/
public function byProductId(int $productId): Collection
{
return Subscription::where('product_id', $productId)->get();
}
}
I want to be able to test that method, to make sure the object retrieve is the one I've asked. So I've done the following:
<?php
namespace Tests\Unit\Launches\Repository\Customer;
use App\Launches\Models\Customer\Subscription;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Collection;
use Tests\TestCase;
use App\Launches\Repositories\Customer\GetSubscriptionRepository;
class GetSubscriptionRepositoryTest extends TestCase
{
use RefreshDatabase;
/**
* #var GetSubscriptionRepository
*/
protected $getSubscriptionRepository;
/**
* #var Collection
*/
protected $subscriptionCollection;
public function setUp(): void
{
parent::setUp();
$this->getSubscriptionRepository = new GetSubscriptionRepository();
$this->subscriptionCollection = factory(Subscription::class, 20)->make();
}
/**
* #covers GetSubscriptionRepository::byProductId
*/
public function testSubscriptionIsPickedById()
{
$randomSubscription = $this->subscriptionCollection->random(1)->first()->toArray();
$pickedSubscription = $this->getSubscriptionRepository->byProductId($randomSubscription['id']);
$this->assertEquals($randomSubscription['id'], $pickedSubscription->get('id'));
}
}
It's always returning null on $this->getSubscriptionRepository->byProductId($randomSubscription['id']);
It is obviously expecting stuff to be in the database, is there a way to test it without adding stuff to the database?

Laravel $schedule to read/send email

I´m trying to create $schedule job in Laravel to read Email with PHP IMAP package. If I go to route, package read email and does all correctly, but need to do this every 5 minutes.
I create a new command class and add this
use Illuminate\Http\Request;
class ReadMail extends Command implements SelfHandling {
protected $name = 'read:mail';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the command.
*
* #return void
*/
public function fire()
{
$request = Request::create($this->option('App\Http\Controllers\MailController#index'), 'GET');
$this->info(app()['Illuminate\Contracts\Http\Kernel']->handle($request));
}
In kernel
protected $commands = [
'App\Console\Commands\ReadMail',
];
protected function schedule(Schedule $schedule)
{
$schedule->call('read:mail')
->everyFiveMinutes();
}
I'm not sure if this code it´is correct, but does not work properly. Any idea about it?
Thank in advance for your help.
UPDATE
I launch this
php artisan read:mail and return
Argument 1 passed to Illuminate\Console\Application::add() must be an instance of Symfony\Component\Console\Command\Command, instance of App\Commands\ReadMail given
The code of ReadMail class
<?php namespace App\Commands;
use App\Commands\Command;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Http\Request;
class ReadMail extends Command implements SelfHandling {
protected $signature = 'read:mail';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Execute the command.
*
* #return void
*/
public function fire()
{
$request = Request::create($this->option('App\Http\Controllers\MailController#index'), 'GET');
$this->info(app()['Illuminate\Contracts\Http\Kernel']->handle($request));
}
}
UPDATE 2: SOLVED - ALL CODE
Kernel
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel {
/**
* The Artisan commands provided by your application.
*
* #var array
*/
protected $commands = [
'App\Commands\ReadMail',
];
/**
* Define the application's command schedule.
*
* #param \Illuminate\Console\Scheduling\Schedule $schedule
* #return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('read:mail')
->everyFiveMinutes();
}
}
ReadMail
<?php namespace App\Commands;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Http\Request;
use Illuminate\Console\Command;
use App\Http\Controllers\MailController;
class ReadMail extends Command implements SelfHandling {
protected $name = 'read:mail';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the command.
*
* #return void
*/
public function handle()
{
MailController::index();
}
}
MailController
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use PhpImap\Mailbox as ImapMailbox;
use App\Models\Escalas;
class MailController extends Controller {
public static function index()
{
$mailbox = new ImapMailbox('{imap.gmail.com:993/imap/ssl}INBOX', '', '','');
$mailsIds = $mailbox->searchMailbox('UNSEEN');
if(!$mailsIds) {
die('Mailbox is empty');
}
$mail=[];
foreach ($mailsIds as $index=>$data){
$mail[]=$mailbox->getMail($mailsIds[$index]);
Escalas::insert([
['' => $mail[$index]->textPlain,
'' => $mail[$index]->date,
''=>$mail[$index]->subject,
''=>$mail[$index]->fromName,
''=>$mail[$index]->fromAddress,
''=>$mail[$index]->toString],
]);
}
}
}
Try changing
protected $name = 'read:mail';
with protected $signature= 'read:mail';
in your ReadMail class and then run in Kernel like this
$schedule->command('read:mail')->everyFiveMinutes();
Check whether your scheduled tasks are set up properly (see docs for Laravel 5.0) Make sure you've added a cronjob to trigger Laravel's scheduled commands. To check you cronjobs are running, look for a file like /logs/crond.log. When opening this file, you should see lines showing at what times this ran. This is the command that triggers Laravel's scheduled jobs.
If all that is correct, then try running your command via your terminal on localhost to check the command is all set. This should reveal any problems with the command setup. Your functionality itself seems allright, since you mentioned everything works when triggered via a route.

How do I solve "Target [Interface] is not instantiable" in Laravel 4?

My error message:
Illuminate \ Container \ BindingResolutionException
Target [Project\Backend\Service\Validation\ValidableInterface] is not instantiable.
I understand that interfaces and abstract classes are not instantiable so I know that Laravel should not be trying to instantiate my interface. Yet somehow it's trying to and I suspect this may be a binding issue...even though I believe I have bound it correctly and have registered it as a service provider.
I should mention that I have taken this example out of Chris Fidao's "Implementing Laravel" and it's almost identical!
This is the first couple of lines of my form class:
namespace Project\Backend\Service\Form\Job;
use Project\Backend\Service\Validation\ValidableInterface;
use Project\Backend\Repo\Job\JobInterface;
class JobForm {
/**
* Form Data
*
* #var array
*/
protected $data;
/**
* Validator
*
* #var \Project\Backend\Form\Service\ValidableInterface
*/
protected $validator;
/**
* Job repository
*
* #var \Project\Backend\Repo\Job\JobInterface
*/
protected $job;
public function __construct(ValidableInterface $validator, JobInterface $job)
{
$this->validator = $validator;
$this->job = $job;
}
This is the first few lines of my validator class:
namespace Project\Backend\Service\Form\Job;
use Project\Backend\Service\Validation\AbstractLaravelValidator;
class JobFormValidator extends AbstractLaravelValidator {
// Includes some validation rules
This is the abstract validator:
namespace Project\Backend\Service\Validation;
use Illuminate\Validation\Factory;
abstract class AbstractLaravelValidator implements ValidableInterface {
/**
* Validator
*
* #var \Illuminate\Validation\Factory
*/
protected $validator;
/**
* Validation data key => value array
*
* #var Array
*/
protected $data = array();
/**
* Validation errors
*
* #var Array
*/
protected $errors = array();
/**
* Validation rules
*
* #var Array
*/
protected $rules = array();
/**
* Custom validation messages
*
* #var Array
*/
protected $messages = array();
public function __construct(Factory $validator)
{
$this->validator = $validator;
}
This is the code where I bind it all to the app:
namespace Project\Backend\Service\Validation;
use Illuminate\Support\ServiceProvider;
use Project\Backend\Service\Form\Job\JobFormValidator;
class ValidationServiceProvider extends ServiceProvider {
public function register()
{
$app = $this->app;
$app->bind('Project\Backend\Service\Form\Job\JobFormValidator', function($app)
{
return new JobFormValidator($app['validator']);
});
}
}
This is then registered in app/config/app.php:
.....
'Project\Backend\Service\Validation\ValidationServiceProvider',
....
Finally these are the first few lines of my controller:
use Project\Backend\Repo\Job\JobInterface;
use Project\Backend\Service\Form\Job\JobForm;
class JobController extends \BaseController {
protected $jobform;
function __construct(JobInterface $job, JobForm $jobform)
{
$this->job = $job;
$this->jobform = $jobform;
}
You need to tell Laravel which instance it should use for a certain interface when injecting it into the constructor via type hinting.
You do this using the bind() method (in your service provider for example)
$app->bind('JobInterface', 'Job'); // Job being the class you want to be used
I highly recommend you watch the video here where Taylor Otwell, the creator of Laravel, explains this and some other things.
First you need to bind using
/app/Providers/AppServiceProvider.php
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider {
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
$this->app->bind('JobInterface', 'Job');
}
}
Once you complete this change
Run composer update

Categories