phpphpdoc

Expanding the PHPDoc of a PHP class what found in a Composer package


There is a Illuminate\Database\Schema\ColumnDefinition class in the laravel/framework package. How can I extend its PHPDoc @method annotations externally? This is a special class by Fluent, for example, the mentioned ->autoIncrement() function also accepts a boolean parameter, and I need the IDE not to show a warning when running ->autoIncrement(false). I don't want to manually disable the IDE warning for that usage, so I am looking for a global solution.

<?php

namespace Illuminate\Database\Schema;

use Illuminate\Support\Fluent;

/**
 * @method $this after(string $column) Place the column "after" another column (MySQL)
 * @method $this always(bool $value = true) Used as a modifier for generatedAs() (PostgreSQL)
 * @method $this autoIncrement() Set INTEGER columns as auto-increment (primary key)
 * ...
 */
class ColumnDefinition extends Fluent
{
    //
}

The only option I have found so far is to extract the class into an ide-helper.php file and fill it with the necessary @method annotations I need. However, in this case, I would have to duplicate the original @method annotations as well, otherwise, they would be lost, but I don't want to duplicate them (since when Laravel is updated, I would have to manually track what has changed in the original file).

I would like something like this, so I don't have to repeat the original class. I don't know if it's possible, and if it is, how to do it.

// ide-helper.php

namespace Illuminate\Database\Schema;

/**
 * @method $this autoIncrement(bool $value = true) Set INTEGER columns as auto-increment (primary key) or disable auto-increment
 */
class ColumnDefinition
{
    //
}
{
    "autoload": {
        "files": [
            "./src/ide-helper.php"
        ]
    }
}

Note: By default, it makes sense that the IDE does not allow passing a variable, because from Laravel 11 onwards, I need to specify whether the column is auto-increment in every migration. However, I still need to pass the false value regardless of this.


Solution

  • added extra phpdoc

    It's a slightly bizarre solution, but it works. I declare another class and mark it as an alias for the original class:

    // ide-helper.php
    
    /**
     * @method $this autoIncrement(bool $value = true) Set INTEGER columns as auto-increment (primary key) or set NON-auto-increment
     * @method $this unsigned(bool $value = true) Set the INTEGER column as UNSIGNED (MySQL) or set NON-UNSIGNED
     */
    class ColumnDefinition
    {
        //
    }
    
    if (! class_exists(ColumnDefinition::class)) {
        class_alias(ColumnDefinition::class, \Illuminate\Database\Schema\ColumnDefinition::class);
    }
    

    With this class_alias, my ColumnDefinition represent the original ColumnDefinition from Laravel. This way, the IDE merges the PHPDoc of the two classes.

    The execution is not affected due to the class_exists check. Since it prevents the class from being marked as an alias during runtime.

    I'm not particularly like of this solution, but for now: it works.

    And since this is only needed for the IDE and does not interfere with production (the function is inherently capable of accepting a boolean variable), only the PHPDoc needed updating. Therefore, it’s better to declare it in autoload-dev instead of autoload:

    {
        "autoload-dev": {
            "files": [
                "./src/ide-helper.php"
            ]
        }
    }