MetaStorm для вашего мозга
MetaStorm позволит вашей IDE глубже понимать код, а заодно пере(за)грузит ваш мозг.
⚡MetaStorm – молот Тора для PHPStorm!⚓︎
MetaStorm — это плагин для PHPStorm, который может сделать вашу IDE умнее. Он позволяет добавлять автодополнение, навигацию по коду и ссылки на свойства, методы и файлы прямо в вашем коде. Всё это достигается с помощью простых конфигурационных файлов в формате XML.
Плагин можно скачать с Marketplace или установить через раздел Plugins в PHPStorm.
🚀 Быстрый старт⚓︎
-
Создайте конфигурационный файл
.meta-storm.xmlв вашем проекте: -
Создайте PHP-файл с примером кода (либо используйте свой):
-
Начните использовать:
- Нажмите
CTRL/CMDна свойствеage, и PHPStorm перенесёт вас к объявлению свойства. - Удалите в последней строчке
ageи начните вводить второй параметр – IDE предложит автодополнение свойств, беря их из объекта$a. - Нажмите на свойство
$ageв классеUser, и PHPStorm подсветит все его использования.
- Нажмите
Преимущества⚓︎
- Не требует специального плагина IDE для поддержки вашего фреймворка.
- Любой может расширить функциональность плагина.
- Если функция не готова в специальном плагине IDE, MetaStorm готов покрыть её своими возможностями.
- Конфигурации компонентов могут быть использованы в других проектах, например, Symfony Console.
- Спасение для одиночных разработчиков – улучшает опыт разработки с минимальными знаниями.
- Бесплатно и с открытым исходным кодом.
Структура конфигурации⚓︎
Каждый конфигурационный файл следует такой структуре:
<?xml version="1.0" encoding="UTF-8" ?>
<meta-storm xmlns="meta-storm">
<definitions>
<!-- таргеты с фичами -->
</definitions>
<collections>
<!-- коллекции -->
</collections>
</meta-storm>
- Определения
- Точка подключения (Где?)
- Функциональность для добавления (Что?)
- Метод отображения (Как?)
- Функциональность для добавления (Что?)
- Точка подключения (Где?)
- Коллекции
- Инструкции по сборке коллекций
Общий принцип создания определений таков: берем таргет (точку подключения) и помещаем внутри него фичу (нужную функциональность).
Таргеты⚓︎
classMethod⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
class | да | полное имя класса | \App\Helper\Arrays |
method | да | имя метода | getValue |
argument | да | позиция аргумента, который вы хотите сделать интерактивным | 0, 1, 2, ... |
targetValue | нет | должен использоваться как целевое значение (строка) | true, false |
targetInArray | нет | позиция в выражении массива | key, value, none |
| children | нет | фичи |
<!-- Автодополнение для метода find() в классе модели User -->
<classMethod class="\App\Models\User" method="find" argument="1">
<properties relatedTo="argument" relatedArgument="0" public="true"/>
</classMethod>
property) IDE будет предлагать свойства класса User. classConstructor⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
class | да | полное имя класса | \App\Helper\Arrays |
argument | да | позиция аргумента, который вы хотите сделать интерактивным | 0, 1, 2, ... |
targetValue | нет | должен использоваться как целевое значение (строка) | true, false |
targetInArray | нет | позиция в выражении массива | key, value, none |
| children | нет | фичи |
<!-- Внедрение языковой поддержки в конструктор класса Database -->
<classConstructor class="\App\Database" argument="1">
<languageInjection language="SQL"/>
</classConstructor>
Database будет обрабатываться как SQL-код с подсветкой и автодополнением. classCallable⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
class | да | полное имя класса | \App\Helper\Arrays |
argument | да | позиция аргумента, который вы хотите сделать интерактивным | 0, 1, 2, ... |
targetValue | нет | должен использоваться как целевое значение (строка) | true, false |
targetInArray | нет | позиция в выражении массива | key, value, none |
| children | нет | фичи |
<!-- Автодополнение для первого аргумента при вызове объекта EventHandler -->
<classCallable class="\Framework\EventHandler" argument="0">
<methods relatedTo="containingClass" static="false"/>
</classCallable>
EventHandler как функции, первый аргумент будет предлагать методы (все, кроме статических) текущего класса. classProperty⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
class | да | полное имя класса | \App\Helper\Arrays |
property | да | имя свойства | tableName, property, ... |
targetValue | нет | должен использоваться как целевое значение (строка) | true, false |
targetInArray | нет | позиция в выражении массива | key, value, none |
| children | нет | фичи |
<!-- Связь свойства "table" класса Entity с коллекцией таблиц БД -->
<classProperty class="\Framework\Entity" property="table">
<tables database="main"/>
</classProperty>
table в классе Entity будет автодополняться списком таблиц из базы main. function⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
name | да | имя функции | file_get_contents |
argument | да | позиция аргумента, который вы хотите сделать интерактивным | 0, 1, 2, ... |
targetValue | нет | должен использоваться как целевое значение (строка) | true, false |
targetInArray | нет | позиция в выражении массива | key, value, none |
| children | нет | фичи |
<!-- Автодополнение для первого аргумента функции view() -->
<function name="view" argument="0">
<files relatedTo="directory" extension=".twig"/>
</function>
view('...') IDE предложит файлы с расширением .twig из текущей директории. returnValue⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
class | да | полное имя класса | \App\Helper\Arrays |
method | да | имя метода | getValue |
| children | нет | фичи |
<!-- Возвращаемое значение метода tableName связывается с коллекцией таблиц -->
<returnValue class="\ActiveRecord" method="tableName">
<tables database=".+"/>
</returnValue>
ActiveRecord::tableName(), будет проверяться на соответствие существующим таблицам БД. Ещё пример:
class CreateUsersTable extends Migration {
public function tableName() {
return 'usr_list'; // Ошибка: таблица 'usr_list' не существует
}
}
files⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
xpath | да | строка xpath для обхода сущностей | $project/resources/templates/ |
extension | нет | имя метода | getValue |
| children | нет | фичи |
<!-- Обработка всех PHP-файлов в директории templates -->
<files xpath="$project/resources/templates" extension=".php">
<variableInjection name="this" class="\Framework\View\View"/>
</files>
templates переменная $this будет типизирована как \Framework\View\View. Ещё пример:
<classMethod class="\Illuminate\Support\Facades\Route" method="get" argument="1">
<files relatedTo="directory" xpath="$project/resources/views" extension=".blade.php"/>
</classMethod>
// В blade-шаблоне:
<a href="{{ route('users.edit') }}"> <!-- IDE предложит 'users.edit' из списка всех роутов -->
Фичи⚓︎
Фичи не используются сами по себе и должны находиться внутри таргетов.
properties⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
relatedTo | нет (если задан xpath) | относительная точка для поиска записей | См. relatedTo |
xpath | нет (если задан relatedTo) | строка xpath для обхода сущностей | См. xpath |
relatedArgument | нет | индекс связанного аргумента, полезный для многих значений relatedTo | 0, 1, 2, ... |
public | нет | показывать или скрывать такие свойства | true, false |
protected | нет | показывать или скрывать такие свойства | true, false |
private | нет | показывать или скрывать такие свойства | true, false |
static | нет | показывать или скрывать такие свойства | true, false |
dynamic | нет | показывать или скрывать такие свойства | true, false |
| children | нет | процессоры функций |
<!-- Автодополнение публичных свойств класса из первого аргумента -->
<properties relatedTo="argument" relatedArgument="0" public="true"/>
methods⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
relatedTo | нет (если задан xpath) | относительная точка для поиска записей | См. relatedTo |
xpath | нет (если задан relatedTo) | строка xpath для обхода сущностей | См. xpath |
relatedArgument | нет | индекс связанного аргумента, полезный для многих значений relatedTo | 0, 1, 2, ... |
public | нет | показывать или скрывать такие методы | true, false |
protected | нет | показывать или скрывать такие методы | true, false |
private | нет | показывать или скрывать такие методы | true, false |
abstract | нет | показывать или скрывать такие методы | true, false |
static | нет | показывать или скрывать такие методы | true, false |
dynamic | нет | показывать или скрывать такие методы | true, false |
| children | нет | процессоры функций |
<!-- Показывает нестатические методы текущего класса -->
<methods relatedTo="containingClass" static="false"/>
Ещё пример:
<classMethod class="\yii\widgets\ActiveForm" method="field" argument="2">
<methods
relatedTo="argument"
relatedArgument="0"
static="false"
public="true"
/>
</classMethod>
<?= $form->field($model, 'attribute', [
'inputOptions' => ['class' => 'form-control']
])-> // IDE предложит методы модели $model
files⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
relatedTo | нет (если задан xpath) | относительная точка для поиска записей | См. relatedTo |
xpath | нет (если задан relatedTo) | строка xpath для обхода сущностей | См. xpath |
extension | нет | расширение файла, которое вы хотите отфильтровать и скрыть от автозаполнения | (пусто), php, blade.php, ... |
| children | нет | процессоры функций |
<!-- Автодополнение изображений в директории ресурсов -->
<files relatedTo="directory" extension=".png">
<regexp from="\.png$" to=""/>
</files>
directories⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
relatedTo | нет (если задан xpath) | относительная точка для поиска записей | См. relatedTo |
xpath | нет (если задан relatedTo) | строка xpath для обхода сущностей | См. xpath |
| children | нет | процессоры функций |
<!-- Предлагает поддиректории в папке migrations -->
<directories xpath="$project/database/migrations"/>
tables⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
database | да | точное имя подключения ИЛИ регулярное выражение | main, .+, ... |
| children | нет | процессоры функций |
returnType⚓︎
Параметры
returnType:
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
| children | нет | список псевдонимов |
alias:
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
name | да | значение аргумента, соответствующее возвращаемому классу | int, user |
class | да | полное имя класса | \IntResult, \UserFactory |
<!-- Связывает возвращаемые типы с кастомными классами -->
<returnType>
<alias name="int" class="\Result\IntResult"/>
<alias name="string" class="\Result\StringResult"/>
</returnType>
При указании нескольких типов сразу будет использоваться объединение типов.
variableInjection⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
name | да | имя переменной | this, urlGenerator |
class | да | полное имя класса | \Framework\View\View, \Framework\Router\UrlGenerator |
<!-- Внедрение переменной $generator типа UrlGenerator в шаблоны -->
<variableInjection name="generator" class="\Framework\Router\UrlGenerator"/>
Ещё пример:
<files xpath="$project/views" extension=".twig">
<variableInjection name="app" class="\Core\Application"/>
<variableInjection name="user" class="\Models\User"/>
</files>
{{ app.request.path }} <!-- Навигация к классу Application -->
{{ user.email }} <!-- Автодополнение свойств User -->
languageInjection⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
language | да | известный язык PHPStorm | RegExp, CSS, SQL и пр. |
<classMethod class="\App\DB\QueryBuilder" method="whereRaw" argument="0">
<languageInjection language="SQL"/>
<tables database="main"/>
</classMethod>
// Полноценная подсветка SQL + автодополнение таблиц БД
$query->whereRaw("SELECT * FROM users WHERE id = ?", [1]);
collection⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
name | да | имя коллекции | tags, cycle/orm:entities |
argument | да | позиция аргумента, который вы хотите сделать интерактивным | 0, 1, 2, ... |
| children | нет | процессоры функций |
<!-- Использование предопределённой коллекции HTML-тегов -->
<collection name="GLOBAL:html-tags" argument="0"/>
arrayValues⚓︎
Возвращает значения массива для автозавершения ввода.
arrayKeys⚓︎
Возвращает ключи массива для автозавершения ввода.
stopCompletion⚓︎
Позволяет отключить встроенное автозавершение ввода PHPStorm.
icon⚓︎
Позволяет отображать иконку.
<files xpath="$project/" extension="php">
<icon xpath="$project/examples/injection/icons/users.svg"/>
</files>
Глобальные коллекции⚓︎
| Название | Описание | Пример |
|---|---|---|
GLOBAL:env | Предоставляет собранные переменные окружения из вызовов функции putenv и файлов .env | APP_ENV, APP_DEBUG |
GLOBAL:html-tags | Предоставляет список известных HTML-тегов | div, span, abbr |
GLOBAL:http-headers | Предоставляет список HTTP-заголовков | Accept, Content-Type |
GLOBAL:http-methods | Предоставляет список HTTP-методов | GET, POST, PUT |
GLOBAL:mime-types | Предоставляет список известных MIME-типов | application/json, image/jpeg |
GLOBAL:php-classes | Предоставляет полные имена классов PHP | \App\MyService |
GLOBAL:php-functions | Предоставляет список всех PHP функций, включая встроенные и пользовательские | time, user_function |
GLOBAL:php-interfaces | Предоставляет список всех PHP интерфейсов в вашем проекте | \App\MyServiceInterface |
GLOBAL:php-traits | Предоставляет список всех PHP трейтов в вашем проекте | \App\Traits\Deletable |
Коллекции⚓︎
Коллекции можно объединять. Определяйте их внутри тегов <collections></collections>:
<meta-storm xmlns="meta-storm">
<definitions>
<target>
<collection name="имя коллекции" />
</target>
</definitions>
<collections>
<!-- коллекции-->
</collections>
</meta-storm>
attributeClass⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
name | да | имя коллекции | tags, cycle/orm:entities |
class | да | полное имя класса атрибута | \Attributes\AsCommand |
<!-- Сбор всех классов с атрибутом AsCommand -->
<attributeClass name="commands" class="\Attributes\AsCommand"/>
attributeArgument⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
name | да | имя коллекции | tags, cycle/orm:entities |
class | да | полное имя класса атрибута | \Attributes\AsCommand |
argument | да | позиция аргумента, который вы хотите собрать | 0, 1, 2, ... |
<!-- Сбор первого аргумента атрибута Route -->
<attributeArgument name="routes" class="\Framework\Attributes\Route" argument="0"/>
Ещё пример:
<collections>
<attributeArgument
name="api-endpoints"
class="\App\Attributes\Endpoint"
argument="0"
/>
</collections>
<definitions>
<function name="fetchData" argument="0">
<collection name="api-endpoints"/>
</function>
</definitions>
#[Endpoint('/api/users')]
class UserController {}
fetchData('/api/'); // IDE предложит все зарегистрированные эндпойнты
jsonFile⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
name | да | имя коллекции | tags, cycle/orm:entities |
xpath | да | строка xpath для обхода сущностей | $project/resources/translations/en.json |
<!-- Сбор ключей из JSON-файла переводов -->
<jsonFile name="translations" xpath="$project/resources/lang/en.json"/>
Ещё пример:
<jsonFile name="config-keys" xpath="$project/config/app.json">
<regexp from="([A-Z])" to="_$1"/>
<case from=".*" case="lower"/>
</jsonFile>
strings⚓︎
Параметры
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
name | да | имя коллекции | tags, cycle/orm:entities |
| children | нет | строки сами по себе |
<!-- Статический набор строк -->
<strings name="greetings">
<value>Hello</value>
<value>Привет</value>
</strings>
Переменные окружения⚓︎
Переменные окружения позволяют осуществлять позднюю статическую привязку для определений между поставщиком и пользователем.
| Параметр | Обязательный | Описание | Возможные значения |
|---|---|---|---|
name | да | имя переменной | VIEW-THEME, YII2/FRAMEWORK:VIEW-THEME |
value | да | значения переменной | dark, database-name, ... |
| children | нет | процессоры функций |
Процессоры⚓︎
regexp⚓︎
case⚓︎
append⚓︎
Ещё пример: <collection name="custom-tags">
<strings name="html-tags">
<value>modal</value>
<value>accordion</value>
</strings>
<append value="-component"/>
</collection>
Дополнительно⚓︎
relatedTo⚓︎
- Сложный параметр, изменяющий интерпретацию файлов
- Возможные значения:
file– связано с текущим (открытым) файломcontainingClass– связано с текущим (открытым) классомdirectory– связано с директорией текущего файлаproject– связано с путём проектаargument– связано с позиционным аргументом: это$objв$service->method($obj, $prop)variable– связано с переменной, содержащей метод: это$serviceв$service->method()
xpath⚓︎
XPath для <files>⚓︎
- Строка, используемая для обхода файловой системы, как обычный путь на основе Unix
- XPath должен начинаться с относительной точки:
$project– базовый путь проекта$file– связано с текущим файлом$directory– связано с текущей директорией
Советы⚓︎
- Конфигурационные файлы могут быть размещены в любом месте проекта.
- Используйте коллекции для определения наборов значений, таких как теги HTML или методы HTTP.
- Поддерживайте свои конфигурации в пакетах и распространяйте их вместе с библиотеками.
Примеры конфигураций⚓︎
Заключение⚓︎
Мы получаем мощный инструмент, который делает разработку на PHP быстрее и удобнее. Но готовы ли вы сломать мозг в попытках создать свой конфиг?
Задать вопросы или подкинуть идеи разработчику можно в телеге.
Если вам понравился плагин, поставьте звезду репозиторию на GitHub. В документации можно ознакомиться со всеми примерами и полным описанием доступных параметров.