Jump to content

PhpStorm autocompletion and typehinting of wire('xx')


interrobang
 Share

Recommended Posts

In PhpStorm you can get autocompletion and typehinting for wire function calls if you add a file with the following content somewhere to your project. Jetbrains suggests naming this file '.phpstorm.meta.php' and adding it to the root of your project, but it should work anywhere else too. I had to re-open the project after adding the file.


<?php
/**
* ProcessWire PhpStorm Meta
*
* This file is not a CODE, it makes no sense and won't run or validate
* Its AST serves PhpStorm IDE as DATA source to make advanced type inference decisions.
*
* @see https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata
*/


namespace PHPSTORM_META {

$STATIC_METHOD_TYPES = [
\wire('') => [
'' == '@',
'config' instanceof Config,
'wire' instanceof ProcessWire,
'log' instanceof WireLog,
'notices' instanceof Notices,
'sanitizer' instanceof \Sanitizer,
'database' instanceof \WireDatabasePDO,
'db' instanceof \DatabaseMysqli,
'cache' instanceof \MarkupCache,
'modules' instanceof \Modules,
'procache' instanceof \ProCache,
'fieldtypes' instanceof \Fieldtypes,
'fields' instanceof \Fields,
'fieldgroups' instanceof \Fieldgroups,
'templates' instanceof \Templates,
'pages' instanceof \Pages,
'permissions' instanceof \ Permissions,
'roles' instanceof \Roles,
'users' instanceof \Users,
'user' instanceof \User,
'session' instanceof \Session,
'input' instanceof \WireInput,
'languages' instanceof \Languages,
'page' instanceof \Page,
]
];
}



  • Like 8
Link to comment
Share on other sites

Good find @interrobang. Thanks for posting. I like how this narrows it down because before I would get every method of every API variable possible, which worked just fine, but this makes it even simpler. A couple of questions that I wasn't able to figure out from the linked page, and thought you might know: 

1. How to make this apply to $this->wire() in the same way? (i.e. The wire() method from the Wire class). I tried to do it like this, duplicating the same properties, but no luck:

 \Wire::wire('') => [ all the same properties here ]

2. Also trying to figure out how to make it recognize a wire() or $this>wire() call with no arguments returns an instance of class ProcessWire. Any ideas? I'm not sure I fully follow what the '' == '@' means, the doc page is a little unclear, or maybe it's time to refill my coffee. 

  • Haha 1
Link to comment
Share on other sites

Unfortunately I can't help here - I did not understand much of the documentation. Getting to this point was mostly trial and error.

I am not even sure if this can be achieved with this file. I think the main purpose of the meta file is to enable type-hinting for static factory methods. 

Link to comment
Share on other sites

  • 9 years later...

Wow, how time flies. This post is already 9 years old! 
The old syntax from the last post is now obsolete.
But today you can do much more. I just looked at the file along with claude.ai and here is a new version. 

Edit: I've added all the core hooks and status codes to this file. Could be useful sometimes. 

image.png
 

Spoiler
<?php

namespace PHPSTORM_META {

	override(\ProcessWire\Wire::wire(0), map([
		'config'      => \ProcessWire\Config::class,
		'cache'       => \ProcessWire\WireCache::class,
		'wire'        => \ProcessWire\ProcessWire::class,
		'log'         => \ProcessWire\WireLog::class,
		'notices'     => \ProcessWire\Notices::class,
		'sanitizer'   => \ProcessWire\Sanitizer::class,
		'database'    => \ProcessWire\WireDatabasePDO::class,
		'db'          => \ProcessWire\DatabaseMysqli::class,
		'modules'     => \ProcessWire\Modules::class,
		'fieldtypes'  => \ProcessWire\Fieldtypes::class,
		'fields'      => \ProcessWire\Fields::class,
		'fieldgroups' => \ProcessWire\Fieldgroups::class,
		'templates'   => \ProcessWire\Templates::class,
		'pages'       => \ProcessWire\Pages::class,
		'permissions' => \ProcessWire\Permissions::class,
		'roles'       => \ProcessWire\Roles::class,
		'users'       => \ProcessWire\Users::class,
		'user'        => \ProcessWire\User::class,
		'session'     => \ProcessWire\Session::class,
		'input'       => \ProcessWire\WireInput::class,
		'languages'   => \ProcessWire\Languages::class,
		'page'        => \ProcessWire\Page::class,
		'hooks'       => \ProcessWire\WireHooks::class,
		'files'       => \ProcessWire\WireFileTools::class,
		'datetime'    => \ProcessWire\WireDateTime::class,
		'mail'        => \ProcessWire\WireMailTools::class,
		''            => '@',
	]));

	// Define the possible status constants
	registerArgumentsSet('pw_status_constants',
		\ProcessWire\Page::statusHidden,
		\ProcessWire\Page::statusUnpublished,
		\ProcessWire\Page::statusLocked,
		\ProcessWire\Page::statusTrash,
		\ProcessWire\Page::statusDeleted,
		\ProcessWire\Page::statusSystem,
		\ProcessWire\Page::statusTemp,
		\ProcessWire\Page::statusDraft
	);

	// Define string values
	registerArgumentsSet('pw_status_strings',
		'hidden',
		'unpublished',
		'locked',
		'trash',
		'deleted',
		'system',
		'temp',
		'draft'
	);

	// Use both for arguments
	expectedArguments(\ProcessWire\Page::status(), 0,
		argumentsSet('pw_status_constants'),
		argumentsSet('pw_status_strings')
	);

	// Use constants for return values
	expectedReturnValues(\ProcessWire\Page::status(),
		argumentsSet('pw_status_constants')
	);


