diff --git a/.github/workflows/code-quality.yaml b/.github/workflows/code-quality.yaml index 1147541209..e00c18212f 100644 --- a/.github/workflows/code-quality.yaml +++ b/.github/workflows/code-quality.yaml @@ -37,6 +37,29 @@ jobs: - name: Run code quality checks (on pull request) if: github.event_name == 'pull_request' run: ./.github/workflows/utilities/phpcs-pr ${{ github.base_ref }} + staticAnalysis: + runs-on: ubuntu-latest + name: PHPStan + steps: + - name: Checkout changes + uses: actions/checkout@v7 + + - name: Install PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 + extensions: curl, fileinfo, gd, mbstring, openssl, pdo, pdo_sqlite, sqlite3, xml, zip + + - name: Install Composer dependencies + run: composer install --no-interaction --no-progress --no-scripts + + - name: Reset modules + run: | + git reset --hard + git clean -fd + + - name: Run static analysis + run: vendor/bin/phpstan analyse --no-progress --memory-limit=2G codeQualityJS: runs-on: ubuntu-latest name: JavaScript diff --git a/composer.json b/composer.json index 49915a8696..6b6a95eba9 100644 --- a/composer.json +++ b/composer.json @@ -43,7 +43,8 @@ "fakerphp/faker": "^1.9.2", "squizlabs/php_codesniffer": "^3.2", "php-parallel-lint/php-parallel-lint": "^1.0", - "dms/phpunit-arraysubset-asserts": "dev-add-phpunit-11-support" + "dms/phpunit-arraysubset-asserts": "dev-add-phpunit-11-support", + "larastan/larastan": "^3.6" }, "repositories": [ { diff --git a/modules/backend/classes/Controller.php b/modules/backend/classes/Controller.php index 2259e16509..9d95ef2015 100644 --- a/modules/backend/classes/Controller.php +++ b/modules/backend/classes/Controller.php @@ -307,6 +307,8 @@ public function run($action = null, $params = []) */ $this->setNavigationContext($action, $params); + $result = null; + /* * Execute AJAX event */ diff --git a/modules/backend/classes/FilterScope.php b/modules/backend/classes/FilterScope.php index 1fa39c4e5b..822ef87163 100644 --- a/modules/backend/classes/FilterScope.php +++ b/modules/backend/classes/FilterScope.php @@ -56,6 +56,11 @@ class FilterScope */ public $dependsOn; + /** + * @var mixed Default value for this filter scope. + */ + public $default; + /** * @var string Specifies contextual visibility of this form scope. */ diff --git a/modules/backend/classes/FormTabs.php b/modules/backend/classes/FormTabs.php index 381b82b920..9b3462586e 100644 --- a/modules/backend/classes/FormTabs.php +++ b/modules/backend/classes/FormTabs.php @@ -203,7 +203,7 @@ public function getAllFields() /** * Returns an icon for the tab based on the tab's name. * @param string $name - * @return string + * @return string|null */ public function getIcon($name) { @@ -216,7 +216,7 @@ public function getIcon($name) * Returns a tab pane CSS class. * @param string $index * @param string $label - * @return string + * @return string|null */ public function getPaneCssClass($index = null, $label = null) { diff --git a/modules/backend/classes/MainMenuItem.php b/modules/backend/classes/MainMenuItem.php index ef64f562b6..09062f2eba 100644 --- a/modules/backend/classes/MainMenuItem.php +++ b/modules/backend/classes/MainMenuItem.php @@ -6,6 +6,8 @@ * Class MainMenuItem * * @package Backend\Classes + * + * @phpstan-consistent-constructor */ class MainMenuItem { diff --git a/modules/backend/classes/QuickActionItem.php b/modules/backend/classes/QuickActionItem.php index 8dab2e7251..da1b38ff82 100644 --- a/modules/backend/classes/QuickActionItem.php +++ b/modules/backend/classes/QuickActionItem.php @@ -4,6 +4,8 @@ * Class QuickActionItem * * @package Backend\Classes + * + * @phpstan-consistent-constructor */ class QuickActionItem { diff --git a/modules/backend/classes/SideMenuItem.php b/modules/backend/classes/SideMenuItem.php index a7fd9b647d..e397101dc1 100644 --- a/modules/backend/classes/SideMenuItem.php +++ b/modules/backend/classes/SideMenuItem.php @@ -4,6 +4,8 @@ * Class SideMenuItem * * @package Backend\Classes + * + * @phpstan-consistent-constructor */ class SideMenuItem { diff --git a/modules/backend/classes/WidgetBase.php b/modules/backend/classes/WidgetBase.php index 91f1ec57ae..5e18edc160 100644 --- a/modules/backend/classes/WidgetBase.php +++ b/modules/backend/classes/WidgetBase.php @@ -91,7 +91,7 @@ public function init() /** * Renders the widget's primary contents. - * @return string HTML markup supplied by this widget. + * @return string|null HTML markup supplied by this widget, or null when the widget renders nothing. */ public function render() { diff --git a/modules/backend/models/BrandSetting.php b/modules/backend/models/BrandSetting.php index bd3ae7d8d2..2fd0b9ce31 100644 --- a/modules/backend/models/BrandSetting.php +++ b/modules/backend/models/BrandSetting.php @@ -20,6 +20,12 @@ * @package winter\wn-backend-module * @author Alexey Bobkov, Samuel Georges * @author Winter CMS + * + * @mixin \System\Behaviors\SettingsModel + * @method static static instance() + * @method static bool isConfigured() + * @method static mixed get(string $key, mixed $default = null) + * @method static void resetDefault() */ class BrandSetting extends Model { diff --git a/modules/backend/models/EditorSetting.php b/modules/backend/models/EditorSetting.php index 0f6d21ab84..666538dc42 100644 --- a/modules/backend/models/EditorSetting.php +++ b/modules/backend/models/EditorSetting.php @@ -14,6 +14,12 @@ * * @package winter\wn-backend-module * @author Alexey Bobkov, Samuel Georges + * + * @mixin \System\Behaviors\SettingsModel + * @method static static instance() + * @method static bool isConfigured() + * @method static mixed get(string $key, mixed $default = null) + * @method static void resetDefault() */ class EditorSetting extends Model { diff --git a/modules/backend/models/ImportModel.php b/modules/backend/models/ImportModel.php index 8552d08b4d..4ed6bf9b56 100644 --- a/modules/backend/models/ImportModel.php +++ b/modules/backend/models/ImportModel.php @@ -12,6 +12,8 @@ * * @package winter\wn-backend-module * @author Alexey Bobkov, Samuel Georges + * + * @method \Winter\Storm\Database\Relations\AttachOne import_file() */ abstract class ImportModel extends Model { diff --git a/modules/backend/models/Preference.php b/modules/backend/models/Preference.php index ee25b9294c..c6655ceab2 100644 --- a/modules/backend/models/Preference.php +++ b/modules/backend/models/Preference.php @@ -17,6 +17,12 @@ * * @package winter\wn-backend-module * @author Alexey Bobkov, Samuel Georges + * + * @mixin \System\Behaviors\SettingsModel + * @method static static instance() + * @method static bool isConfigured() + * @method static mixed get(string $key, mixed $default = null) + * @method static void resetDefault() */ class Preference extends Model { diff --git a/modules/cms/classes/Asset.php b/modules/cms/classes/Asset.php index 302b0544b0..55f6f5ea7f 100644 --- a/modules/cms/classes/Asset.php +++ b/modules/cms/classes/Asset.php @@ -15,6 +15,8 @@ * * @package winter\wn-cms-module * @author Alexey Bobkov, Samuel Georges + * + * @phpstan-consistent-constructor */ class Asset extends Extendable { diff --git a/modules/cms/classes/AutoDatasource.php b/modules/cms/classes/AutoDatasource.php index 63852ba8ba..524cb4a8ad 100644 --- a/modules/cms/classes/AutoDatasource.php +++ b/modules/cms/classes/AutoDatasource.php @@ -490,6 +490,8 @@ public function update(string $dirName, string $fileName, string $extension, str */ public function delete(string $dirName, string $fileName, string $extension): bool { + $success = false; + try { // Delete from only the active datasource if ($this->forceDeleting) { diff --git a/modules/cms/classes/CmsCompoundObject.php b/modules/cms/classes/CmsCompoundObject.php index 33a516d0a4..b10a1de7cc 100644 --- a/modules/cms/classes/CmsCompoundObject.php +++ b/modules/cms/classes/CmsCompoundObject.php @@ -18,6 +18,8 @@ * * @package winter\wn-cms-module * @author Alexey Bobkov, Samuel Georges + * + * @method \Winter\Storm\Halcyon\Collection get(array $columns = ['*']) */ class CmsCompoundObject extends CmsObject { diff --git a/modules/cms/classes/CmsException.php b/modules/cms/classes/CmsException.php index 3a2f05fa39..4ffaa1a344 100644 --- a/modules/cms/classes/CmsException.php +++ b/modules/cms/classes/CmsException.php @@ -67,6 +67,8 @@ public function __construct($message = null, $code = 100, ?Throwable $previous = */ public function processCompoundObject(Throwable $exception) { + $result = false; + switch ($this->code) { case 200: $result = $this->processIni($exception); diff --git a/modules/cms/classes/CmsObject.php b/modules/cms/classes/CmsObject.php index 4411d61d94..faef7bdb7f 100644 --- a/modules/cms/classes/CmsObject.php +++ b/modules/cms/classes/CmsObject.php @@ -204,7 +204,7 @@ public static function inTheme($theme) public function save(?array $options = null) { try { - parent::save($options); + return parent::save($options); } catch (Exception $ex) { $this->throwHalcyonSaveException($ex); @@ -322,6 +322,7 @@ public function getTwigCacheKey() /** * Converts an exception type thrown by Halcyon to a native CMS exception. * @param Exception $ex + * @return never */ protected function throwHalcyonSaveException(Exception $ex) { diff --git a/modules/cms/classes/CodeParser.php b/modules/cms/classes/CodeParser.php index 3d022ad7a8..f91ae73818 100644 --- a/modules/cms/classes/CodeParser.php +++ b/modules/cms/classes/CodeParser.php @@ -193,7 +193,7 @@ public function source($page, $layout, $controller) * In some rare cases the cache file will not contain the class * name we expect. When this happens, destroy the corrupt file, * flush the request cache, and repeat the cycle. - * @return void + * @return array */ protected function handleCorruptCache($data) { diff --git a/modules/cms/classes/ComponentManager.php b/modules/cms/classes/ComponentManager.php index 01858ce7c1..101389dc62 100644 --- a/modules/cms/classes/ComponentManager.php +++ b/modules/cms/classes/ComponentManager.php @@ -81,7 +81,7 @@ protected function loadComponents() * }); * * @param callable $definitions - * @return array Array values are class names. + * @return void */ public function registerComponents(callable $definitions) { @@ -195,7 +195,7 @@ public function hasComponent($name) * @param array $properties The properties set by the Page or Layout. * @param bool $isSoftComponent Defines if this is a soft component. * - * @return ComponentBase The component object. + * @return ComponentBase|null The component object, or null for an unresolvable soft component. * @throws SystemException If the (hard) component cannot be found or is not registered. */ public function makeComponent($name, $cmsObject = null, $properties = [], $isSoftComponent = false) diff --git a/modules/cms/classes/ComponentPartial.php b/modules/cms/classes/ComponentPartial.php index 3df5200011..a88008b589 100644 --- a/modules/cms/classes/ComponentPartial.php +++ b/modules/cms/classes/ComponentPartial.php @@ -12,6 +12,8 @@ * * @package winter\wn-cms-module * @author Alexey Bobkov, Samuel Georges + * + * @phpstan-consistent-constructor */ class ComponentPartial extends Extendable implements CmsObjectContract { diff --git a/modules/cms/classes/Controller.php b/modules/cms/classes/Controller.php index d3e855ca33..480ab2895d 100644 --- a/modules/cms/classes/Controller.php +++ b/modules/cms/classes/Controller.php @@ -32,6 +32,8 @@ * * @package winter\wn-cms-module * @author Alexey Bobkov, Samuel Georges + * + * @phpstan-consistent-constructor */ class Controller { diff --git a/modules/cms/classes/Page.php b/modules/cms/classes/Page.php index 6bf807eea4..f46587ec41 100644 --- a/modules/cms/classes/Page.php +++ b/modules/cms/classes/Page.php @@ -10,6 +10,8 @@ * * @package winter\wn-cms-module * @author Alexey Bobkov, Samuel Georges + * + * @method static \Winter\Storm\Halcyon\Builder sortBy(string $column, string $direction = 'asc') */ class Page extends CmsCompoundObject { diff --git a/modules/cms/classes/Router.php b/modules/cms/classes/Router.php index 04b0f429b4..fcc70a9b49 100644 --- a/modules/cms/classes/Router.php +++ b/modules/cms/classes/Router.php @@ -72,7 +72,7 @@ public function __construct(Theme $theme) /** * Finds a page by its URL. Returns the page object and sets the $parameters property. * @param string $url The requested URL string. - * @return \Cms\Classes\Page Returns \Cms\Classes\Page object or null if the page cannot be found. + * @return \Cms\Classes\Page|null Returns \Cms\Classes\Page object or null if the page cannot be found. */ public function findByUrl($url) { @@ -275,7 +275,7 @@ public function clearCache() /** * Sets the current routing parameters. * @param array $parameters - * @return array + * @return void */ public function setParameters(array $parameters) { diff --git a/modules/cms/models/MaintenanceSetting.php b/modules/cms/models/MaintenanceSetting.php index e81514f87b..c27f3b4a25 100644 --- a/modules/cms/models/MaintenanceSetting.php +++ b/modules/cms/models/MaintenanceSetting.php @@ -12,6 +12,12 @@ * * @package winter\wn-cms-module * @author Alexey Bobkov, Samuel Georges + * + * @mixin \System\Behaviors\SettingsModel + * @method static static instance() + * @method static bool isConfigured() + * @method static mixed get(string $key, mixed $default = null) + * @method static void resetDefault() */ class MaintenanceSetting extends Model { diff --git a/modules/cms/models/ThemeExport.php b/modules/cms/models/ThemeExport.php index 83856bd39e..733670a7d1 100644 --- a/modules/cms/models/ThemeExport.php +++ b/modules/cms/models/ThemeExport.php @@ -61,7 +61,7 @@ class ThemeExport extends Model */ public function save(?array $options = null, $sessionKey = null) { - throw new ApplicationException(sprintf("The % model is not intended to be saved, please use %s instead", get_class($this), 'ThemeData')); + throw new ApplicationException(sprintf("The %s model is not intended to be saved, please use %s instead", get_class($this), 'ThemeData')); } public function getFoldersOptions() diff --git a/modules/cms/models/ThemeImport.php b/modules/cms/models/ThemeImport.php index b31da568c7..5bf3d545df 100644 --- a/modules/cms/models/ThemeImport.php +++ b/modules/cms/models/ThemeImport.php @@ -13,6 +13,8 @@ * * @package winter\wn-cms-module * @author Alexey Bobkov, Samuel Georges + * + * @method \Winter\Storm\Database\Relations\AttachOne uploaded_file() */ class ThemeImport extends Model { @@ -66,7 +68,7 @@ class ThemeImport extends Model */ public function save(?array $options = null, $sessionKey = null) { - throw new ApplicationException(sprintf("The % model is not intended to be saved, please use %s instead", get_class($this), 'ThemeData')); + throw new ApplicationException(sprintf("The %s model is not intended to be saved, please use %s instead", get_class($this), 'ThemeData')); } public function getFoldersOptions() diff --git a/modules/system/classes/CombineAssets.php b/modules/system/classes/CombineAssets.php index bb185bad4a..fb1418155a 100644 --- a/modules/system/classes/CombineAssets.php +++ b/modules/system/classes/CombineAssets.php @@ -521,7 +521,7 @@ protected function setHashOnCombinerFilters($hash) /** * Returns a deep hash on filters that support it. * @param array $assets List of asset files. - * @return void + * @return string */ protected function getDeepHashFromAssets($assets) { diff --git a/modules/system/classes/ImageResizer.php b/modules/system/classes/ImageResizer.php index 5f178f4c43..166ca95de4 100644 --- a/modules/system/classes/ImageResizer.php +++ b/modules/system/classes/ImageResizer.php @@ -40,6 +40,8 @@ * @see System\Twig\Extension Twig filters for this class defined * @package winter\wn-system-module * @author Luke Towers + * + * @phpstan-consistent-constructor */ class ImageResizer { diff --git a/modules/system/classes/MediaLibrary.php b/modules/system/classes/MediaLibrary.php index 0a28ea0230..3e788b41cd 100644 --- a/modules/system/classes/MediaLibrary.php +++ b/modules/system/classes/MediaLibrary.php @@ -695,6 +695,8 @@ protected function scanFolderContents($fullFolderPath) } elseif ($content['type'] === 'dir') { $type = MediaLibraryItem::TYPE_FOLDER; $key = 'folders'; + } else { + continue; } $libraryItem = $this->initLibraryItem($content, $type); diff --git a/modules/system/classes/PluginBase.php b/modules/system/classes/PluginBase.php index 466279660b..4fcad0b9b0 100644 --- a/modules/system/classes/PluginBase.php +++ b/modules/system/classes/PluginBase.php @@ -118,7 +118,7 @@ public function registerComponents() /** * Registers back-end navigation items for this plugin. * - * @return array + * @return array|null */ public function registerNavigation() { @@ -141,7 +141,7 @@ public function registerNavigation() /** * Registers back-end quick actions for this plugin. * - * @return array + * @return array|null */ public function registerQuickActions() { @@ -164,7 +164,7 @@ public function registerQuickActions() /** * Registers any back-end permissions used by this plugin. * - * @return array + * @return array|null */ public function registerPermissions() { @@ -177,7 +177,7 @@ public function registerPermissions() /** * Registers any back-end configuration links used by this plugin. * - * @return array + * @return array|null */ public function registerSettings() { diff --git a/modules/system/classes/PluginManager.php b/modules/system/classes/PluginManager.php index 4715e848ec..78c5b5b3bf 100644 --- a/modules/system/classes/PluginManager.php +++ b/modules/system/classes/PluginManager.php @@ -258,6 +258,8 @@ public function registerAll(bool $force = false): void return; } + $pluginId = null; + try { foreach ($this->plugins as $pluginId => $plugin) { $this->registerPlugin($plugin, $pluginId); @@ -330,7 +332,7 @@ public function registerPlugin(PluginBase $plugin, ?string $pluginId = null): vo */ $configPath = $pluginPath . '/config'; if (File::isDirectory($configPath)) { - Config::package($pluginNamespace, $configPath, $pluginNamespace); + Config::package($pluginNamespace, $configPath); } /* @@ -381,6 +383,8 @@ public function bootAll(bool $force = false): void return; } + $pluginId = null; + try { foreach ($this->plugins as $pluginId => $plugin) { $this->bootPlugin($plugin); diff --git a/modules/system/classes/SystemController.php b/modules/system/classes/SystemController.php index 2b430ceb21..6aa73e0078 100644 --- a/modules/system/classes/SystemController.php +++ b/modules/system/classes/SystemController.php @@ -58,6 +58,8 @@ public function resizer(string $identifier, string $encodedUrl) } // Attempt to process the resize + $resizer = null; + try { $resizer = ImageResizer::fromIdentifier($identifier); $resizer->resize(); @@ -72,7 +74,7 @@ public function resizer(string $identifier, string $encodedUrl) } catch (Exception $ex) { // If it failed for any other reason, restore the config so that // the resizer route will continue to work until it succeeds - if (!empty($resizer)) { + if ($resizer !== null) { $resizer->storeConfig(); } diff --git a/modules/system/classes/UpdateManager.php b/modules/system/classes/UpdateManager.php index b02f2a9699..8902923359 100644 --- a/modules/system/classes/UpdateManager.php +++ b/modules/system/classes/UpdateManager.php @@ -424,7 +424,7 @@ public function uninstall() public function getBuildNumberManually($detailed = false) { $source = new SourceManifest(); - $manifest = new FileManifest(null, null, true); + $manifest = new FileManifest(); // Find build by comparing with source manifest return $source->compare($manifest, $detailed); @@ -655,7 +655,7 @@ public function rollbackPlugin(string $name, ?string $stopOnVersion = null) * @param string $name Plugin name. * @param string $hash Expected file hash. * @param boolean $installation Indicates whether this is a plugin installation request. - * @return self + * @return void */ public function downloadPlugin($name, $hash, $installation = false) { @@ -699,7 +699,7 @@ public function requestThemeDetails($name) * Downloads a theme from the update server. * @param string $name Theme name. * @param string $hash Expected file hash. - * @return self + * @return void */ public function downloadTheme($name, $hash) { @@ -853,6 +853,8 @@ public function requestChangelog() $build = Parameter::get('system::core.build'); // Determine branch + $branch = null; + if (!is_null($build)) { $branch = explode('.', $build); array_pop($branch); @@ -896,7 +898,7 @@ public function requestChangelog() protected function write($component, ...$arguments) { if ($this->notesOutput !== null) { - with(new $component($this->notesOutput))->render(...$arguments); + (new $component($this->notesOutput))->render(...$arguments); } return $this; diff --git a/modules/system/classes/VersionManager.php b/modules/system/classes/VersionManager.php index ea2e7735a9..f159ca1dfc 100644 --- a/modules/system/classes/VersionManager.php +++ b/modules/system/classes/VersionManager.php @@ -614,7 +614,7 @@ protected function hasDatabaseHistory($code, $version, $script = null) protected function write($component, ...$arguments) { if ($this->notesOutput !== null) { - with(new $component($this->notesOutput))->render(...$arguments); + (new $component($this->notesOutput))->render(...$arguments); } return $this; diff --git a/modules/system/classes/asset/BundleManager.php b/modules/system/classes/asset/BundleManager.php index 4da992350a..fc83d05007 100644 --- a/modules/system/classes/asset/BundleManager.php +++ b/modules/system/classes/asset/BundleManager.php @@ -75,7 +75,7 @@ public function init(): void ); }); - $manager->registerSetupHandler('react', function (string $packagePath, string $packageType) use ($manager) { + $manager->registerSetupHandler('react', function (string $packagePath, string $packageType) { if ($this->option('no-stubs')) { return; } @@ -261,6 +261,10 @@ public function registerBundle(string $name, array $definition): static /** * Registers a single bundle setup handler. + * + * The handler runs bound to the asset command invoking it, through Closure::call(). + * + * @param-closure-this \System\Console\Asset\AssetCreate $closure */ public function registerSetupHandler(string $name, Closure $closure): static { @@ -271,6 +275,10 @@ public function registerSetupHandler(string $name, Closure $closure): static /** * Registers a single bundle scaffold handler. + * + * The handler runs bound to the asset command invoking it, through Closure::call(). + * + * @param-closure-this \System\Console\Asset\AssetCreate $closure */ public function registerScaffoldHandler(string $name, Closure $closure): static { diff --git a/modules/system/models/LogSetting.php b/modules/system/models/LogSetting.php index 50766acaf8..2421d2caf7 100644 --- a/modules/system/models/LogSetting.php +++ b/modules/system/models/LogSetting.php @@ -7,6 +7,12 @@ * * @package winter\wn-system-module * @author Alexey Bobkov, Samuel Georges + * + * @mixin \System\Behaviors\SettingsModel + * @method static static instance() + * @method static bool isConfigured() + * @method static mixed get(string $key, mixed $default = null) + * @method static void resetDefault() */ class LogSetting extends Model { diff --git a/modules/system/models/MailBrandSetting.php b/modules/system/models/MailBrandSetting.php index 8f161d43c8..8109e44020 100644 --- a/modules/system/models/MailBrandSetting.php +++ b/modules/system/models/MailBrandSetting.php @@ -14,6 +14,12 @@ * * @package winter\wn-system-module * @author Alexey Bobkov, Samuel Georges + * + * @mixin \System\Behaviors\SettingsModel + * @method static static instance() + * @method static bool isConfigured() + * @method static mixed get(string $key, mixed $default = null) + * @method static void resetDefault() */ class MailBrandSetting extends Model { diff --git a/modules/system/models/MailSetting.php b/modules/system/models/MailSetting.php index 44147f69ff..b919ee1290 100644 --- a/modules/system/models/MailSetting.php +++ b/modules/system/models/MailSetting.php @@ -8,6 +8,12 @@ * * @package winter\wn-system-module * @author Alexey Bobkov, Samuel Georges + * + * @mixin \System\Behaviors\SettingsModel + * @method static static instance() + * @method static bool isConfigured() + * @method static mixed get(string $key, mixed $default = null) + * @method static void resetDefault() */ class MailSetting extends Model { diff --git a/modules/system/models/Parameter.php b/modules/system/models/Parameter.php index 8d7ed42c09..ad7cfdd336 100644 --- a/modules/system/models/Parameter.php +++ b/modules/system/models/Parameter.php @@ -12,6 +12,8 @@ * * @package winter\wn-system-module * @author Alexey Bobkov, Samuel Georges + * + * @method static \Winter\Storm\Database\Builder applyKey(string $key) */ class Parameter extends Model { diff --git a/phpstan-bootstrap.php b/phpstan-bootstrap.php new file mode 100644 index 0000000000..024975de72 --- /dev/null +++ b/phpstan-bootstrap.php @@ -0,0 +1,27 @@ +register(); + +foreach (glob(__DIR__ . '/modules/*', GLOB_ONLYDIR) as $modulePath) { + $classLoader->autoloadPackage(basename($modulePath), $modulePath); +} + +Illuminate\Foundation\AliasLoader::getInstance( + require __DIR__ . '/modules/system/aliases.php' +)->register(); diff --git a/phpstan-stubs/EventFacade.stub b/phpstan-stubs/EventFacade.stub new file mode 100644 index 0000000000..0a9514d71c --- /dev/null +++ b/phpstan-stubs/EventFacade.stub @@ -0,0 +1,13 @@ +Hello, world!

\ No newline at end of file diff --git a/themes/apitest/testobjects/compound-markup.htm b/themes/apitest/testobjects/compound-markup.htm new file mode 100644 index 0000000000..1f19a39b35 --- /dev/null +++ b/themes/apitest/testobjects/compound-markup.htm @@ -0,0 +1 @@ +

Hello, world!

\ No newline at end of file diff --git a/themes/apitest/testobjects/compound.htm b/themes/apitest/testobjects/compound.htm new file mode 100644 index 0000000000..cf46eaeb6f --- /dev/null +++ b/themes/apitest/testobjects/compound.htm @@ -0,0 +1,7 @@ +var = "value" +== + +== +

Hello, world!

\ No newline at end of file diff --git a/themes/apitest/testobjects/existingobj.htm b/themes/apitest/testobjects/existingobj.htm new file mode 100644 index 0000000000..1979fe4583 --- /dev/null +++ b/themes/apitest/testobjects/existingobj.htm @@ -0,0 +1 @@ +str \ No newline at end of file diff --git a/themes/apitest/testobjects/testsubdir/mytestobj.htm b/themes/apitest/testobjects/testsubdir/mytestobj.htm new file mode 100644 index 0000000000..e9bdfffd0b --- /dev/null +++ b/themes/apitest/testobjects/testsubdir/mytestobj.htm @@ -0,0 +1 @@ +mytestcontent \ No newline at end of file