Doxygen not recognize PHP Class in static array storage - php

In my PHP project im using a Class factory that stores the object instances inside an object member of a static class. This member is an array and if for example i gonne instance lib/log.php (class log {....) it will be accessed like
glob::$data["lib/log"]
Since im using this structure all over my project i want doxygen to recognize the calls for the call/caller graphs and for linking the functions. In my code i currently do like
glob::$data["lib/log"]->info("info to log.......");
Wich i realized wont be recognized by doxygen so i tried modify the code to structure like:
$libLog = glob::$data["lib/log"];
$libLog->info("info to log......");
And adding source comments to tell the code wich instances of classes im using here. I tried in both ways like
/* #var $libLog log */
same as
/* #var log $libLog */
since i found examples refering to both of that. None of them worked. The log class itself gets recognized and is inside the Class list so it can't be an recognation error.
If anyone has idea how i can make doxygen recognize those calls or a hint to another stack posting that solves this problem i would be really gratefull!

Related

VSCode extension Intelephense gives error "Undefined method 'xxx'. Intelephense (1013)" with polymorphism and dynamic binding

I'm developing a PHP (v7.0.33) project using VScode (v1.56). I recently installed the VSCode's extension Intelephense (v1.7.1) and started to clean my code following Intelephense suggestions.
A set of classes inside my project has the following structure (function names are not real, but just to let you see that for each sublcass I have some function overrided from the superclass (those with the prefix baseFunction) and new functions specific for that subclass (those with the class acronym like fdmSpecificFunction):
According to the diagram, each DocumentSaver has an instance of a DocumentManager.
The code where I create an instance of, for example, FatturaVenditaDocumentSaver is
$documentManager = new FatturaVenditaDocumentManager();
$documentSaver = new FatturaVenditaDocumentSaver($documentManager);
$documentSaver->baseFunction1();
Consider the following code inside FatturaVenditaDocumentSaver:
public function baseFunction1() {
parent::baseFunction1();
$this->documentManager->fvdmSpecificFunction1();
}
This is a common implementation in OOP, using polymorphism and dynamic binding: having created the instance of FatturaVenditaDocumentSaver with a document manager instantiated from FatturaVenditaDocumentManager, the call $documentSaver->baseFunction1() will execute the code implemented in FatturaVenditaDocumentSaver and, inside it, will correctly execute the code inside fvdmSpecificFunction1() implemented in FatturaVenditaDocumentManager.
The problem is that Intelephense, as fvdmSpecificFunction is not defined in BaseDocumentManager, gives me the error "Undefined method 'fvdmSpecificFunction1'. Intelephense (1013)".
Is there a way to let Intelephense understand the real implementation of my code (considering that Intelephense parse all my PHP code)? I'd like to avoid to disable the Intelliphense's "undefined method" check and I don't like to add an empty fvdmSpecificFunction1 in BaseDocumentManager as is not consistent with the project's logic.
Thank you in advance for your help.
Solution found!
I had just to add the #property hint before the class block, specifying the type of the object $documentManager.
/**
* #property FatturaVenditaDocumentManager $documentManager
*/
class FatturaVenditaSaver extends FatturaSaver {
public function baseFunction1() {
parent::baseFunction1();
$this->documentManager->fvdmSpecificFunction1();
}
}
In this way, Intelephense understands the real class related to that object.

Is it possible to load docstrings for a class from a different file in PHP (PhpStorm/IntelliJ)?

In my Laravel application I created a script that exports the attributes of my model classes to TypeScript interfaces. Thanks to those interfaces, my IDE knows which attributes the TypeScript objects should have.
Now, I'd like to go a step further and have my IDE also know about the attributes for each PHP class. For this, I'd like to create PHP Docstring definitions in separate files and link them to the actual class file. The linking would be okay to set manually.
My directory structure would look like this:
/classes/MyModel.php
/definitions/MyModel.php
The definition file for the class should only contain the Docstrings for the class:
// file: /definitions/MyModel.php
/**
* #var string $myStringAttribute
*/
Now, I'd like to include this generated file somehow in the class MyModel, so any IDE can know which attributes the Model can access from the DB. I already tried including the definitions file with include __DIR__ . '/../definitions/MyClass.php' but this did not work.
Outputting the Docstring definitions in the actual class file is not really an option for me. With separate files, I would just need to add a single line of code to the classes to link the definitions.
Is there a way of doing this that could work? Or maybe there are plugins for my IDE (PhpStorm/IntelliJ) which could do this (official Laravel Plugin did not do this)?
This is a quality-of-life question. I know I could write the docstrings for each class myself, but I prefer to have them generated automatically to be on par with the actual model definition in the database without manual work.

PhalconPHP - getRouter in \Phalcon\Di

I've created new project using PhalconPHP 3.1.2. Everything works fine, but I have problem with IDE. In PhpStorm I've added ide/stubs/Phalcon from phalcon-devtools 3.1.2 as external libraries to dispose of warnings and errors.
But there is still one problem: in app/config/router.php (standard catalog structure created by devtools) I got line $router = $di->getRouter(); (also created by devtools) with warning: Method getRouter not found in Phalcon\Di\FactoryDefault.
There is no method in this class indeed: https://github.com/phalcon/phalcon-devtools/blob/3.1.x/ide/stubs/Phalcon/di/FactoryDefault.php -> https://github.com/phalcon/phalcon-devtools/blob/3.1.x/ide/stubs/Phalcon/Di.php
Now I don't have autocomplete of router's methods and this is problem for me. Did I do something wrong?
First of all -- I'm not familiar with Phalcon. These are my comments based on general PHP/PhpStorm experience.
So .. if you look at that PHPDoc in the last link you gave (stubs for Di.php) you will notice the code example there that has $request = $di->getRequest();.
If you just copy-paste that whole sample you will get the same "method not found" error ... as getRquest() is transformed at run time via magic __get() method.
The possible solution here is to create your own stub for your $di:
Create new class that will extend original Di, e.g.
class MyDi extends \Phalcon\Di
Add all those getRoute() / getRequest() etc methods there (could be real methods with empty bodies as in Phalcon's stub files .. or via #method PHPDoc tag)
Place such file anywhere in the project -- it will be used by IDE only.
When you are using your $di -- typehint it with your class, e.g.
/** #var \MyDi $di */
$di = new Di();
In the above code during runtime $di will be an instance of Di but for PhpStorm during development it will be MyDi so all type hints are in place.
As possible alternative -- instead of using magic via $di->getRoute() .. try $di->getShared('route') or similar.
If you use PhpStorm's Advanced Metadata functionality it will allow to get correct type based on parameter value.
$di->getRouter() is magic method, Phalcon\Di implements __call method and it gets router service this way if you use getRouter().
If you want you can use PHPStorm metadata and use $di->get() https://www.google.pl/search?client=opera&q=phpstorm+metadata&sourceid=opera&ie=UTF-8&oe=UTF-8

log4php renderer unable to convert object to string

I am using log4php and within my objects, I would like to log the object variables upon entry and exit of a method (for debug purposes). I came across log4php's renderer functionality and thought it would be a great idea but I am unable to get it to work.
public function someMethod() {
$this->logger->debug($this); //entry log
... do something ...
$this->logger->debug($this); //exit log
}
The application throws an error stating that log4php cannot convert the object to a string. Should I be doing something else in order for the renderer to work?
A point to note - the object does have several private and protected variable - no public variables. Perhaps this is an issue - but then I didnt note that statement anywhere in the docs.
Thanks in advance
Unless you extending or inheriting from it, private shouldn't be a problem.
And unless you're directly accessing a protected function inside the class it resides, that can't be either.
In any case, I'm guessing that you're trying to print something out. That error happens when you're trying to echo out an object(PDO thought me that one).
not being able to comment kinda of sucks

Using Laravel 4 models in custom classes / subsystems without class dependency

I'm building a parser system that will parse loads of different XML/JSON feeds upon request/cronjob.
I use Laravel 4.
The purpose of the thread is to use IoC in my context, and not hardcoded Model names in custom-class methods
Providing an example of parser for Soccer Player with XML structure like:
<players category="Midfielders">
<player id="777">
<name>Caio Augusto Paim do Santos</name>
<statistic>
<club name="Camaçari" id="7191" league="Baiano 2" league_id="1136" season="2013" minutes="" appearences="" lineups="" substitute_in="" substitute_out="" substitutes_on_bench="" goals="" yellowcards="" yellowred="" redcards=""/>
I've created an additional directory in my /app folder called /parsers These are custom classes, they all extend or implement custom abstracts/interfaces in the same folder and basically are responsible for receiving path to XML/JSON file and returning a well-structured PHP arrays.
They are added in composer.json in autoload as: "app/parsers"
Screenshot of file structure attached
All is good and the code/classes are testable and not dependent on another classes, but here's the problem.
Checkout the XML example, there's thing like:
<club id="XXX" league_id="YYY" />
this is feed club id and feed league id, but I have my own IDs in database referenced to feed IDs.
Like on this screenshot:
So the logic says: Go to database, check if there's id in league league table with feed_id provided from XML file.
If yes, get it, if not, create a new league and get the id for future references.
This requires me to use Model in my parser classes, now I know you can use IoC and inject models into Controllers, but I'm not sure I can do the same with my parser classes...
So doing something like this in the middle of my parser class:
// Try to get league and season ids from database if they already exists, if not, insert
$leagueId = DB::select('SELECT id FROM league WHERE feed_id=?', array($data['league_id']));
or
$league = new LeagueModel();
Is pretty much incorrect.
Now just to clarify the way it all works, my parsers are getting called in Laravel Command classes like this:
/**
* Execute the console command.
*
* #return void
*/
public function fire()
{
$this->setParser();
$this->setStorage();
$this->parser->parseFile($file);
}
And Laravel Command classes are getting called in my Controllers like:
$stamps = $this->getStamp();
Artisan::call('command:getSoccerPlayer',array('stamps' => $stamps, 'parser_id' => Request::segment(2)));
The Controller itself is called via URI:
/jobs/soccer_player/parse?type=soccer&directory=players
**What do you suggest or how would you overcome this issue to avoid dependencies and still use Models for interactions with the database in this context? **
P.S Please don't pay attention that the whole parse logic on my screenshot is in the same method "parse" now, I will break it into pieces once I see the full picture of how I want it to work/look.
Appreciate any help!
you can still call your namespaced models
use App\Models\League;
class SoccerPlayerParser extends AbstractParser{
//...
public function parse()
{
//...
$league = App\Models\League::find($data['league_id']);
//...
}
//....
}
I see two possible solutions here, but am not 100% sure how to integrate it in your project.
The first is to store the name of the model class to use in a config file and intantiate the model via new $class where $class is a value retrieved via Config::get or similar. This solution is very common in packages, and even Laravel itself uses it (see the model setting in app/config/auth.php).
The other is to not instantiate the model, but instead create an interface for it and then dependency-inject it into your command. You can easily auto-inject stuff into your commands by using Artisan::resolve('MyNamespace\MyCommand') instead of Artisan::add(new MyCommand), and then inject via type hinting as you do via controllers. http://laravel.com/docs/ioc#practical-usage
Once you've set up the interface as an argument to the command's constructor, you can use App::bind('MyInterface', 'MyModel') to tell Laravel which class to inject, and this can be swapped at any point.

Categories