	// Hook methods autocompletion
	registerArgumentsSet('pw_hooks',
		'AdminTheme::getExtraMarkup',
		'AdminTheme::install',
		'AdminTheme::uninstall',
		'AdminThemeDefault::install',
		'AdminThemeFramework::getPrimaryNavArray',
		'AdminThemeFramework::getUserNavArray',
		'AdminThemeFramework::renderFile',
		'AdminThemeRenoHelpers::topNavItems',
		'AdminThemeUikit::getUikitCSS',
		'AdminThemeUikit::renderBreadcrumbs',
		'CommentList::renderItem',
		'CommentListCustom::renderItem',
		'CommentNotifications::sendAdminNotificationEmail',
		'CommentNotifications::sendConfirmationEmail',
		'CommentNotifications::sendNotificationEmail',
		'Config::callUnknown',
		'Field::editable',
		'Field::getConfigInputfields',
		'Field::getInputfield',
		'Field::viewable',
		'Fieldgroups::clone',
		'Fieldgroups::delete',
		'Fieldgroups::fieldAdded',
		'Fieldgroups::fieldRemoved',
		'Fieldgroups::getExportData',
		'Fieldgroups::load',
		'Fieldgroups::save',
		'Fieldgroups::saveContext',
		'Fieldgroups::setImportData',
		'Fields::applySetupName',
		'Fields::changeFieldtype',
		'Fields::changeTypeReady',
		'Fields::changedType',
		'Fields::clone',
		'Fields::delete',
		'Fields::deleteFieldDataByTemplate',
		'Fields::getTags',
		'Fields::save',
		'Fields::saveFieldgroupContext',
		'Fieldtype::cloneField',
		'Fieldtype::createField',
		'Fieldtype::deleteField',
		'Fieldtype::deletePageField',
		'Fieldtype::deleteTemplateField',
		'Fieldtype::emptyPageField',
		'Fieldtype::exportConfigData',
		'Fieldtype::exportValue',
		'Fieldtype::formatValue',
		'Fieldtype::getCompatibleFieldtypes',
		'Fieldtype::getConfigAdvancedInputfields',
		'Fieldtype::getConfigAllowContext',
		'Fieldtype::getConfigArray',
		'Fieldtype::getConfigInputfields',
		'Fieldtype::getFieldSetups',
		'Fieldtype::getSelectorInfo',
		'Fieldtype::importConfigData',
		'Fieldtype::importValue',
		'Fieldtype::install',
		'Fieldtype::loadPageField',
		'Fieldtype::loadPageFieldFilter',
		'Fieldtype::markupValue',
		'Fieldtype::renamedField',
		'Fieldtype::replacePageField',
		'Fieldtype::saveFieldReady',
		'Fieldtype::savePageField',
		'Fieldtype::savedField',
		'Fieldtype::sleepValue',
		'Fieldtype::uninstall',
		'Fieldtype::upgrade',
		'Fieldtype::wakeupValue',
		'FieldtypeCache::getCompatibleFieldtypes',
		'FieldtypeCache::getConfigInputfields',
		'FieldtypeCache::savePageField',
		'FieldtypeCache::sleepValue',
		'FieldtypeCache::wakeupValue',
		'FieldtypeCheckbox::getCompatibleFieldtypes',
		'FieldtypeCheckbox::getSelectorInfo',
		'FieldtypeCheckbox::markupValue',
		'FieldtypeComments::commentAddReady',
		'FieldtypeComments::commentAdded',
		'FieldtypeComments::commentApproved',
		'FieldtypeComments::commentDeleted',
		'FieldtypeComments::commentUnapproved',
		'FieldtypeComments::deleteField',
		'FieldtypeComments::deletePageField',
		'FieldtypeComments::emptyPageField',
		'FieldtypeComments::exportValue',
		'FieldtypeComments::getConfigInputfields',
		'FieldtypeComments::importValue',
		'FieldtypeComments::renamedField',
		'FieldtypeComments::replacePageField',
		'FieldtypeComments::savePageField',
		'FieldtypeComments::sendNotifyEmails',
		'FieldtypeComments::sleepValue',
		'FieldtypeComments::updateComment',
		'FieldtypeComments::wakeupValue',
		'FieldtypeDatetime::exportValue',
		'FieldtypeDatetime::formatValue',
		'FieldtypeDatetime::getCompatibleFieldtypes',
		'FieldtypeDatetime::getConfigInputfields',
		'FieldtypeDatetime::getFieldSetups',
		'FieldtypeDatetime::getSelectorInfo',
		'FieldtypeDatetime::sleepValue',
		'FieldtypeDatetime::wakeupValue',
		'FieldtypeDecimal::getCompatibleFieldtypes',
		'FieldtypeDecimal::getConfigInputfields',
		'FieldtypeDecimal::savedField',
		'FieldtypeDecimal::sleepValue',
		'FieldtypeEmail::getConfigAdvancedInputfields',
		'FieldtypeFieldsetPage::exportValue',
		'FieldtypeFieldsetPage::formatValue',
		'FieldtypeFieldsetPage::getConfigInputfields',
		'FieldtypeFieldsetPage::loadPageField',
		'FieldtypeFieldsetPage::savePageField',
		'FieldtypeFieldsetPage::sleepValue',
		'FieldtypeFieldsetPage::wakeupValue',
		'FieldtypeFile::cloneField',
		'FieldtypeFile::deleteField',
		'FieldtypeFile::deletePageField',
		'FieldtypeFile::emptyPageField',
		'FieldtypeFile::exportValue',
		'FieldtypeFile::formatValue',
		'FieldtypeFile::formatValueString',
		'FieldtypeFile::getCompatibleFieldtypes',
		'FieldtypeFile::getConfigAdvancedInputfields',
		'FieldtypeFile::getConfigInputfields',
		'FieldtypeFile::getFieldSetups',
		'FieldtypeFile::getModuleConfigInputfields',
		'FieldtypeFile::getSelectorInfo',
		'FieldtypeFile::loadPageField',
		'FieldtypeFile::markupValue',
		'FieldtypeFile::renamedField',
		'FieldtypeFile::replacePageField',
		'FieldtypeFile::sleepValue',
		'FieldtypeFile::wakeupValue',
		'FieldtypeFloat::getCompatibleFieldtypes',
		'FieldtypeFloat::getConfigInputfields',
		'FieldtypeFloat::sleepValue',
		'FieldtypeImage::exportValue',
		'FieldtypeImage::getConfigAdvancedInputfields',
		'FieldtypeImage::getConfigInputfields',
		'FieldtypeImage::getFieldSetups',
		'FieldtypeInteger::getCompatibleFieldtypes',
		'FieldtypeInteger::getConfigInputfields',
		'FieldtypeModule::getCompatibleFieldtypes',
		'FieldtypeModule::getConfigInputfields',
		'FieldtypeModule::getSelectorInfo',
		'FieldtypeModule::markupValue',
		'FieldtypeModule::sleepValue',
		'FieldtypeModule::wakeupValue',
		'FieldtypeMulti::deletePageFieldRows',
		'FieldtypeMulti::getCompatibleFieldtypes',
		'FieldtypeMulti::getConfigInputfields',
		'FieldtypeMulti::getSelectorInfo',
		'FieldtypeMulti::loadPageField',
		'FieldtypeMulti::savePageField',
		'FieldtypeMulti::savePageFieldRows',
		'FieldtypeMulti::sleepValue',
		'FieldtypeMulti::wakeupValue',
		'FieldtypeNotifications::sleepValue',
		'FieldtypeNotifications::wakeupValue',
		'FieldtypeOptions::cloneField',
		'FieldtypeOptions::deleteField',
		'FieldtypeOptions::exportConfigData',
		'FieldtypeOptions::formatValue',
		'FieldtypeOptions::getCompatibleFieldtypes',
		'FieldtypeOptions::getConfigInputfields',
		'FieldtypeOptions::getFieldSetups',
		'FieldtypeOptions::getSelectorInfo',
		'FieldtypeOptions::importConfigData',
		'FieldtypeOptions::install',
		'FieldtypeOptions::markupValue',
		'FieldtypeOptions::sleepValue',
		'FieldtypeOptions::uninstall',
		'FieldtypeOptions::wakeupValue',
		'FieldtypePage::exportConfigData',
		'FieldtypePage::exportValue',
		'FieldtypePage::formatValue',
		'FieldtypePage::getCompatibleFieldtypes',
		'FieldtypePage::getConfigInputfields',
		'FieldtypePage::getFieldSetups',
		'FieldtypePage::getSelectorInfo',
		'FieldtypePage::importConfigData',
		'FieldtypePage::importValue',
		'FieldtypePage::markupValue',
		'FieldtypePage::savePageField',
		'FieldtypePage::sleepValue',
		'FieldtypePage::wakeupValue',
		'FieldtypePageTable::exportConfigData',
		'FieldtypePageTable::formatValue',
		'FieldtypePageTable::getConfigInputfields',
		'FieldtypePageTable::getSelectorInfo',
		'FieldtypePageTable::importConfigData',
		'FieldtypePageTable::sleepValue',
		'FieldtypePageTable::wakeupValue',
		'FieldtypePageTitle::getCompatibleFieldtypes',
		'FieldtypePageTitleLanguage::getCompatibleFieldtypes',
		'FieldtypePassword::getCompatibleFieldtypes',
		'FieldtypePassword::getConfigInputfields',
		'FieldtypePassword::sleepValue',
		'FieldtypePassword::wakeupValue',
		'FieldtypeRepeater::cloneField',
		'FieldtypeRepeater::deleteField',
		'FieldtypeRepeater::deletePageField',
		'FieldtypeRepeater::exportConfigData',
		'FieldtypeRepeater::exportValue',
		'FieldtypeRepeater::formatValue',
		'FieldtypeRepeater::getCompatibleFieldtypes',
		'FieldtypeRepeater::getConfigAdvancedInputfields',
		'FieldtypeRepeater::getConfigInputfields',
		'FieldtypeRepeater::getSelectorInfo',
		'FieldtypeRepeater::importConfigData',
		'FieldtypeRepeater::importValue',
		'FieldtypeRepeater::install',
		'FieldtypeRepeater::readyPageSaved',
		'FieldtypeRepeater::replacePageField',
		'FieldtypeRepeater::saveConfigInputfields',
		'FieldtypeRepeater::savePageField',
		'FieldtypeRepeater::sleepValue',
		'FieldtypeRepeater::uninstall',
		'FieldtypeRepeater::wakeupValue',
		'FieldtypeSelector::formatValue',
		'FieldtypeSelector::getCompatibleFieldtypes',
		'FieldtypeSelector::getConfigInputfields',
		'FieldtypeSelector::sleepValue',
		'FieldtypeSelector::wakeupValue',
		'FieldtypeText::formatValue',
		'FieldtypeText::getCompatibleFieldtypes',
		'FieldtypeText::getConfigInputfields',
		'FieldtypeText::importConfigData',
		'FieldtypeText::importValue',
		'FieldtypeText::saveFieldReady',
		'FieldtypeTextLanguage::exportValue',
		'FieldtypeTextLanguage::importValue',
		'FieldtypeTextarea::exportValue',
		'FieldtypeTextarea::formatValue',
		'FieldtypeTextarea::getConfigInputfields',
		'FieldtypeTextarea::getFieldSetups',
		'FieldtypeTextarea::importValue',
		'FieldtypeTextarea::loadPageField',
		'FieldtypeTextarea::markupValue',
		'FieldtypeTextarea::sleepValue',
		'FieldtypeTextarea::wakeupValue',
		'FieldtypeTextareaLanguage::exportValue',
		'FieldtypeTextareaLanguage::importValue',
		'FieldtypeToggle::formatValue',
		'FieldtypeToggle::getCompatibleFieldtypes',
		'FieldtypeToggle::getConfigInputfields',
		'FieldtypeToggle::getSelectorInfo',
		'FieldtypeToggle::markupValue',
		'FieldtypeToggle::sleepValue',
		'FieldtypeURL::formatValue',
		'FieldtypeURL::getConfigInputfields',
		'FileCompiler::compile',
		'FileCompiler::compileData',
		'FileCompilerModule::install',
		'FileCompilerModule::uninstall',
		'FileValidatorHTML::log',
		'HelloWorld::install',
		'HelloWorld::uninstall',
		'HelloWorld::upgrade',
		'ImageSizer::resize',
		'ImageSizerEngineAnimatedGif::install',
		'ImageSizerEngineGD::imSaveReady',
		'ImageSizerEngineIMagick::imSaveReady',
		'ImageSizerEngineIMagick::install',
		'Inputfield::callUnknown',
		'Inputfield::exportConfigData',
		'Inputfield::getConfigAllowContext',
		'Inputfield::getConfigArray',
		'Inputfield::getConfigInputfields',
		'Inputfield::importConfigData',
		'Inputfield::install',
		'Inputfield::processInput',
		'Inputfield::render',
		'Inputfield::renderReadyHook',
		'Inputfield::renderValue',
		'Inputfield::uninstall',
		'InputfieldAsmSelect::getConfigInputfields',
		'InputfieldAsmSelect::render',
		'InputfieldButton::render',
		'InputfieldCKEditor::getConfigInputfields',
		'InputfieldCKEditor::processInput',
		'InputfieldCKEditor::render',
		'InputfieldCKEditor::renderValue',
		'InputfieldCheckbox::getConfigInputfields',
		'InputfieldCheckbox::processInput',
		'InputfieldCheckbox::render',
		'InputfieldCheckbox::renderValue',
		'InputfieldCheckboxes::getConfigInputfields',
		'InputfieldCheckboxes::render',
		'InputfieldCommentsAdmin::getConfigInputfields',
		'InputfieldCommentsAdmin::processInput',
		'InputfieldCommentsAdmin::render',
		'InputfieldCommentsAdmin::renderItem',
		'InputfieldCommentsAdmin::renderValue',
		'InputfieldDatetime::getConfigInputfields',
		'InputfieldDatetime::processInput',
		'InputfieldDatetime::render',
		'InputfieldDatetime::renderValue',
		'InputfieldEmail::getConfigInputfields',
		'InputfieldEmail::processInput',
		'InputfieldEmail::render',
		'InputfieldEmail::renderConfirm',
		'InputfieldFieldset::render',
		'InputfieldFieldsetClose::getConfigInputfields',
		'InputfieldFieldsetClose::render',
		'InputfieldFieldsetOpen::getCompatibleFieldtypes',
		'InputfieldFieldsetOpen::getConfigAdvancedInputfields',
		'InputfieldFieldsetOpen::getConfigInputfields',
		'InputfieldFieldsetOpen::renamedField',
		'InputfieldFieldsetTabOpen::getConfigAllowContext',
		'InputfieldFieldsetTabOpen::getConfigInputfields',
		'InputfieldFile::extractMetadata',
		'InputfieldFile::fileAdded',
		'InputfieldFile::getConfigInputfields',
		'InputfieldFile::processInput',
		'InputfieldFile::processInputAddFile',
		'InputfieldFile::processInputDeleteFile',
		'InputfieldFile::processInputFile',
		'InputfieldFile::processItemInputfields',
		'InputfieldFile::render',
		'InputfieldFile::renderItem',
		'InputfieldFile::renderList',
		'InputfieldFile::renderUpload',
		'InputfieldFile::renderValue',
		'InputfieldForm::process',
		'InputfieldForm::processInput',
		'InputfieldForm::render',
		'InputfieldForm::renderOrProcessReady',
		'InputfieldHidden::getConfigInputfields',
		'InputfieldHidden::render',
		'InputfieldHidden::renderValue',
		'InputfieldIcon::render',
		'InputfieldImage::buildTooltipData',
		'InputfieldImage::fileAdded',
		'InputfieldImage::getConfigInputfields',
		'InputfieldImage::getFileActions',
		'InputfieldImage::getImageEditButtons',
		'InputfieldImage::getImageThumbnailActions',
		'InputfieldImage::processInput',
		'InputfieldImage::processInputFile',
		'InputfieldImage::processUnknownFileAction',
		'InputfieldImage::render',
		'InputfieldImage::renderAdditionalFields',
		'InputfieldImage::renderButtons',
		'InputfieldImage::renderClipboard',
		'InputfieldImage::renderItem',
		'InputfieldImage::renderList',
		'InputfieldImage::renderSingleItem',
		'InputfieldImage::renderUpload',
		'InputfieldInteger::render',
		'InputfieldMarkup::getConfigInputfields',
		'InputfieldMarkup::render',
		'InputfieldMarkup::renderValue',
		'InputfieldPage::findPagesCode',
		'InputfieldPage::getConfigInputfields',
		'InputfieldPage::getSelectablePages',
		'InputfieldPage::processInput',
		'InputfieldPage::processInputAddPages',
		'InputfieldPage::render',
		'InputfieldPage::renderAddable',
		'InputfieldPage::renderPageLabel',
		'InputfieldPage::renderValue',
		'InputfieldPageAutocomplete::getAjaxUrl',
		'InputfieldPageAutocomplete::getConfigInputfields',
		'InputfieldPageAutocomplete::install',
		'InputfieldPageAutocomplete::processInput',
		'InputfieldPageAutocomplete::render',
		'InputfieldPageAutocomplete::renderList',
		'InputfieldPageAutocomplete::renderListItem',
		'InputfieldPageAutocomplete::uninstall',
		'InputfieldPageListSelect::processInput',
		'InputfieldPageListSelect::render',
		'InputfieldPageListSelect::renderValue',
		'InputfieldPageListSelectMultiple::processInput',
		'InputfieldPageListSelectMultiple::render',
		'InputfieldPageListSelectMultiple::renderValue',
		'InputfieldPageName::processInput',
		'InputfieldPageName::render',
		'InputfieldPageTable::getConfigInputfields',
		'InputfieldPageTable::processInput',
		'InputfieldPageTable::render',
		'InputfieldPageTable::renderTable',
		'InputfieldPageTable::renderValue',
		'InputfieldPageTableAjax::checkAjax',
		'InputfieldPassword::getConfigInputfields',
		'InputfieldPassword::processInput',
		'InputfieldPassword::render',
		'InputfieldPassword::renderValue',
		'InputfieldRadios::getConfigInputfields',
		'InputfieldRadios::render',
		'InputfieldRepeater::getConfigInputfields',
		'InputfieldRepeater::processInput',
		'InputfieldRepeater::render',
		'InputfieldRepeater::renderRepeaterLabel',
		'InputfieldRepeater::renderValue',
		'InputfieldSelect::getConfigInputfields',
		'InputfieldSelect::processInput',
		'InputfieldSelect::render',
		'InputfieldSelect::renderValue',
		'InputfieldSelectMultiple::getConfigInputfields',
		'InputfieldSelector::processInput',
		'InputfieldSelector::render',
		'InputfieldSubmit::processInput',
		'InputfieldSubmit::render',
		'InputfieldText::getConfigAllowContext',
		'InputfieldText::getConfigInputfields',
		'InputfieldText::processInput',
		'InputfieldText::render',
		'InputfieldText::renderValue',
		'InputfieldTextTags::getConfigInputfields',
		'InputfieldTextTags::processInput',
		'InputfieldTextTags::render',
		'InputfieldTextTags::renderValue',
		'InputfieldTextarea::getConfigAllowContext',
		'InputfieldTextarea::getConfigInputfields',
		'InputfieldTextarea::processInput',
		'InputfieldTextarea::render',
		'InputfieldTextarea::renderValue',
		'InputfieldTinyMCE::getConfigInputfields',
		'InputfieldTinyMCE::processInput',
		'InputfieldTinyMCE::render',
		'InputfieldTinyMCE::renderValue',
		'InputfieldToggle::getConfigAllowContext',
		'InputfieldToggle::getConfigInputfields',
		'InputfieldToggle::getInputfield',
		'InputfieldToggle::processInput',
		'InputfieldToggle::render',
		'InputfieldToggle::renderValue',
		'InputfieldURL::getConfigInputfields',
		'InputfieldURL::render',
		'InputfieldWrapper::allowProcessInput',
		'InputfieldWrapper::getConfigInputfields',
		'InputfieldWrapper::new',
		'InputfieldWrapper::processInput',
		'InputfieldWrapper::render',
		'InputfieldWrapper::renderInputfield',
		'InputfieldWrapper::renderValue',
		'JqueryCore::use',
		'JqueryUI::use',
		'JqueryWireTabs::render',
		'LanguageSupport::install',
		'LanguageSupport::uninstall',
		'LanguageSupportFields::fieldLanguageAdded',
		'LanguageSupportFields::fieldLanguageRemoved',
		'LanguageSupportFields::install',
		'LanguageSupportFields::languageAdded',
		'LanguageSupportFields::languageDeleted',
		'LanguageSupportFields::uninstall',
		'LanguageSupportInstall::install',
		'LanguageSupportInstall::uninstall',
		'LanguageSupportPageNames::install',
		'LanguageSupportPageNames::pageNotAvailableInLanguage',
		'LanguageSupportPageNames::uninstall',
		'LanguageSupportPageNames::upgrade',
		'LanguageTranslator::getTranslation',
		'Languages::added',
		'Languages::deleted',
		'Languages::updated',
		'LanguagesPageFieldValue::getStringValue',
		'LazyCron::every10Minutes',
		'LazyCron::every12Hours',
		'LazyCron::every15Minutes',
		'LazyCron::every2Days',
		'LazyCron::every2Hours',
		'LazyCron::every2Minutes',
		'LazyCron::every2Weeks',
		'LazyCron::every30Minutes',
		'LazyCron::every30Seconds',
		'LazyCron::every3Minutes',
		'LazyCron::every45Minutes',
		'LazyCron::every4Days',
		'LazyCron::every4Hours',
		'LazyCron::every4Minutes',
		'LazyCron::every4Weeks',
		'LazyCron::every5Minutes',
		'LazyCron::every6Hours',
		'LazyCron::everyDay',
		'LazyCron::everyHour',
		'LazyCron::everyMinute',
		'LazyCron::everyWeek',
		'LazyCron::uninstall',
		'MarkupAdminDataTable::render',
		'MarkupCache::uninstall',
		'MarkupHTMLPurifier::initConfig',
		'MarkupHTMLPurifier::uninstall',
		'MarkupPagerNav::install',
		'MarkupPagerNav::render',
		'MarkupPagerNav::uninstall',
		'ModuleJS::install',
		'ModuleJS::uninstall',
		'ModuleJS::use',
		'ModulePlaceholder::install',
		'ModulePlaceholder::uninstall',
		'Modules::delete',
		'Modules::getModuleConfigInputfields',
		'Modules::install',
		'Modules::isUninstallable',
		'Modules::moduleVersionChanged',
		'Modules::refresh',
		'Modules::saveConfig',
		'Modules::saveModuleConfigData',
		'Modules::uninstall',
		'NullPage::rootParent',
		'Page::callUnknown',
		'Page::edit',
		'Page::getIcon',
		'Page::getInputfields',
		'Page::getMarkup',
		'Page::getUnknown',
		'Page::if',
		'Page::isPublic',
		'Page::links',
		'Page::loaded',
		'Page::path',
		'Page::references',
		'Page::renderField',
		'Page::renderValue',
		'Page::rootParent',
		'Page::setEditor',
		'PageAction::action',
		'PageArray::getMarkup',
		'PageFinder::find',
		'PageFinder::getQuery',
		'PageFinder::getQueryAllowedTemplatesWhere',
		'PageFinder::getQueryJoinPath',
		'PageFinder::getQueryUnknownField',
		'PageFrontEdit::getAjaxPostUrl',
		'PageFrontEdit::getPage',
		'PagePathHistory::install',
		'PagePathHistory::uninstall',
		'PagePathHistory::upgrade',
		'PagePaths::install',
		'PagePaths::uninstall',
		'PagePaths::upgrade',
		'PagePermissions::pageEditable',
		'PageRender::clearCacheFileAll',
		'PageRender::clearCacheFilePages',
		'PageRender::renderPage',
		'PageRender::saveCacheFileReady',
		'Pagefile::changed',
		'Pagefile::filename',
		'Pagefile::httpUrl',
		'Pagefile::install',
		'Pagefile::noCacheURL',
		'Pagefile::url',
		'PagefileExtra::create',
		'PagefileExtra::noCacheURL',
		'Pagefiles::clone',
		'Pagefiles::delete',
		'PagefilesManager::path',
		'PagefilesManager::save',
		'PagefilesManager::url',
		'Pageimage::createdVariation',
		'Pageimage::crop',
		'Pageimage::install',
		'Pageimage::isVariation',
		'Pageimage::rebuildVariations',
		'Pageimage::render',
		'Pageimage::size',
		'Pageimages::render',
		'Pages::add',
		'Pages::added',
		'Pages::clone',
		'Pages::cloneReady',
		'Pages::cloned',
		'Pages::delete',
		'Pages::deleteBranchReady',
		'Pages::deleteReady',
		'Pages::deleted',
		'Pages::deletedBranch',
		'Pages::emptyTrash',
		'Pages::find',
		'Pages::found',
		'Pages::insertAfter',
		'Pages::insertBefore',
		'Pages::moveReady',
		'Pages::moved',
		'Pages::new',
		'Pages::publishReady',
		'Pages::published',
		'Pages::renameReady',
		'Pages::renamed',
		'Pages::restore',
		'Pages::restoreReady',
		'Pages::restored',
		'Pages::save',
		'Pages::saveField',
		'Pages::saveFieldReady',
		'Pages::saveFields',
		'Pages::savePageOrFieldReady',
		'Pages::saveReady',
		'Pages::saved',
		'Pages::savedField',
		'Pages::savedPageOrField',
		'Pages::setupNew',
		'Pages::setupPageName',
		'Pages::sort',
		'Pages::sorted',
		'Pages::statusChangeReady',
		'Pages::statusChanged',
		'Pages::templateChanged',
		'Pages::touch',
		'Pages::trash',
		'Pages::trashReady',
		'Pages::trashed',
		'Pages::unpublishReady',
		'Pages::unpublished',
		'PagesRequest::getClosestPage',
		'PagesRequest::getLoginPageOrUrl',
		'PagesRequest::getPage',
		'PagesRequest::getPageForUser',
		'PagesType::add',
		'PagesType::added',
		'PagesType::delete',
		'PagesType::deleteReady',
		'PagesType::deleted',
		'PagesType::save',
		'PagesType::saveReady',
		'PagesType::saved',
		'PagesVersions::allowPageVersions',
		'PagesVersions::useTempVersionToRestore',
		'Password::setPass',
		'Permissions::add',
		'Permissions::delete',
		'Permissions::deleted',
		'Permissions::getOptionalPermissions',
		'Permissions::save',
		'Permissions::saved',
		'Process::breadcrumb',
		'Process::browserTitle',
		'Process::execute',
		'Process::executeNavJSON',
		'Process::executeUnknown',
		'Process::executed',
		'Process::headline',
		'Process::install',
		'Process::installPage',
		'Process::uninstall',
		'Process::uninstallPage',
		'Process::upgrade',
		'ProcessCommentsManager::execute',
		'ProcessCommentsManager::executeEdit',
		'ProcessCommentsManager::executeList',
		'ProcessCommentsManager::executeMeta',
		'ProcessCommentsManager::install',
		'ProcessCommentsManager::renderComment',
		'ProcessController::execute',
		'ProcessField::allowFieldInTemplate',
		'ProcessField::buildEditForm',
		'ProcessField::buildEditFormActions',
		'ProcessField::buildEditFormAdvanced',
		'ProcessField::buildEditFormBasics',
		'ProcessField::buildEditFormContext',
		'ProcessField::buildEditFormCustom',
		'ProcessField::buildEditFormDelete',
		'ProcessField::buildEditFormInfo',
		'ProcessField::execute',
		'ProcessField::executeAdd',
		'ProcessField::executeChangeType',
		'ProcessField::executeEdit',
		'ProcessField::executeExport',
		'ProcessField::executeImport',
		'ProcessField::executeNavJSON',
		'ProcessField::executeSave',
		'ProcessField::executeSaveChangeType',
		'ProcessField::executeSendTemplates',
		'ProcessField::executeSendTemplatesSave',
		'ProcessField::fieldAdded',
		'ProcessField::fieldChangedContext',
		'ProcessField::fieldChangedType',
		'ProcessField::fieldDeleted',
		'ProcessField::fieldSaved',
		'ProcessField::getListFilterForm',
		'ProcessField::getListTable',
		'ProcessField::getListTableRow',
		'ProcessField::saveContext',
		'ProcessField::upgrade',
		'ProcessFieldExportImport::buildExport',
		'ProcessFieldExportImport::buildImport',
		'ProcessFieldExportImport::buildInputDataForm',
		'ProcessFieldExportImport::processImport',
		'ProcessForgotPassword::execute',
		'ProcessForgotPassword::install',
		'ProcessForgotPassword::log',
		'ProcessForgotPassword::renderContinue',
		'ProcessForgotPassword::renderEmailBody',
		'ProcessForgotPassword::renderError',
		'ProcessForgotPassword::renderErrorEmailBody',
		'ProcessForgotPassword::renderForm',
		'ProcessForgotPassword::renderMessage',
		'ProcessForgotPassword::uninstall',
		'ProcessForgotPassword::upgrade',
		'ProcessHome::execute',
		'ProcessLanguage::execute',
		'ProcessLanguage::executeDownload',
		'ProcessLanguage::processCSV',
		'ProcessLanguageTranslator::execute',
		'ProcessLanguageTranslator::executeAdd',
		'ProcessLanguageTranslator::executeEdit',
		'ProcessLanguageTranslator::executeList',
		'ProcessLanguageTranslator::processAdd',
		'ProcessLanguageTranslator::processEdit',
		'ProcessList::execute',
		'ProcessLogger::execute',
		'ProcessLogger::executeNavJSON',
		'ProcessLogger::executeView',
		'ProcessLogger::formatLogText',
		'ProcessLogin::afterLogin',
		'ProcessLogin::afterLoginOutput',
		'ProcessLogin::afterLoginRedirect',
		'ProcessLogin::afterLoginURL',
		'ProcessLogin::beforeLogin',
		'ProcessLogin::buildLoginForm',
		'ProcessLogin::execute',
		'ProcessLogin::executeLogout',
		'ProcessLogin::getBeforeLoginVars',
		'ProcessLogin::getLoginLinks',
		'ProcessLogin::login',
		'ProcessLogin::loginAttemptReady',
		'ProcessLogin::loginAttempted',
		'ProcessLogin::loginFailed',
		'ProcessLogin::loginFormProcessReady',
		'ProcessLogin::loginFormProcessed',
		'ProcessLogin::loginSuccess',
		'ProcessLogin::renderLoginForm',
		'ProcessModule::buildDownloadConfirmForm',
		'ProcessModule::buildDownloadSuccessForm',
		'ProcessModule::execute',
		'ProcessModule::executeDownload',
		'ProcessModule::executeDownloadURL',
		'ProcessModule::executeEdit',
		'ProcessModule::executeInstallConfirm',
		'ProcessModule::executeNavJSON',
		'ProcessModule::executeReadme',
		'ProcessModule::executeTranslation',
		'ProcessModule::executeUpload',
		'ProcessPageAdd::buildForm',
		'ProcessPageAdd::execute',
		'ProcessPageAdd::executeBookmarks',
		'ProcessPageAdd::executeNavJSON',
		'ProcessPageAdd::executeTemplate',
		'ProcessPageAdd::getAllowedTemplates',
		'ProcessPageAdd::nameChangedWarning',
		'ProcessPageAdd::processInput',
		'ProcessPageAdd::processQuickAdd',
		'ProcessPageClone::buildForm',
		'ProcessPageClone::execute',
		'ProcessPageClone::getSuggestedNameAndTitle',
		'ProcessPageClone::process',
		'ProcessPageClone::render',
		'ProcessPageEdit::ajaxEditable',
		'ProcessPageEdit::ajaxSave',
		'ProcessPageEdit::ajaxSaveDone',
		'ProcessPageEdit::buildForm',
		'ProcessPageEdit::buildFormChildren',
		'ProcessPageEdit::buildFormContent',
		'ProcessPageEdit::buildFormCreatedUser',
		'ProcessPageEdit::buildFormDelete',
		'ProcessPageEdit::buildFormRoles',
		'ProcessPageEdit::buildFormSettings',
		'ProcessPageEdit::buildFormView',
		'ProcessPageEdit::deletedPage',
		'ProcessPageEdit::execute',
		'ProcessPageEdit::executeBookmarks',
		'ProcessPageEdit::executeNavJSON',
		'ProcessPageEdit::executeSaveTemplate',
		'ProcessPageEdit::executeTemplate',
		'ProcessPageEdit::getSubmitActions',
		'ProcessPageEdit::getTabs',
		'ProcessPageEdit::getViewActions',
		'ProcessPageEdit::loadPage',
		'ProcessPageEdit::processInput',
		'ProcessPageEdit::processSaveRedirect',
		'ProcessPageEdit::processSubmitAction',
		'ProcessPageEditImageSelect::execute',
		'ProcessPageEditImageSelect::executeEdit',
		'ProcessPageEditImageSelect::executeResize',
		'ProcessPageEditImageSelect::executeVariations',
		'ProcessPageEditLink::buildForm',
		'ProcessPageEditLink::execute',
		'ProcessPageEditLink::executeFiles',
		'ProcessPageEditLink::getFilesPage',
		'ProcessPageList::ajaxAction',
		'ProcessPageList::execute',
		'ProcessPageList::executeBookmarks',
		'ProcessPageList::executeId',
		'ProcessPageList::executeNavJSON',
		'ProcessPageList::executeOpen',
		'ProcessPageList::find',
		'ProcessPageList::getHidePageIDs',
		'ProcessPageListActions::getActions',
		'ProcessPageListActions::getExtraActions',
		'ProcessPageListActions::processAction',
		'ProcessPageListRender::getNumChildren',
		'ProcessPageListRender::getPageActions',
		'ProcessPageListRender::getPageLabel',
		'ProcessPageLister::buildListerTableColActions',
		'ProcessPageLister::execute',
		'ProcessPageLister::executeEditBookmark',
		'ProcessPageLister::executeNavJSON',
		'ProcessPageLister::executeReset',
		'ProcessPageLister::executeUnknown',
		'ProcessPageLister::findResults',
		'ProcessPageLister::getSelector',
		'ProcessPageLister::install',
		'ProcessPageLister::renderResults',
		'ProcessPageLister::renderedExtras',
		'ProcessPageLister::uninstall',
		'ProcessPageSearch::execute',
		'ProcessPageSearch::executeFor',
		'ProcessPageSearch::findReady',
		'ProcessPageSearchLive::execute',
		'ProcessPageSearchLive::findCustom',
		'ProcessPageSearchLive::getDefaultPageSearchFields',
		'ProcessPageSearchLive::renderItem',
		'ProcessPageSearchLive::renderList',
		'ProcessPageSort::execute',
		'ProcessPageSort::install',
		'ProcessPageTrash::execute',
		'ProcessPageType::execute',
		'ProcessPageType::executeActions',
		'ProcessPageType::executeAdd',
		'ProcessPageType::executeConfig',
		'ProcessPageType::executeEdit',
		'ProcessPageType::executeEditBookmark',
		'ProcessPageType::executeList',
		'ProcessPageType::executeNavJSON',
		'ProcessPageType::executeReset',
		'ProcessPageType::executeSave',
		'ProcessPageType::executeSaveTemplate',
		'ProcessPageType::executeTemplate',
		'ProcessPageType::executeUnknown',
		'ProcessPageType::executeViewport',
		'ProcessPageView::execute',
		'ProcessPageView::executeExternal',
		'ProcessPageView::failed',
		'ProcessPageView::finished',
		'ProcessPageView::pageNotFound',
		'ProcessPageView::pathHooks',
		'ProcessPageView::ready',
		'ProcessPageView::sendFile',
		'ProcessPageView::userNotAllowed',
		'ProcessPagesExportImport::execute',
		'ProcessPagesExportImport::install',
		'ProcessPagesExportImport::uninstall',
		'ProcessPermission::executeAdd',
		'ProcessPermission::executeInstallPermissions',
		'ProcessProfile::execute',
		'ProcessProfile::isDisallowedUserName',
		'ProcessRecentPages::execute',
		'ProcessRecentPages::executeAnother',
		'ProcessRecentPages::executeAnotherNavJSON',
		'ProcessRecentPages::executeEdit',
		'ProcessRecentPages::executeNavJSON',
		'ProcessSessionDB::execute',
		'ProcessTemplate::buildEditForm',
		'ProcessTemplate::execute',
		'ProcessTemplate::executeAdd',
		'ProcessTemplate::executeEdit',
		'ProcessTemplate::executeExport',
		'ProcessTemplate::executeFieldgroup',
		'ProcessTemplate::executeImport',
		'ProcessTemplate::executeNavJSON',
		'ProcessTemplate::executeRename',
		'ProcessTemplate::executeSave',
		'ProcessTemplate::executeSaveFieldgroup',
		'ProcessTemplate::executeSaveProperty',
		'ProcessTemplate::executeTags',
		'ProcessTemplate::fieldAdded',
		'ProcessTemplate::fieldRemoved',
		'ProcessTemplate::getListFilterForm',
		'ProcessTemplate::getListTable',
		'ProcessTemplate::getListTableRow',
		'ProcessTemplateExportImport::buildExport',
		'ProcessTemplateExportImport::buildImport',
		'ProcessTemplateExportImport::buildInputDataForm',
		'ProcessTemplateExportImport::processImport',
		'ProcessUser::executeAdd',
		'ProcessUser::executeEdit',
		'ProcessUser::executeNavJSON',
		'ProcessWire::finished',
		'ProcessWire::init',
		'ProcessWire::ready',
		'Roles::add',
		'Roles::delete',
		'Roles::deleted',
		'Roles::save',
		'Sanitizer::array',
		'Sanitizer::callUnknown',
		'Sanitizer::fileName',
		'Sanitizer::testAll',
		'Session::allowLogin',
		'Session::allowLoginAttempt',
		'Session::authenticate',
		'Session::init',
		'Session::isValidSession',
		'Session::login',
		'Session::loginFailure',
		'Session::loginSuccess',
		'Session::logout',
		'Session::logoutSuccess',
		'Session::redirect',
		'SessionHandlerDB::install',
		'SessionHandlerDB::uninstall',
		'SessionHandlerDB::upgrade',
		'SessionLoginThrottle::install',
		'SessionLoginThrottle::uninstall',
		'SystemNotifications::install',
		'SystemNotifications::uninstall',
		'SystemUpdater::coreVersionChange',
		'Template::getConnectedField',
		'TemplateFile::fileFailed',
		'TemplateFile::render',
		'Templates::clone',
		'Templates::delete',
		'Templates::fileModified',
		'Templates::getExportData',
		'Templates::getTags',
		'Templates::save',
		'Templates::setImportData',
		'Textformatter::install',
		'Textformatter::uninstall',
		'Tfa::buildAuthCodeForm',
		'Tfa::getFingerprintArray',
		'Tfa::getUserEnabledInputfields',
		'Tfa::getUserSettingsInputfields',
		'Tfa::install',
		'Tfa::process',
		'Tfa::processUserEnabledInputfields',
		'Tfa::processUserSettingsInputfields',
		'Tfa::render',
		'Tfa::start',
		'Tfa::uninstall',
		'User::changed',
		'User::hasPagePermission',
		'User::hasTemplatePermission',
		'User::setEditor',
		'Users::save',
		'Users::saveReady',
		'Wire::callUnknown',
		'Wire::changed',
		'Wire::log',
		'Wire::trackException',
		'WireAction::action',
		'WireAction::executeMultiple',
		'WireAction::getConfigInputfields',
		'WireArray::and',
		'WireArray::callUnknown',
		'WireCache::log',
		'WireData::and',
		'WireDatabasePDO::unknownColumnError',
		'WireDateTime::relativeTimeStr',
		'WireFileTools::include',
		'WireFileTools::log',
		'WireHttp::download',
		'WireHttp::send',
		'WireHttp::sendFile',
		'WireInput::callUnknown',
		'WireInputData::callUnknown',
		'WireLog::save',
		'WireMail::htmlToText',
		'WireMail::sanitizeHeaderName',
		'WireMail::sanitizeHeaderValue',
		'WireMail::send',
		'WireMailTools::isBlacklistEmail',
		'WireMailTools::new',
		'WireSaveableItems::added',
		'WireSaveableItems::clone',
		'WireSaveableItems::cloneReady',
		'WireSaveableItems::cloned',
		'WireSaveableItems::delete',
		'WireSaveableItems::deleteReady',
		'WireSaveableItems::deleted',
		'WireSaveableItems::find',
		'WireSaveableItems::load',
		'WireSaveableItems::renameReady',
		'WireSaveableItems::renamed',
		'WireSaveableItems::save',
		'WireSaveableItems::saveReady',
		'WireSaveableItems::saved',
		'WireSaveableItemsLookup::delete',
		'WireSaveableItemsLookup::load',
		'WireSaveableItemsLookup::save',
		'WireShutdown::fatalError',
		'WireTextTools::wordAlternates'
	);

