phpDocumentor 2 tags not working - phpdoc

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.

Related

Laravel swagger annotations into a separate file

I am using DarkaOnLine/L5-Swagger package for project. Here is example annotation
/**
* #OA\Post(
* //annotations etc..
* )
*/
public function login(LoginRequest $request): JsonResponse
{
//login method
}
But using annotations in controllers complicates the code. Is there another way to do it in separate file?
Not sure it complicates things - with separate files you always have to update two different places.
Your annotations can be whereever you like as long as they are associated with structural elements (class, method, etc) so reflection can find them (means you need to create dummy classes, etc if the annotations are separate from the "real" code).
Also, those files need to be found by the bundle but I would expect you can configure multiple path to scan.
The downside for me is that you need to replicate all details, in particular type-hints and keep them in sync.

What is the Laravel trait pattern?

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.

Php storm, navigate function in class with contract

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

Magento source model conventions

I often see two different methods in a source model that appear to do the same thing:
class Mypackage_Mymodule_Model_Source_Generic {
/* I sometimes see this method */
public function getAllOptions() {}
/* And other times this method */
public function toOptionArray() {}
}
In my experience, there's no rhyme or reason as to when which method name is employed; they both appear to return the same data structure.
Is there something I'm missing?
Is there semantic link between a source model's toOptionArray and Varien_Data_Collection::toOptionArray?
Like so many of my answers, this is informed speculation.
The toOptionArray and getAllOptions "source model" split seems like another case of too many chefs in the Magento 1 kitchen. That is, a team of developers working with similar concepts, but with no one in charge of making sure the end result was a solid, consistent system. The problem is there's (at least) two kinds of "source models" in Magento.
First, there's a source model concept in the system configuration system (system.xml files, System -> Configuration, etc) which dictates the options for the system configuration forms. Second, there's a source model concept (more accurately, an attribute source) in the EAV system which, again, dictates options for UI forms, but this time for rendering user interfaces to edit object entries that have a particular attribute.
The system configuration system uses toOptionArray. The EAV system uses getAllOptions. This is reflected in the interfaces provided for the EAV system's source attribute objects.
#File: app/code/core/Mage/Eav/Model/Entity/Attribute/Source/Interface.php
interface Mage_Eav_Model_Entity_Attribute_Source_Interface
{
/**
* Retrieve All options
*
* #return array
*/
public function getAllOptions();
/**
* Retrieve Option value text
*
* #param string $value
* #return mixed
*/
public function getOptionText($value);
}
More importantly than that though is how the objects are used by the system. When Magento renders the UI in the system configuration tabs, it does so with this code
#File: app/code/core/Mage/Adminhtml/Block/System/Config/Form.php
//...
$optionArray = $sourceModel->toOptionArray($fieldType == 'multiselect');
//...
When Magento renders the UI for editing an EAV product object, it does so with code like this
#File: app/code/core/Mage/Adminhtml/Block/Catalog/Product/Edit/Tab/Super/Config/Simple.php
'values' => $attribute->getSource()->getAllOptions(true, true),
So that's two different system developers implementing a similar concept in different parts of Magento. So, when other developers need to create a UI with a select list and aren't intimately familiar with the system conventions, they pick the method they've seen before, which is what leads to the (seemingly) no rhyme or reason pattern you mentioned above. There's also a few cases where Magento core developers working on features have tried to marry the two methods.
#File: app/code/core/Mage/Tax/Model/Class/Source/Product.php
public function getAllOptions($withEmpty = false)
{
//...
}
//...
public function toOptionArray()
{
return $this->getAllOptions();
}
Finally, while there's no official semantic link between Varien_Data_Collection's toOptionArray and the toOptionArray used in the system configuration source models, it seems safe to speculate that since the source models are, in practice, collections of data, that a core developer chose toOptionArray as the method name so (in theory) a Varien_Data_Collection based object could be used as a source model. I suspect if not for performance considerations in PHP 5.2, the models in app/code/core/Mage/Adminhtml/Model/System/Config/Source all would have inherited from Varien_Data_Collection.

phpDocumentor 2.0 Page-level DocBlock - Where is it?

I have a set of classes, each class is in its own file. I've added appropriate DocBlocks so that I get no errors or warnings when I build the documentation. Here is a very simplified example:
<?php
/**
* Page level description.
*/
/**
* Short class description.
*
* Longer description on what this class is all about.
*/
class Test {
// a bunch of code
}
?>
When I run phpdoc on this class, the Page-level DocBlock does not appear anywhere in the generated HTML.
The reason for this is perhaps because version 2.0 is still in Alpha. Can someone enlighten me as to what I'm missing, if in fact I'm missing something?
Btw, I did do my homework on trying to find the answer. I found this post from 2 months ago but it references an earlier version of phpDocumentor, and it doesn't look like the OP specified whether or not it answered the question satisfactorily.
[...] a Page-level DocBlock is the first DocBlock in a file if it contains a #package tag. [...]
<?php
/**
* Page-level DocBlock
* #package pagepackage
*/
/**
* Define DocBlock
*/
define("ahhhh","Now the Page-level DocBlock is for the page, and the Define DocBlock for the define");
?>
Reference:
http://manual.phpdoc.org/HTMLSmartyConverter/HandS/phpDocumentor/tutorial_elements.pkg.html

Resources