I did'nt found any method in phpStorm to go to function definition while class I'm using is a contract, and the class i want to go to is bind behind the scenes thru laravel IOC container. How to tell PhpStorm that definition is in other folder? Interface and class implementing interface have the same names.
You can use type hinting for PHPStorm this way:
/** #var \App\Class\ConcreteObject $object */
$object= App::make(\App\Contracts\SomeContract::class);
Now PhpStorm will know $object is \App\Class\ConcreteObject object and you will be able to see all the methods from this object when using PhpStorm
EDIT
Looking at sample from comment you should use:
/** #var \proj\Repositories\definitions\UsersRepository $object */
$object= App::make(\proj\Repositories\contracts\UsersRepository::class);
$object->saveInfo();
to make PhpStorm go to valid saveInfo method
Related
The vendor's code looks like this:
/**
* Create a new SendEmailsCommand instance.
*
* #param Store $store
*/
public function __construct(Store $store)
{
parent::__construct();
$this->store = $store;
}
But when I invoke this command with say php artisan mail:send, where does the value of $store come from? Is this what is meant by this cryptic documentation quote?
Note that we are able to inject any dependencies we need into the
command's constructor. The Laravel service container will
automatically inject all dependencies type-hinted in the constructor.
I see that Laravel (5.2) documentation on console commands seems to do a similar thing with an object called Drip ... https://laravel.com/docs/5.2/artisan#command-structure
Is Laravel taking upon itself to realize that there's a type-name given to the constructor, and it automagically instantiates a corresponding object instead of expecting your constructor to do so itself?
Thank you, fubar. My assumptions were correct.
More specifically when doing this from inside a model.
$this->myRelationship->
I would expect at this point in typing that I should get a list of all the eloquent collection methods but I do not.
I currently have the PHP Intelephense plugin installed. What am I missing here?
Intelephense sees the myRelationship() method but doesn't see it as a property because that property is resolved in the __get magic method. What you can do is document it above the model like:
/**
* #property \Illuminate\Database\Eloquent\Collection $myRelationship
*/
class YourModel extends Model ...
and then you will have the autocomplete. Also this package can help you.
I suggest laravel-ide-helper
It can creates phpDocs automatically like below.
php artisan ide-helper:models
So your intellisense(for me: PHP Intelephense) can recognize your model's properties.
See it's Documentation for details
While looking at the Laravel source, I noticed a lot of stuff like this:
A controller class:
class Controller extends BaseController
{
use AuthorizesRequests, AuthorizesResources, DispatchesJobs, ValidatesRequests;
}
One of its component traits:
trait AuthorizesRequests {
/**
* Authorize a given action against a set of arguments.
*
* #param mixed $ability
* #param mixed|array $arguments
*
* #return \Illuminate\Auth\Access\Response
*
* #throws \Illuminate\Auth\Access\AuthorizationException
*/
public function authorize($ability, $arguments = []) {
list($ability, $arguments) = $this->parseAbilityAndArguments($ability, $arguments);
return app(Gate::class)->authorize($ability, $arguments);
}
// ...
}
I have a couple of questions about this:
Does this pattern (abstracting re-usable functionality into traits) have a name?
Is this pattern used to good effect in any other projects?
If a trait requires dependencies, is there a best-practise way to inject them, instead of using a service locator (like app(), in this case)?
I'm considering using this approach in my code to share some general functionality between a couple of my classes - I'm considering creating a ChecksBarcodes trait, which will work with a repository of stock information, and sharing that trait between a few similar but unrelated product management process classes, which all need to check barcodes.
Traits, being introduced with PHP 5.4, in general solving one big problem of PHP: single inheritance. A rough guess from me: if PHP would support multi inheritance (inherit from more than one class) there wouldn't be traits.
Nevertheless, traits are a good thing to reduce duplications of code and furthermore provide same fuctionality to multiple classes.
As far as I can see, there is no real (pattern) name for using traits.
It is not a pattern per se, as compared to other Software design pattern, just call it traits ;)
Laravel and maybe more specifically the Cashier package are good examples of using traits. If somebody finds other good examples please mention it.
Traits can be extended by other traits. That of course creates more and more complexity. To extend you probably should consider other methods to bring a functionality to your class. "Chaining" of traits adds load of complexity.
Traits are similar to extending classes, but with a few differences
Traits don't have a constructor
Classes can only extend one class, but have multiple traits
They're similar to mixins in other languages. I guess you could say its an easy way to use the DRY principle.
Since traits don't have constructors, any dependencies they have would need to exist on the class they're used on. I think depending on the class to have something other than the trait would be a bad design pattern. So you would have to use a service locator to pull in dependencies.
If you would rather not use a service locator, I would recommend using a class rather than a trait. You could have a BarcodeChecker class that you could inject into the constructor of the classes you want to use it. Then instead of $this->checkBarcode() you would use $this->barcodeChecker->check(). I think that would be a better design pattern if the trait requires dependencies.
I have a class called Awesome and have used the ServiceProvider and the Facade to register it to the app. Now I can use it as Awesome::Things().
I want to add constants to this class, so I tried
<?php namespace Helper\Awesome;
class Awesome()
{
public static $MOVIE = 'I love the Lego Movie!";
}
but when I call Awesome::$MOVIE, I get Access to undeclared static property: Helper\\Aesome\\Facades\\AwesomeFacade::$MOVIE
Can someone help?
The short version is -- you don't really want to do that. Laravel facades aren't mean to be used like normal classes, and if your application uses them that way you'll likely confuse future developers.
Warning out of the way. When you create a "facade" in Laravel, you're actually creating a class alias. When you added Awesome to the alias list in app/config/app.php, at some point code like the following ran
class_alias('Helper\Aesome\Facades\AwesomeFacade','Awesome');
That means whenever you use a global non-namespaced class Awesome, PHP substitutes Helper\Aesome\Facades\AwesomeFacade. If you wanted to add constants, you'd need to add them to this class.
Laravel's able to pass through methods because of the base Facade class implements a __callStatic method that passes on your call to the actual service implementation object. Facades don't pass on static constant access. Additionally, PHP does not (appear to?) have similar magic methods for passing along requests for constants.
If you're curious about the in depth version of this answer, I'm currently writing a series on Laravel's object system, including some in-depth information about the facade implementation.
I installed phpDocumentor 2 using Pear as described on phpdoc.org. When doing so, I compiled my comments
/**
* Calls class1
* #see class2
* #access public
*/
class class1 {
}
/**
* Calls class2
* you can {#link class1}
*/
class class2 {
}
The first one does not work unless you say #see class2 Class 2, and the second one would not work regardless. It just prints like it looks, not reading the curly brackets as inline tags. So, my question is - am I doing something wrong here? Is anyone else running into something similar? I downloaded phpDocs 1.x and did not have this problem, but I'd like phpDocs 2 if possible..
Thanks!
phpDocumentor 2.x has not yet implemented the inline link tag ("{#link}") that was available in 1.x. It's on the TODO list. I would suggest using the #see tag here also, though obviously you can't do so as an inline tag.
I would expect the #see tag to work fine with only the target class name ("#see class2"), without requiring description text ("#see class2 Class 2"). I would consider the behavior you describe to be a bug, which could be reported here -- https://github.com/phpDocumentor/phpDocumentor2/issues
Incidentally, the #access tag has no context with regard to a class itself. Visibility scope of public/protected/private only applies to class methods and class properties, not to a class itself. Further, it was added to phpDocumentor 1.x back in the PHP4 days, before such visibility scope was available in PHP at all (that was added in PHP5). Therefore, it's not actually useful anymore. Even in 1.x, if run using PHP5 against code written for PHP5, the code scope keywords would override whatever an #access tag said. I don't believe that phpDocumentor 2.x even bothered implementing the #access tag, and rightly so.