I am using this Laravel 4 package for interacting with the Xero accounting application: https://github.com/Daursu/xero
In the GitHub README, it says that you can extend the package easily by using the following code:
namespace Daursu\Xero;
class CreditNote extends BaseModel {
/**
* The name of the primary column.
*
* #var string
*/
protected $primary_column = 'CreditNoteID';
}
I tried adding this as a new Model, but Laravel gives me a Class not found error.
I'm assuming this is a namespacing issue a but can't seem to get it right. I have tried using \Darsu\Xero and also \Darsu\Xero\BaseModel, and other various combinations with and without the initial \.
Any tips on how to do this right?
Easiest way to achieve your intentions:
1) Create a file CreditNote.php in app\models
2) Put the following code in the above file:
use Daursu\Xero\BaseModel;
class CreditNote extends BaseModel {
/**
* The name of the primary column.
*
* #var string
*/
protected $primary_column = 'CreditNoteID';
}
3) Whenever you need to use the CreditNote model, use $creditNote = new CreditNote();
Related
I have an old Laravel app laravel-5.4, I review it recently, and I wondered how did that code was generated for the model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* App\Defect
*
* #property int $id
* #property string $code
* #property string $title
* #property bool $defgroup_id
* #method static \Illuminate\Database\Query\Builder|\App\Defect whereCode($value)
* #method static \Illuminate\Database\Query\Builder|\App\Defect whereDefgroupId($value)
* #method static \Illuminate\Database\Query\Builder|\App\Defect whereId($value)
* #method static \Illuminate\Database\Query\Builder|\App\Defect whereTitle($value)
* #mixin \Eloquent
*/
class Defect extends Model
{//....
I'm pretty sure that I could not able to write all property comments there, but I could not remember how did they had written in the model?!
I tried php artisan make:model Defect but I almost get a plain model without any comments nor relations with about five lines of code.
Could any one able to remember me how could that code with comments was generated?
You can install this composer package:
https://github.com/barryvdh/laravel-ide-helper
Once you have that you can run this, which will generate the doc block similar to the one you listed in your example:
https://github.com/barryvdh/laravel-ide-helper#automatic-phpdocs-for-models
The package a bit more then generate the doc block you mentioned, it helps greatly with IDE code completion, I highly recommend it.
So long story short, I have a model in my Larvel 8 (Jetstream) application called Board. I am trying to generate a factory for this Board model.
When I use either of the commands below:
php artisan make:factory BoardFactory
or
php artisan make:factory BoardFactory --model=Board
I get a factory class generated with seemingly no errors or issues. However, when I open the class it contains nothing to do with the model.
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class BoardFactory extends Factory{
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
//
];
}
}
I have tried this with all the Model's within my application and this persists. Once again no error to say the model is not found. The command seemingly runs successfully but obviously hasn't generated the factory for the Model.
I know I can easily write this manually if needs be, but I would like to understand why this isn't working and how I can fix it. The faster I can get through my testing... the better :)
Thanks in advance for any help.
Try publishing your laravel stubs and confirm that the stub file contents are defined as expected.
Publish the stubs.
php artisan stub:publish
This should create a /stubs folder in the root project directory.
Inside that folder, you will see all stubs.
Most specifically, open the stub file called factory.stub
It's file contents should look something similar to this:
<?php
namespace {{ factoryNamespace }};
use Illuminate\Database\Eloquent\Factories\Factory;
use {{ namespacedModel }};
class {{ factory }}Factory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = {{ model }}::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
//
];
}
}
Notes:
From the looks of it, it appears as if your current factory stub is missing the section(s) below:
// ...
use {{ namespacedModel }};
// ...
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = {{ model }}::class;
// ...
Ideally speaking, in normal (default) cases, running a command that generates a factory with a linked model should look like this:
Command:
php artisan make:factory BoardFactory --model=Board
Expected Output File (database/factories/BoardFactory.php):
<?php
namespace Database\Factories;
use App\Models\Board;
use Illuminate\Database\Eloquent\Factories\Factory;
class BoardFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Board::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
//
];
}
}
Addendum:
As pointed out in a comment by #miken32, in Laravel versions published later than Oct 22, 2021, declaring a model attribute in your Factory class will no longer be necessary:
Laravel Pull Request
At this time, database factories have this hidden feature where
database models can be "guessed".
So, this pull request proposes that remove protected $model from the
Factory stub, as probably the current "guess" logic works for
99.99% of the people. In addition, I've also pull requested to the
skeleton that we remove protected $model = User::class from the
UserFactory.php:
laravel/laravel#5713.
I am looking to extend a trait by using it in another trait. However the trait is using a method that looks like it isn't extending. The trait works, so I am wondering how.
Why does this trait have access to the markEntityForCleanup method?
The code is in this repo for Drupal Test Traits
<?php
namespace weitzman\DrupalTestTraits\Entity;
use Drupal\Tests\node\Traits\NodeCreationTrait as CoreNodeCreationTrait;
/**
* Wraps the node creation trait to track entities for deletion.
*/
trait NodeCreationTrait
{
use CoreNodeCreationTrait {
createNode as coreCreateNode;
}
/**
* Creates a node and marks it for automatic cleanup.
*
* #param array $settings
* #return \Drupal\node\NodeInterface
*/
protected function createNode(array $settings = [])
{
$entity = $this->coreCreateNode($settings);
$this->markEntityForCleanup($entity);
return $entity;
}
}
I found the issue.
When using the Drupal Test Traits package you are expected to use your own custom php-unit bootstrap.php and manually load the required packages.
Adding this line to the bottom of the bootstrap script will gain access to the namespace in php.
// <?php is needed for SO to do the syntax highlighting.
<?php
// Register more namespaces, as needed.
$class_loader->addPsr4('weitzman\DrupalTestTraits\Entity\\', "$root/vendor/weitzman\drupal-test-triats\src\Entity");
I have Silex setup with Doctrine2 ORM. I am trying to build a pagination class that I can use with my entities. I am well aware of the existing pagination classes that exist within Doctrine2 but because this project is for my school research I am trying to create this component myself.
Below is the fatal error I get when accessing this page:
Fatal error: Class 'PlayGround\Model\Helper\UserRepository' not found in D:\web\playground-solutions\vendor\doctrine\orm\lib\Doctrine\ORM\EntityManager.php on line 689
I have defined an interface called PaginateableInterface with two methods count and paginate. I went on to define a custom EntityRepository class that extends Doctrine\ORM\EntityRepository. Below is my custom EntityRepository.
<?php
namespace PlayGround\Service\Doctrine;
use Doctrine\ORM\EntityRepository as ParentEntityRepository;
class EntityRepository extends ParentEntityRepository{
public function count(){
$em = $this->getEntityManager();
$builder = $em->createQueryBuilder();
/**
* ToDo: #entity
*
* Still need to find a better way of getting entity class name.
*/
$entity = $em->getClassMetadata(get_class(__CLASS__))->getName();
//Dynamically get a count of records on any entity we happen to call this on.
$builder->select($builder->expr()->count('e'))
->from($entity, 'e');
$query = $builder->getQuery();
//Try-Catch block ommitted
return $query->getSingleScalarResult();
}
}
<?php
namespace PlayGround\Model\Helper;
use PlayGround\Service\Doctrine\EntityRepository as CustomRepository;
use PlayGround\Contract\PaginateableInterface as IPaginate;
class UserRepository extends CustomRepository implements IPaginate
{
}
In my understanding this should suffice as the count and paginate methods are sitting within the custom repository.
Inside my Paginator class I call the entity I want to paginate as shown below:
<?php
//Paginator class
$model = $this->getModel($model);
//Count should be inherited from CustomRepository aliased object.
$totalRecords = $model->count();
Below is another pierce of meet with regards to this where I add an annotation to my model to point it to the repository class it is suppose to use.
<?php
namespace Application\Model\Entity;
use Doctrine\ORM\Mapping as ORM;
use Application\Model\Entity\UserGroup;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity
* #ORM\HasLifecycleCallbacks()
* #ORM\Entity(repositoryClass="PlayGround\Model\Helper\UserRepository")
*/
class User{ /* Rest of the code goes here... */ }
Given all this setup what could I have missed in getting this to work? I have even ran two commands on my doctrine console but that didn't help either.
Luyanda.Siko#ZACT-PC301 MINGW64 /d/web/playground-solutions
$ php app/Console/bin/doctrine.php orm:clear-cache:metadata
Clearing ALL Metadata cache entries
Successfully deleted cache entries.
Luyanda.Siko#ZACT-PC301 MINGW64 /d/web/playground-solutions
$ php app/Console/bin/doctrine.php orm:clear-cache:query
Clearing ALL Query cache entries
Successfully deleted cache entries.
EDIT:
Below is my file structure found in D:\web\playground-solutions.
You declare twice #ORM\Entity. Once with the repositoryClass and once without. Remove the one without:
#ORM\Entity
and leave this:
#ORM\Entity(repositoryClass="PlayGround\Model\Helper\UserRepository")
#ORM\HasLifecycleCallbacks should be declared without parentheses ()...
Also make sure that the EntityRepository is in the correct namespace and the corresponding folder:
your namespace is PlayGround\Model\Helper\UserRepository meaning the file should be in folder PlayGround\Model\Helper and the class file name should be UserRepository.php.
Fix and check that and if it still doesn't work leave a comment.
UPDATE:
Your UserRepository is in the wrong module. Is now in app should be in PlayGround
The file should be in:
src/PlayGround/Model/Helper/UserRepository.php
It's all about that problem.
Clearly this has really consumed my thought process. All I was doing was pointing to an incorrect namespace as pointed out by #Witt.
I changed my annotation entry in the User entity and the error went away.
<?php
/** #ORM\Entity(repositoryClass="Application\Model\Helper\UserRepository") */
Thanks you guys.
So I'm just starting off with Laravel (using v5) and Eloquent. I'm working on getting some basic APIs up and running and noticing that a lot of working methods don't show up in PhpStorm's code hinting
So I have this model:
namespace Project\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model
implements AuthenticatableContract, CanResetPasswordContract {
}
And in one of my controllers I try to do
User::query()->orderBy('id', 'desc');
User::query() creates a Eloquent Builder object and orderBy() behave properly and without error. However, PhpStorm does not show orderBy() (or take(), skip(), and I'm sure others) when I type User::query()-> and gives warnings when I actually do use it.
I am using Laravel IDE Helper which has helped immensely with bringing code hints to the Facades, but not to the models/builders it would seem.
Does anyone have a solution to this?
For future Googlers, and perhaps OP as well if you are still sticking to Laravel.
The laravel-ide-helper package solves this issue for you quite elegantly, with what I believe is a relatively new feature; generated model PHPDocs.
You can generate a separate file for all PHPDocs with this command:
php artisan ide-helper:models
The generated metadata will look something like this for each class:
namespace App {
/**
* App\Post
*
* #property integer $id
* #property integer $author_id
* #property string $title
* #property string $text
* #property \Carbon\Carbon $created_at
* #property \Carbon\Carbon $updated_at
* #property-read \User $author
* #property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
*/
class Post {}
}
This caused issues for me in PHPStorm however, where the software was complaining about multiple class definitions. Luckily an option is readily available for writing directly to the model files:
php artisan ide-helper:models -W
There are a few more options and settings available if you need to tweak the behavior, but this is the gist of it.
Add in model PHPDoc#mixin
/**
* Class News
* #property int $id
* #property string $created_at
* #property string $updated_at
* #mixin \Eloquent
* #package App
*/
class News extends Model
{
}
In PHPStorm works
You can try Laravel plug-in for PhpStorm and you need to specifically activate it in your project settings.
If you're using BarryVHD's Laravel IDE Helper package, run:
php artisan ide-helper:eloquent
This will write /** #mixin \Eloquent */ into the vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php file.
A little late but I recently had the same problem so I thought I would put a note down:
This is because Database\Eloquent\Model.php has a query() function which returns \Illuminate\Database\Eloquent\Builder and the Eloquent\Builder has a line:
use Illuminate\Database\Query\Builder as QueryBuilder;
Then it uses 'magic' __call methods to call to functions in Query\Builder. (look for __call method in Eloquent\Builder)
See:
http://php.net/manual/en/language.oop5.overloading.php#object.call
__call() is triggered when invoking inaccessible methods in an object context.
So, indeed the method you are calling is inaccessible :) There is not much that the IDE can do.
There are workarounds like using #method tags but it is unmaintainable. An alternative is to use #mixin (but this is not standards based).
See: https://github.com/laravel/framework/issues/7558
I think this all be resolved when they get rid of all the magic calls in the Laravel code and use PHP 'traits' instead. See last message here. :)
Just import Eloquent Builder in your Model class and add mixin:
use Illuminate\Database\Eloquent\Builder;
/** #mixin Builder */
To cover all the models at once — add the mixin to the src/Illuminate/Database/Eloquent/Model.php)
I wanted to have some kind of explicit "casting" when interacting with the query builder. Example...
$user = User::query()->findOrFail($id);
$user->myUserSpecialMethod(); // <-- IDE syntax error
Since all my models are extending my custom base Model which in turn extends Eloquent, I've ended up creating this method in my custom base model:
/**
* Explicit type-hinting
*
* #return static
*/
static public function hint(BaseModel $model)
{
return $model;
}
This way, it solves the IDE invalid error and helps me:
$user = User::hint(User::query()->findOrFail($id));
$user->myUserSpecialMethod(); // <-- all OK !
Please note that this is not OOP type casting. It is only a hint to help the IDE. In my example, the returned Model was already a User. If I woud use this method on a derived class like SuperUser, only the IDE will be fooled...
An nice alternative also is to put meta information directly over the assignment statement:
/** #var User $user */
$user = User::query()->findOrFail($id);
$user->myUserSpecialMethod(); // <-- all OK !
Or next to it...
$user = User::query()->findOrFail($id); /** #var User $user */
$user->myUserSpecialMethod(); // <-- all OK !
Verified on Laravel 8, just added #mixin Builder to Illuminate\Database\Eloquent\Model.php annotation solved it.
// Illuminate\Database\Eloquent\Model.php
/**
* #mixin Builder
*/
abstract class Model