	expectedArguments(\ProcessWire\Wire::addHook(), 0, argumentsSet('pw_hooks'));
	expectedArguments(\ProcessWire\Wire::addHookBefore(), 0, argumentsSet('pw_hooks'));
	expectedArguments(\ProcessWire\Wire::addHookAfter(), 0, argumentsSet('pw_hooks'));
}

 


But there's more, here's a little module that adds a few things to an extra phpstorm.meta.php. After installing the module you get suggestions for 
$fields->get('') // suggests existing field names
$templates->get('') // suggests existing template names
$modules->get('') // suggests existing module names 
+ all hooks defined in /site/modules/
 

Spoiler
<?php

namespace ProcessWire;

class MetaFileGenerator extends WireData implements Module, ConfigurableModule
{
    public static function getModuleInfo() {
        return [
            'title'    => 'PhpStorm Meta File Generator',
            'version'  => 1,
            'summary'  => 'Generates .phpstorm.meta.php file for ProcessWire autocompletion',
            'singular' => true,
            'autoload' => 'template=admin',
            'requires' => 'ProcessWire>=3.0.0',
        ];
    }

    public function init() {
        // Regenerate meta file when fields, templates or modules change
        $this->addHookAfter('Fields::save', $this, 'generateMetaFile');
        $this->addHookAfter('Fields::delete', $this, 'generateMetaFile');
        $this->addHookAfter('Templates::save', $this, 'generateMetaFile');
        $this->addHookAfter('Templates::delete', $this, 'generateMetaFile');
        $this->addHookAfter('Modules::install', $this, 'generateMetaFile');
        $this->addHookAfter('Modules::uninstall', $this, 'generateMetaFile');
    }

