Plugin on Jetbrains Marketplace: https://plugins.jetbrains.com/plugin/26121-meta-storm/
MetaStorm makes your IDE understand code even deeper.
A few lines of config files unlock both references and autocompletion at regular places such as method($object, <property of object>)
, render(<file name>)
, etc
- No need dedicated IDE plugin to support your own framework
- Anyone can extend or override plugin functionality
- So if a feature is not ready by the dedicated IDE plugin, MetaStorm is ready to covers with its possibilities
- No need to support legacy codebase in the dedicated IDE plugin
- Written component config might be used with any other projects, like Symfony Console and almost the whole PHP world
- Life save for single developers, any library configuration might improve developer experience with less knowledge
- Totally free
Short Youtube demo: https://youtu.be/fFGrRNFDZIg
When I use the static method ArrayHelper::getValue
I want to make my IDE to be as helpful as possible.
I want to make the IDE understand that if I type the second argument it must be one of the properties of the first argument:
public static function getValue(object $object, string $property)
- Create a file with the name
.meta-storm.xml
at any place in your project with the following content:
<?xml version="1.0" encoding="UTF-8" ?>
<meta-storm xmlns="meta-storm">
<definitions>
<classMethod class="\ArrayHelper" method="getValue" argument="1">
<properties relatedTo="argument" relatedArgument="0"/>
</classMethod>
</definitions>
</meta-storm>
- Create a PHP file with the following content:
<?php
class User { private $id; protected $name; public $age; }
$a = new User;
class ArrayHelper {
public static function getValue(object $object, string $property) {}
}
ArrayHelper::getValue($a, 'age');
- Start doing
- Click with pressed CTRL / COMMAND on the
'age'
and PhpStorm navigates you to the$age
property declaration. - Remove
age
and start typing, you can see properties completion for the existing properties. - Click on the property
$age
in the classUser
and PhpStorm highlight you all the usages and add references to them
That was example how it works. Read the rest documentation to understand what you can do with the plugin.
Open-source tools can greatly improve workflows, helping developers and businesses save time and increase revenue. Many successful projects have been built on these tools, benefiting a wide community. However, maintaining and enhancing these resources requires continuous effort and investment.
Support from the community helps keep these projects alive and ensures they remain useful for everyone. Donations play a key role in sustaining and improving these open-source initiatives.
Chose the best option for you to say thank you:
Patreon
|
Buy me a coffee
|
Boosty
Meta Storm searches for any files with the .meta-storm.xml
at the end of file name so:
- A file can be placed at any place (except ignored directories)
- A file may have any name with the specific postfix, e.g.:
arrays.meta-storm.xml
,files.meta-storm.xml
,.meta-storm.xml
, etc - Configuration files could exist more than one at the moment
- The whole config is combines with several config files
The best way to use the plugin is to add a specific configuration to a package and distribute the config file with the package.
<?xml version="1.0" encoding="UTF-8" ?>
<meta-storm xmlns="meta-storm">
<definitions>
</definitions>
<collections>
</collections>
</meta-storm>
- The configuration files are written in XML format.
- There can be any number of configuration files, as long as their names end with
.meta-storm.xml
. - Configuration files can be distributed with libraries and may be located in the
vendor/*
directory.
Each configuration file follows this structure:
- Definitions
- Mount Point (Where?)
- Functionality to Add (What?)
- Display Method (How?)
- Functionality to Add (What?)
- Mount Point (Where?)
- Collections
- Collection Assembly Instructions
Now that you understand how the configuration is structured, you can assemble it using existing components or submit an issue or pull request with your idea.
Mounts into the class method call.
Parameter | Required | Description | Possible values |
---|---|---|---|
class |
yes | fully qualified class name | \App\Helper\Arrays |
method |
yes | method name | getValue |
argument |
yes | position of the argument you want to make interactive | 0 , 1 , 2 , ... |
targetValue |
no | should be used as direct value target (string) | true , false |
targetInArray |
no | position in array expression | key , value , none |
children | no | features |
<classMethod
class="\Framework\AttributeArgumentValueInterface"
method="attributeArgumentValue" argument="0">
<!-- features -->
</classMethod>
Mounts into the class constructor call or the attribute definition call.
Parameter | Required | Description | Possible values |
---|---|---|---|
class |
yes | fully qualified class name | \App\Helper\Arrays |
argument |
yes | position of the argument you want to make interactive | 0 , 1 , 2 , ... |
targetValue |
no | should be used as direct value target (string) | true , false |
targetInArray |
no | position in array expression | key , value , none |
children | no | features |
<classConstructor class="\Framework\AttributeArgumentValueInterface" argument="0">
<!-- features -->
</classConstructor>
Mounts into the class object invocation.
Parameter | Required | Description | Possible values |
---|---|---|---|
class |
yes | fully qualified class name | \App\Helper\Arrays |
argument |
yes | position of the argument you want to make interactive | 0 , 1 , 2 , ... |
targetValue |
no | should be used as direct value target (string) | true , false |
targetInArray |
no | position in array expression | key , value , none |
children | no | features |
<classCallable class="\Framework\EventHandler" argument="0">
<!-- features -->
</classCallable>
Mounts into the class property default value.
Parameter | Required | Description | Possible values |
---|---|---|---|
class |
yes | fully qualified class name | \App\Helper\Arrays |
property |
yes | name of the property | tableName , property , ... |
targetValue |
no | should be used as direct value target (string) | true , false |
targetInArray |
no | position in array expression | key , value , none |
children | no | features |
<classProperty class="\Framework\Entity" property="table">
<!-- features -->
</classProperty>
Mounts into the function call.
Parameter | Required | Description | Possible values |
---|---|---|---|
name |
yes | function name | file_get_contents |
argument |
yes | position of the argument you want to make interactive | 0 , 1 , 2 , ... |
targetValue |
no | should be used as direct value target (string) | true , false |
targetInArray |
no | position in array expression | key , value , none |
children | no | features |
<function name="view" argument="0">
<!-- features -->
</function>
Mounts into the returning value of the method.
Parameter | Required | Description | Possible values |
---|---|---|---|
class |
yes | fully qualified class name | \App\Helper\Arrays |
method |
yes | method name | getValue |
children | no | features |
<returnValue class="\ActiveRecord" method="tableName">
<!-- features -->
</returnValue>
Mounts into the files satisfied by xpath.
Parameter | Required | Description | Possible values |
---|---|---|---|
xpath |
yes | xpath string to walk through the entities | $project/resources/templates/ |
extension |
no | method name | getValue |
children | no | features |
Note:
files
target xpath work properly only with$project
start point
All *.php
files under $project/resources/templates
directory
<files xpath="$project/resources/templates" extension=".php">
<!-- features -->
</files>
Any files under $project/resources/templates
directory
<files xpath="$project/resources/templates">
<!-- features -->
</files>
Once you configured target it's possible to inject one or many features into the mounting point.
Many of the following features automatically enable the following IDE abilities:
- Autocompletion
- When you start typing inside the string literal IDE suggest you necessary endings
- Referencing string literals as program language entities that automatically enables:
- Navigating from the usage to the definition
- From
method('prop')
toclass { public $prop }
- From
render('index')
totemplates/site/index.php
- From
- Navigating from the definition to the usages
- Vise-serve of the navigating from the usage to the definition
- Renaming
- Refactoring
- Finding usages
- Navigating from the usage to the definition
Provide properties of the related class.
Parameter | Required | Description | Possible values |
---|---|---|---|
relatedTo |
no (if xpath set) |
relative point to lookup for entries | See Related type |
xpath |
no (if relatedTo set) |
xpath string to walk through the entities | See Related type |
relatedArgument |
no | related argument index, useful for many relatedTo values |
0 , 1 , 2 , ... |
public |
no | show or hide such properties | true , false |
protected |
no | show or hide such properties | true , false |
private |
no | show or hide such properties | true , false |
static |
no | show or hide such properties | true , false |
dynamic |
no | show or hide such properties | true , false |
children | no | feature processors |
<properties relatedTo="argument" relatedArgument="0"/>
Provide properties of the related class.
Parameter | Required | Description | Possible values |
---|---|---|---|
relatedTo |
no (if xpath set) |
relative point to lookup for entries | See Related type |
xpath |
no (if relatedTo set) |
xpath string to walk through the entities | See Related type |
relatedArgument |
no | related argument index, useful for many relatedTo values |
0 , 1 , 2 , ... |
public |
no | show or hide such methods | true , false |
protected |
no | show or hide such methods | true , false |
private |
no | show or hide such methods | true , false |
abstract |
no | show or hide such methods | true , false |
static |
no | show or hide such methods | true , false |
dynamic |
no | show or hide such methods | true , false |
children | no | feature processors |
<methods relatedTo="containingClass" static="false" />
Provide files and directories at the related filesystem point.
Parameter | Required | Description | Possible values |
---|---|---|---|
relatedTo |
no (if xpath set) |
relative point to lookup for entries | See Related type |
xpath |
no (if relatedTo set) |
xpath string to walk through the entities | See Related type |
extension |
no | file extension you want to filter and hide from autocompletion | (empty) , php , blade.php , ... |
children | no | feature processors |
Directory-related files
<files extension="" relatedTo="directory"/>
Absolute directory lookup
<files extension="" xpath="$project/resources/templates"/>
directoryProcessors
is applied here as the children element.
Provide directories only at the related filesystem point.
Parameter | Required | Description | Possible values |
---|---|---|---|
relatedTo |
no (if xpath set) |
relative point to lookup for entries | See Related type |
xpath |
no (if relatedTo set) |
xpath string to walk through the entities | See Related type |
children | no | feature processors |
Directory-related files
<directories relatedTo="directory"/>
Absolute directory lookup
<directories xpath="$project/resources/templates"/>
directoryProcessors
is applied here as the children element.
Provide database table names.
Parameter | Required | Description | Possible values |
---|---|---|---|
database |
yes | connection exact name OR regular expression | main , .+ , ... |
children | no | feature processors |
<tables />
Overrides returning type by matching value alias.
returnType
:
Parameter | Required | Description | Possible values |
---|---|---|---|
children | no | aliases list |
alias
:
Parameter | Required | Description | Possible values |
---|---|---|---|
name |
yes | argument value matched returning class | int , user |
class |
yes | fully qualified class name | \IntResult , \UserFactory |
<returnType>
<alias name="int" class="\IntResult" />
<alias name="string" class="\StringResult" />
<alias name="null" class="\NullResult" />
<alias name="object" class="\ObjectResult" />
</returnType>
Injects variable into the target.
Parameter | Required | Description | Possible values |
---|---|---|---|
name |
yes | variable name | this , urlGenerator |
class |
yes | fully qualified class name | \Framework\View\View , \Framework\Router\UrlGenerator |
Note:
variableInjection
feature works properly only withfiles
target.
<variableInjection name="this" class="\Framework\View\View" />
Injects language support into the target.
Parameter | Required | Description | Possible values |
---|---|---|---|
language |
yes | known PHPStorm language | RegExp , CSS , SQL |
<labgyageInjection language="RegExp" />
Provide value from the defined collections
Parameter | Required | Description | Possible values |
---|---|---|---|
name |
yes | collection name | tags , cycle/orm:entities |
argument |
yes | position of the argument you want to make interactive | 0 , 1 , 2 , ... |
children | no | feature processors |
<collection name="workflows_methods" argument="0" />
Name | Description | Example |
---|---|---|
GLOBAL:html-tags |
Provides known html tags | div , span , abbr |
GLOBAL:http-methods |
Provides HTTP methods | GET , POST , PUT |
GLOBAL:php-classes |
Provides php full qualified class names | div , span , abbr |
GLOBAL:php-interfaces |
Provides php full qualified interface names | div , span , abbr |
GLOBAL:php-functions |
Provides php full qualified function names | div , span , abbr |
GLOBAL:env |
Provides collected ENV variables from putenv function calls and .env files |
APP_ENV , APP_DEBUG |
Using collections helps to first define a set of values, prepare, filter and then use as definitions.
Collections can be merged. So it's possible to build a collection with different sources (attributes, yaml, json, php).
All collections must be defined in the collections
tag in the root xml tag:
<meta-storm xmlns="meta-storm">
<definitions>
<target>
<collection name="" /> // <-- there is only usage of the collection defined below
</target>
</definitions>
<collections>
... // <-- there are collection definitions
</collections>
</meta-storm>
Collects attribute from the attribute usage.
Parameter | Required | Description | Possible values |
---|---|---|---|
name |
yes | collection name | tags , cycle/orm:entities |
class |
yes | fully qualified attribute class name | \Attributes\AsCommand |
<attributeClass
name="workflows_classes"
class="\Framework\ClassMarker"
/>
Collects argument from the attribute usage.
Parameter | Required | Description | Possible values |
---|---|---|---|
name |
yes | collection name | tags , cycle/orm:entities |
class |
yes | fully qualified attribute class name | \Attributes\AsCommand |
argument |
yes | position of the argument you want to collect | 0 , 1 , 2 , ... |
<attributeArgument
name="commands"
class="\Framework\Command"
argument="0"
/>
Collects keys from the json file.
Parameter | Required | Description | Possible values |
---|---|---|---|
name |
yes | collection name | tags , cycle/orm:entities |
xpath |
yes | xpath string to walk through the entities | $project/resources/translations/en.json |
<jsonFile name="translations" xpath="$directory/en.json" />
Defines static strings from the current definition.
Parameter | Required | Description | Possible values |
---|---|---|---|
name |
yes | collection name | tags , cycle/orm:entities |
children | no | strings itself |
<strings name="static_strings">
<value>Hello</value>
<value>Static</value>
<value>World</value>
</strings>
Environment variables make it able to have late static binding for vendor <-> user definitions.
E.g., you as a vendor may define default path or a part of path, database name, default class or whatever*, buy a user when face with its custom settings will have incorrect behaviour.
This is when envs
will come in useful:
- Replace a changing part with an
env
- Set default value
- Let user redefine the variable
A few rules about the envs
:
- Variable name must be in uppercase
- Values outside the vendor folder override those within it
- Since there may be multiple files, the order of value overwriting is not guaranteed
Defines variables to be replaced in some other strings.
Parameter | Required | Description | Possible values |
---|---|---|---|
name |
yes | variable name | VIEW-THEME , YII2/FRAMEWORK:VIEW-THEME |
value |
yes | variable values | dark , database-name , ... |
children | no | feature processors |
<envs>
<env name="VIEW-THEME" value="dark" />
</envs>
- Complex parameter changes interpretation of the files
- Possible values:
file
– related to the current (opened) filecontainingClass
– related to the current (opened) classdirectory
– related to the current file directoryproject
– related to the project pathargument
– related to the positioned argument: it's$obj
in$service->method($obj, $prop)
variable
– related to the variable holding the method: it's$service
in$service->method()
- A string used to walk through the file system, like regular Unix-based FS path
- XPath must be started from a relative point:
$project
– project base path$file
– related to the current file$directory
– related to the current directory
Absolute directory
$project/resources/templates
Current directory
$directory/views
Current file
$file/../views
- A string used to walk through the programming entities: classes, methods, properties, constants, etc
- XPath must be started from a relative point:
$containingClass
– means the class in which context the target is placed$argument
– related to the positioned argument: it's$obj
in$service->method($obj, $prop)
$variable
– related to the variable holding the method: it's$service
in$service->method()
- After you specified starting point you may walk further:
- Each "entrance" must be a dot symbol:
.
- Each "property" must be prefixed with a dollar symbol:
$
- Each "method return type" must have double squares as a suffix :
()
- Each "entrance" must be a dot symbol:
- Lookup supports:
- Typed properties:
private Class $property
- Untyped properties with reference inside:
private string $propertyClass = Class::class
- Typed methods' returning:
public function methodA(): Class
- Typed properties:
Look through a property in a factory
$containingClass.$originalClass
Look through the decorator
$variable.$decorated
Could be chained any number of times
$variable.$a.$b.$c.$d.methoA().methodB()
- Regular expression based processor, helps you to change directory, convert camelCase to snake_case and other
- Parameters:
from
: required- Regular expression
to
: required- Regular expression, could you $1, $2, etc as group references
- Supports envs substitution
Converts HelloWorld
to Hello-World
<regexp from="([a-z])([A-Z])" to="$1-$2"/>
Using envs
:
<regexp from="(${VIEW-THEME})" to="$1-${VIEW-THEME}"/>
- Regular expression based processor, helps you to change directory, convert camelCase to snake_case and other
- Parameters:
from
: required- Regular expression
case
: required- lower
- upper
from
supports envs substitution
Converts /MyPath/To/HelloWorld
to /MyPath/To/helloworld
<regexp from="[^/]+$" case="lower"/>
- Such prefixing basically used for some static values like static path from the project directory
- Parameters:
value
: required- String
- Supports envs substitution
Regular case:
<append value="/common/mail"/>
Using envs
:
<append value="/resources/themes/${VIEW-THEME}/layout"/>
The plugin for PhpStorm natively adds support of XSD scheme, but if you want to look at it deeper please open the link.