    public function ready() {
        if ($this->wire()->session->metaFileGenerate) {
            $this->generateMetaFile();
            $this->wire()->session->remove('metaFileGenerate');
        }
    }

    public function ___install() {
        $this->wire()->session->set('metaFileGenerate', true);
    }

    static public function getModuleConfigInputfields(array $data) {
        $inputfields = new InputfieldWrapper();
        $modules = wire()->modules;

        $f = $modules->get('InputfieldButton');
        $f->name = 'regenerate';
        $f->value = __('Regenerate Meta File');
        $f->icon = 'refresh';
        $f->href = wire()->config->urls->admin.'module/edit?name=MetaFileGenerator&regenerate=1';
        $inputfields->add($f);

        $f = $modules->get('InputfieldMarkup');
        $f->name = 'meta_file_info';
        $filePath = wire()->config->paths->get('MetaFileGenerator').'.phpstorm.meta.php';
        $fileExists = file_exists($filePath);
        $lastModified = $fileExists ? date('Y-m-d H:i:s', filemtime($filePath)) : 'never';
        $f->value = "<p>Meta File Location: <code>{$filePath}</code><br>Last Modified: {$lastModified}</p>";
        $inputfields->add($f);

        if (wire()->input->get('regenerate')) {
            $module = $modules->get('MetaFileGenerator');
            $module->generateMetaFile();
            wire()->session->message(__('Meta file regenerated'));
            wire()->session->redirect(wire()->config->urls->admin.'module/edit?name=MetaFileGenerator');
        }

        return $inputfields;
    }

    public function ___generateMetaFile(HookEvent $event = null) {
        $content = "<?php\n\nnamespace PHPSTORM_META {\n\n";
        $content .= $this->generateModuleMetaContent();
        $content .= $this->generateFieldMetaContent();
        $content .= $this->generateTemplateMetaContent();
        $content .= $this->generateHookMetaContent();
        $content .= "}\n";

        try {
            $file = $this->wire()->config->paths->get($this->className()).'.phpstorm.meta.php';
            if (file_put_contents($file, $content) !== false) {
                if ($event) {
                    $this->message('PhpStorm meta file updated successfully');
                }
            } else {
                $this->error('Failed to write meta file');
            }
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }
    }

    protected function generateModuleMetaContent() {
        $content = "    // Module name autocompletion for get() and install()\n";
        $content .= "    override(\\ProcessWire\\Modules::get(0), map([\n";

        $moduleData = [];
        foreach ($this->wire('modules')->findByPrefix('') as $moduleName) {
            $moduleClass = strpos($moduleName, '\\') === false
                ? "\\ProcessWire\\{$moduleName}"
                : $moduleName;
            $moduleData[$moduleName] = "        '$moduleName' => $moduleClass::class,\n";
        }

        ksort($moduleData);
        $content .= implode('', $moduleData);
        $content .= "    ]));\n\n";

        return $content;
    }

    protected function generateFieldMetaContent() {
        $content = "    // Field name autocompletion for Fields::get()\n";
        $content .= "    override(\\ProcessWire\\Fields::get(0), map([\n";

        foreach ($this->wire()->fields as $field) {
            $content .= "        '{$field->name}' => '\\ProcessWire\\Field',\n";
        }

        $content .= "    ]));\n\n";

        return $content;
    }

    protected function generateTemplateMetaContent() {
        $content = "    // Template name autocompletion for Templates::get()\n";
        $content .= "    override(\\ProcessWire\\Templates::get(0), map([\n";

        foreach ($this->wire()->templates as $template) {
            $content .= "        '{$template->name}' => '\\ProcessWire\\Template',\n";
        }

        $content .= "    ]));\n\n";

        return $content;
    }

    protected function findAllHookableMethods() {
        $hooks = [];

        $paths = [
            $this->config->paths->siteModules,
            // $this->config->paths->modules,
            // $this->config->paths->core,
            // $this->config->paths->adminTemplates
        ];

        foreach ($paths as $rootPath) {
            if (!is_dir($rootPath)) continue;

            $directory = new \RecursiveDirectoryIterator($rootPath);
            $iterator = new \RecursiveIteratorIterator($directory);
            $regex = new \RegexIterator($iterator, '/^.+\.(php|module)$/i', \RecursiveRegexIterator::GET_MATCH);

            foreach ($regex as $file) {
                $content = file_get_contents($file[0]);
                if (!preg_match('/namespace\s+ProcessWire;/', $content)) continue;

                if (preg_match('/class\s+(\w+)(?:\s+extends\s+[\\\\\w]+)?(?:\s+implements\s+[\\\\\w,\s]+)?\s*\{/s', $content, $classMatch)) {
                    $className = $classMatch[1];

                    if (preg_match_all('/(public|protected)\s+function\s+_{3}(\w+)/i', $content, $matches)) {
                        foreach ($matches[2] as $method) {
                            $hooks[] = "        '{$className}::{$method}'";
                        }
                    }
                }
            }
        }

        $hooks = array_unique($hooks);
        sort($hooks);
        return $hooks;
    }

    protected function generateHookMetaContent() {
        $content = "    // Hook methods autocompletion\n";
        $content .= "    registerArgumentsSet('pw_hooks',\n";

        $hooks = $this->findAllHookableMethods();
        sort($hooks);

        $content .= implode(",\n", $hooks);
        $content .= "\n    );\n\n";

        // Register hooks for all hook methods
        $content .= "    expectedArguments(\\ProcessWire\\Wire::addHook(), 0, argumentsSet('pw_hooks'));\n";
        $content .= "    expectedArguments(\\ProcessWire\\Wire::addHookBefore(), 0, argumentsSet('pw_hooks'));\n";
        $content .= "    expectedArguments(\\ProcessWire\\Wire::addHookAfter(), 0, argumentsSet('pw_hooks'));\n";

        return $content;
    }
}

 

 

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...