From ef94f03cde0a1847c17a0a96e9dc26de73275afe Mon Sep 17 00:00:00 2001 From: ouidade Date: Tue, 15 Mar 2022 10:52:21 +0100 Subject: [PATCH] maj --- CHANGELOG.md | 117 +++ README.md | 17 +- assets/.gitkeep | 2 +- bin/composer.phar | Bin 2205196 -> 2291189 bytes bin/gpm | 14 +- bin/grav | 14 +- bin/plugin | 14 +- composer.json | 30 +- composer.lock | 809 +++++++++--------- index.php | 34 +- system/blueprints/config/system.yaml | 159 +++- system/blueprints/flex/pages.yaml | 2 +- system/blueprints/flex/user-accounts.yaml | 2 + system/blueprints/flex/user-groups.yaml | 1 + system/blueprints/pages/default.yaml | 12 + system/blueprints/pages/external.yaml | 18 +- .../blueprints/pages/partials/security.yaml | 10 +- system/blueprints/user/account.yaml | 19 +- system/config/media.yaml | 2 +- system/config/system.yaml | 5 + system/defines.php | 4 +- system/install.php | 2 +- system/languages/es.yaml | 12 +- system/router.php | 6 +- system/src/DOMLettersIterator.php | 165 ++++ system/src/DOMWordsIterator.php | 158 ++++ system/src/Grav/Common/Assets.php | 167 +++- system/src/Grav/Common/Assets/BaseAsset.php | 23 +- system/src/Grav/Common/Assets/BlockAssets.php | 207 +++++ system/src/Grav/Common/Assets/Css.php | 4 +- system/src/Grav/Common/Assets/InlineCss.php | 4 +- system/src/Grav/Common/Assets/InlineJs.php | 4 +- .../src/Grav/Common/Assets/InlineJsModule.php | 46 + system/src/Grav/Common/Assets/Js.php | 4 +- system/src/Grav/Common/Assets/JsModule.php | 49 ++ system/src/Grav/Common/Assets/Link.php | 43 + system/src/Grav/Common/Assets/Pipeline.php | 65 +- .../Common/Assets/Traits/AssetUtilsTrait.php | 18 +- .../Assets/Traits/LegacyAssetsTrait.php | 2 +- .../Assets/Traits/TestingAssetsTrait.php | 11 +- system/src/Grav/Common/Backup/Backups.php | 8 +- system/src/Grav/Common/Browser.php | 2 +- system/src/Grav/Common/Cache.php | 4 +- system/src/Grav/Common/Composer.php | 2 +- .../src/Grav/Common/Config/CompiledBase.php | 2 +- .../Grav/Common/Config/CompiledBlueprints.php | 2 +- .../src/Grav/Common/Config/CompiledConfig.php | 2 +- .../Grav/Common/Config/CompiledLanguages.php | 2 +- system/src/Grav/Common/Config/Config.php | 2 +- .../Grav/Common/Config/ConfigFileFinder.php | 2 +- system/src/Grav/Common/Config/Languages.php | 2 +- system/src/Grav/Common/Config/Setup.php | 4 +- system/src/Grav/Common/Data/Blueprint.php | 13 +- .../src/Grav/Common/Data/BlueprintSchema.php | 20 +- system/src/Grav/Common/Data/Blueprints.php | 2 +- system/src/Grav/Common/Data/Data.php | 3 +- system/src/Grav/Common/Data/DataInterface.php | 2 +- system/src/Grav/Common/Data/Validation.php | 4 +- .../Grav/Common/Data/ValidationException.php | 2 +- system/src/Grav/Common/Debugger.php | 6 +- system/src/Grav/Common/Errors/BareHandler.php | 2 +- system/src/Grav/Common/Errors/Errors.php | 2 +- .../Grav/Common/Errors/SimplePageHandler.php | 2 +- .../src/Grav/Common/Errors/SystemFacade.php | 2 +- system/src/Grav/Common/File/CompiledFile.php | 5 +- .../src/Grav/Common/File/CompiledJsonFile.php | 2 +- .../Grav/Common/File/CompiledMarkdownFile.php | 2 +- .../src/Grav/Common/File/CompiledYamlFile.php | 2 +- .../src/Grav/Common/Filesystem/Archiver.php | 2 +- system/src/Grav/Common/Filesystem/Folder.php | 7 +- .../RecursiveDirectoryFilterIterator.php | 2 +- .../RecursiveFolderFilterIterator.php | 2 +- .../Grav/Common/Filesystem/ZipArchiver.php | 2 +- .../src/Grav/Common/Flex/FlexCollection.php | 2 +- system/src/Grav/Common/Flex/FlexIndex.php | 2 +- system/src/Grav/Common/Flex/FlexObject.php | 2 +- .../Flex/Traits/FlexCollectionTrait.php | 2 +- .../Common/Flex/Traits/FlexCommonTrait.php | 2 +- .../Grav/Common/Flex/Traits/FlexGravTrait.php | 2 +- .../Common/Flex/Traits/FlexIndexTrait.php | 2 +- .../Common/Flex/Traits/FlexObjectTrait.php | 2 +- .../Flex/Types/Generic/GenericCollection.php | 2 +- .../Flex/Types/Generic/GenericIndex.php | 2 +- .../Flex/Types/Generic/GenericObject.php | 2 +- .../Flex/Types/Pages/PageCollection.php | 49 +- .../Common/Flex/Types/Pages/PageIndex.php | 52 +- .../Common/Flex/Types/Pages/PageObject.php | 27 +- .../Flex/Types/Pages/Storage/PageStorage.php | 10 +- .../Types/Pages/Traits/PageContentTrait.php | 2 +- .../Types/Pages/Traits/PageLegacyTrait.php | 2 +- .../Types/Pages/Traits/PageRoutableTrait.php | 2 +- .../Types/Pages/Traits/PageTranslateTrait.php | 2 +- .../Types/UserGroups/UserGroupCollection.php | 4 +- .../Flex/Types/UserGroups/UserGroupIndex.php | 2 +- .../Flex/Types/UserGroups/UserGroupObject.php | 4 +- .../Types/Users/Storage/UserFileStorage.php | 2 +- .../Types/Users/Storage/UserFolderStorage.php | 2 +- .../Users/Traits/UserObjectLegacyTrait.php | 3 +- .../Flex/Types/Users/UserCollection.php | 2 +- .../Common/Flex/Types/Users/UserIndex.php | 4 +- .../Common/Flex/Types/Users/UserObject.php | 56 +- system/src/Grav/Common/Form/FormFlash.php | 7 +- .../Grav/Common/GPM/AbstractCollection.php | 2 +- .../GPM/Common/AbstractPackageCollection.php | 2 +- .../Common/GPM/Common/CachedCollection.php | 2 +- system/src/Grav/Common/GPM/Common/Package.php | 6 +- system/src/Grav/Common/GPM/GPM.php | 12 +- system/src/Grav/Common/GPM/Installer.php | 5 +- system/src/Grav/Common/GPM/Licenses.php | 2 +- .../GPM/Local/AbstractPackageCollection.php | 2 +- system/src/Grav/Common/GPM/Local/Package.php | 2 +- system/src/Grav/Common/GPM/Local/Packages.php | 2 +- system/src/Grav/Common/GPM/Local/Plugins.php | 2 +- system/src/Grav/Common/GPM/Local/Themes.php | 2 +- .../GPM/Remote/AbstractPackageCollection.php | 2 +- .../src/Grav/Common/GPM/Remote/GravCore.php | 2 +- system/src/Grav/Common/GPM/Remote/Package.php | 3 +- .../src/Grav/Common/GPM/Remote/Packages.php | 2 +- system/src/Grav/Common/GPM/Remote/Plugins.php | 2 +- system/src/Grav/Common/GPM/Remote/Themes.php | 2 +- system/src/Grav/Common/GPM/Upgrader.php | 2 +- system/src/Grav/Common/Getters.php | 7 +- system/src/Grav/Common/Grav.php | 106 ++- system/src/Grav/Common/GravTrait.php | 2 +- system/src/Grav/Common/HTTP/Client.php | 2 +- system/src/Grav/Common/HTTP/Response.php | 2 +- system/src/Grav/Common/Helpers/Base32.php | 2 +- system/src/Grav/Common/Helpers/Excerpts.php | 2 +- system/src/Grav/Common/Helpers/Exif.php | 2 +- system/src/Grav/Common/Helpers/LogViewer.php | 4 +- system/src/Grav/Common/Helpers/Truncator.php | 2 +- system/src/Grav/Common/Helpers/YamlLinter.php | 5 +- system/src/Grav/Common/Inflector.php | 2 +- system/src/Grav/Common/Iterator.php | 5 +- system/src/Grav/Common/Language/Language.php | 3 +- .../Grav/Common/Language/LanguageCodes.php | 6 +- system/src/Grav/Common/Markdown/Parsedown.php | 2 +- .../Grav/Common/Markdown/ParsedownExtra.php | 2 +- .../Common/Markdown/ParsedownGravTrait.php | 3 +- .../Media/Interfaces/AudioMediaInterface.php | 2 +- .../Interfaces/ImageManipulateInterface.php | 2 +- .../Media/Interfaces/ImageMediaInterface.php | 2 +- .../Interfaces/MediaCollectionInterface.php | 2 +- .../Media/Interfaces/MediaFileInterface.php | 2 +- .../Media/Interfaces/MediaInterface.php | 2 +- .../Media/Interfaces/MediaLinkInterface.php | 2 +- .../Media/Interfaces/MediaObjectInterface.php | 13 +- .../Media/Interfaces/MediaPlayerInterface.php | 2 +- .../Media/Interfaces/MediaUploadInterface.php | 2 +- .../Media/Interfaces/VideoMediaInterface.php | 2 +- .../Common/Media/Traits/AudioMediaTrait.php | 2 +- .../Common/Media/Traits/ImageLoadingTrait.php | 2 +- .../Common/Media/Traits/ImageMediaTrait.php | 2 +- .../Common/Media/Traits/MediaFileTrait.php | 2 +- .../Common/Media/Traits/MediaObjectTrait.php | 33 +- .../Common/Media/Traits/MediaPlayerTrait.php | 12 +- .../Grav/Common/Media/Traits/MediaTrait.php | 2 +- .../Common/Media/Traits/MediaUploadTrait.php | 12 +- .../Common/Media/Traits/StaticResizeTrait.php | 2 +- .../Media/Traits/ThumbnailMediaTrait.php | 2 +- .../Common/Media/Traits/VideoMediaTrait.php | 4 +- system/src/Grav/Common/Page/Collection.php | 5 +- system/src/Grav/Common/Page/Header.php | 3 +- .../Interfaces/PageCollectionInterface.php | 29 +- .../Page/Interfaces/PageContentInterface.php | 14 +- .../Common/Page/Interfaces/PageInterface.php | 2 +- .../Interfaces/PageTranslateInterface.php | 5 + .../Page/Interfaces/PagesSourceInterface.php | 2 +- .../Grav/Common/Page/Markdown/Excerpts.php | 4 +- system/src/Grav/Common/Page/Media.php | 59 +- .../Grav/Common/Page/Medium/AbstractMedia.php | 3 +- .../Grav/Common/Page/Medium/AudioMedium.php | 2 +- .../Grav/Common/Page/Medium/GlobalMedia.php | 5 +- .../src/Grav/Common/Page/Medium/ImageFile.php | 3 +- .../Grav/Common/Page/Medium/ImageMedium.php | 42 +- system/src/Grav/Common/Page/Medium/Link.php | 5 +- system/src/Grav/Common/Page/Medium/Medium.php | 12 +- .../Grav/Common/Page/Medium/MediumFactory.php | 14 +- .../Common/Page/Medium/ParsedownHtmlTrait.php | 2 +- .../Page/Medium/RenderableInterface.php | 2 +- .../Common/Page/Medium/StaticImageMedium.php | 10 +- .../Common/Page/Medium/StaticResizeTrait.php | 2 +- .../Page/Medium/ThumbnailImageMedium.php | 2 +- .../Common/Page/Medium/VectorImageMedium.php | 68 ++ .../Grav/Common/Page/Medium/VideoMedium.php | 2 +- system/src/Grav/Common/Page/Page.php | 28 +- system/src/Grav/Common/Page/Pages.php | 23 +- system/src/Grav/Common/Page/Types.php | 5 +- system/src/Grav/Common/Plugin.php | 28 +- system/src/Grav/Common/Plugins.php | 2 +- .../Common/Processors/AssetsProcessor.php | 2 +- .../Common/Processors/BackupsProcessor.php | 2 +- .../Processors/DebuggerAssetsProcessor.php | 2 +- .../Processors/Events/RequestHandlerEvent.php | 2 +- .../Common/Processors/InitializeProcessor.php | 2 +- .../Grav/Common/Processors/PagesProcessor.php | 2 +- .../Common/Processors/PluginsProcessor.php | 2 +- .../Grav/Common/Processors/ProcessorBase.php | 2 +- .../Common/Processors/ProcessorInterface.php | 2 +- .../Common/Processors/RenderProcessor.php | 2 +- .../Common/Processors/RequestProcessor.php | 5 +- .../Common/Processors/SchedulerProcessor.php | 2 +- .../Grav/Common/Processors/TasksProcessor.php | 2 +- .../Common/Processors/ThemesProcessor.php | 2 +- .../Grav/Common/Processors/TwigProcessor.php | 2 +- system/src/Grav/Common/Scheduler/Cron.php | 2 +- .../Grav/Common/Scheduler/IntervalTrait.php | 2 +- system/src/Grav/Common/Scheduler/Job.php | 2 +- .../src/Grav/Common/Scheduler/Scheduler.php | 2 +- system/src/Grav/Common/Security.php | 24 +- .../Service/AccountsServiceProvider.php | 2 +- .../Common/Service/AssetsServiceProvider.php | 2 +- .../Common/Service/BackupsServiceProvider.php | 2 +- .../Common/Service/ConfigServiceProvider.php | 2 +- .../Common/Service/ErrorServiceProvider.php | 2 +- .../Service/FilesystemServiceProvider.php | 2 +- .../Common/Service/FlexServiceProvider.php | 2 +- .../Service/InflectorServiceProvider.php | 2 +- .../Common/Service/LoggerServiceProvider.php | 2 +- .../Common/Service/OutputServiceProvider.php | 2 +- .../Common/Service/PagesServiceProvider.php | 5 +- .../Common/Service/RequestServiceProvider.php | 2 +- .../Service/SchedulerServiceProvider.php | 2 +- .../Common/Service/SessionServiceProvider.php | 5 +- .../Common/Service/StreamsServiceProvider.php | 2 +- .../Common/Service/TaskServiceProvider.php | 2 +- system/src/Grav/Common/Session.php | 2 +- system/src/Grav/Common/Taxonomy.php | 2 +- system/src/Grav/Common/Theme.php | 2 +- system/src/Grav/Common/Themes.php | 2 +- .../Common/Twig/Exception/TwigException.php | 6 +- .../Twig/Extension/FilesystemExtension.php | 26 +- .../Common/Twig/Extension/GravExtension.php | 23 +- .../Grav/Common/Twig/Node/TwigNodeCache.php | 2 +- .../Grav/Common/Twig/Node/TwigNodeLink.php | 114 +++ .../Common/Twig/Node/TwigNodeMarkdown.php | 2 +- .../Grav/Common/Twig/Node/TwigNodeRender.php | 3 +- .../Grav/Common/Twig/Node/TwigNodeScript.php | 84 +- .../Grav/Common/Twig/Node/TwigNodeStyle.php | 72 +- .../Grav/Common/Twig/Node/TwigNodeSwitch.php | 2 +- .../Grav/Common/Twig/Node/TwigNodeThrow.php | 2 +- .../Common/Twig/Node/TwigNodeTryCatch.php | 2 +- .../Twig/TokenParser/TwigTokenParserCache.php | 2 +- .../Twig/TokenParser/TwigTokenParserLink.php | 109 +++ .../TokenParser/TwigTokenParserMarkdown.php | 2 +- .../TokenParser/TwigTokenParserRender.php | 2 +- .../TokenParser/TwigTokenParserScript.php | 28 +- .../Twig/TokenParser/TwigTokenParserStyle.php | 2 +- .../TokenParser/TwigTokenParserSwitch.php | 2 +- .../Twig/TokenParser/TwigTokenParserThrow.php | 2 +- .../TokenParser/TwigTokenParserTryCatch.php | 2 +- system/src/Grav/Common/Twig/Twig.php | 9 +- .../Common/Twig/TwigClockworkDataSource.php | 2 +- .../Grav/Common/Twig/TwigClockworkDumper.php | 2 +- .../src/Grav/Common/Twig/TwigEnvironment.php | 41 +- system/src/Grav/Common/Twig/TwigExtension.php | 2 +- .../Grav/Common/Twig/WriteCacheFileTrait.php | 2 +- system/src/Grav/Common/Uri.php | 25 +- system/src/Grav/Common/User/Access.php | 2 +- .../src/Grav/Common/User/Authentication.php | 2 +- system/src/Grav/Common/User/DataUser/User.php | 8 +- .../Common/User/DataUser/UserCollection.php | 4 +- system/src/Grav/Common/User/Group.php | 2 +- .../User/Interfaces/AuthorizeInterface.php | 2 +- .../Interfaces/UserCollectionInterface.php | 2 +- .../User/Interfaces/UserGroupInterface.php | 2 +- .../Common/User/Interfaces/UserInterface.php | 2 +- .../src/Grav/Common/User/Traits/UserTrait.php | 52 +- system/src/Grav/Common/User/User.php | 2 +- system/src/Grav/Common/Utils.php | 97 ++- system/src/Grav/Common/Yaml.php | 2 +- .../Grav/Console/Application/Application.php | 48 +- .../CommandLoader/PluginCommandLoader.php | 2 +- .../Console/Application/GpmApplication.php | 2 +- .../Console/Application/GravApplication.php | 2 +- .../Console/Application/PluginApplication.php | 2 +- system/src/Grav/Console/Cli/BackupCommand.php | 2 +- system/src/Grav/Console/Cli/CleanCommand.php | 2 +- .../Grav/Console/Cli/ClearCacheCommand.php | 2 +- .../src/Grav/Console/Cli/ComposerCommand.php | 2 +- .../src/Grav/Console/Cli/InstallCommand.php | 2 +- .../src/Grav/Console/Cli/LogViewerCommand.php | 2 +- .../Grav/Console/Cli/NewProjectCommand.php | 2 +- .../Cli/PageSystemValidatorCommand.php | 2 +- .../src/Grav/Console/Cli/SandboxCommand.php | 9 +- .../src/Grav/Console/Cli/SchedulerCommand.php | 4 +- .../src/Grav/Console/Cli/SecurityCommand.php | 2 +- system/src/Grav/Console/Cli/ServerCommand.php | 2 +- .../Grav/Console/Cli/YamlLinterCommand.php | 2 +- system/src/Grav/Console/ConsoleCommand.php | 2 +- system/src/Grav/Console/ConsoleTrait.php | 2 +- .../Grav/Console/Gpm/DirectInstallCommand.php | 2 +- system/src/Grav/Console/Gpm/IndexCommand.php | 2 +- system/src/Grav/Console/Gpm/InfoCommand.php | 2 +- .../src/Grav/Console/Gpm/InstallCommand.php | 4 +- .../Grav/Console/Gpm/SelfupgradeCommand.php | 2 +- .../src/Grav/Console/Gpm/UninstallCommand.php | 2 +- system/src/Grav/Console/Gpm/UpdateCommand.php | 2 +- .../src/Grav/Console/Gpm/VersionCommand.php | 2 +- system/src/Grav/Console/GpmCommand.php | 2 +- system/src/Grav/Console/GravCommand.php | 2 +- .../Grav/Console/Plugin/PluginListCommand.php | 2 +- .../Grav/Console/TerminalObjects/Table.php | 2 +- system/src/Grav/Events/FlexRegisterEvent.php | 2 +- .../Grav/Events/PermissionsRegisterEvent.php | 2 +- system/src/Grav/Events/PluginsLoadedEvent.php | 2 +- system/src/Grav/Events/SessionStartEvent.php | 2 +- system/src/Grav/Framework/Acl/Access.php | 13 +- system/src/Grav/Framework/Acl/Action.php | 21 +- system/src/Grav/Framework/Acl/Permissions.php | 19 +- .../Grav/Framework/Acl/PermissionsReader.php | 15 +- .../Framework/Acl/RecursiveActionIterator.php | 4 +- .../Grav/Framework/Cache/AbstractCache.php | 2 +- .../Framework/Cache/Adapter/ChainCache.php | 10 +- .../Framework/Cache/Adapter/DoctrineCache.php | 10 +- .../Framework/Cache/Adapter/FileCache.php | 21 +- .../Framework/Cache/Adapter/MemoryCache.php | 2 +- .../Framework/Cache/Adapter/SessionCache.php | 2 +- .../Grav/Framework/Cache/CacheInterface.php | 2 +- .../src/Grav/Framework/Cache/CacheTrait.php | 2 +- .../Cache/Exception/CacheException.php | 2 +- .../Exception/InvalidArgumentException.php | 2 +- .../Collection/AbstractFileCollection.php | 6 +- .../Collection/AbstractIndexCollection.php | 56 +- .../Collection/AbstractLazyCollection.php | 14 +- .../Framework/Collection/ArrayCollection.php | 25 +- .../Collection/CollectionInterface.php | 3 +- .../Framework/Collection/FileCollection.php | 2 +- .../Collection/FileCollectionInterface.php | 2 +- .../Grav/Framework/Compat/Serializable.php | 2 +- .../Framework/ContentBlock/ContentBlock.php | 3 +- .../ContentBlock/ContentBlockInterface.php | 2 +- .../Grav/Framework/ContentBlock/HtmlBlock.php | 118 ++- .../ContentBlock/HtmlBlockInterface.php | 39 +- .../Traits/ControllerResponseTrait.php | 9 +- system/src/Grav/Framework/DI/Container.php | 2 +- .../src/Grav/Framework/File/AbstractFile.php | 9 +- system/src/Grav/Framework/File/CsvFile.php | 11 +- system/src/Grav/Framework/File/DataFile.php | 2 +- system/src/Grav/Framework/File/File.php | 11 +- .../File/Formatter/AbstractFormatter.php | 2 +- .../Framework/File/Formatter/CsvFormatter.php | 3 +- .../Framework/File/Formatter/IniFormatter.php | 5 +- .../File/Formatter/JsonFormatter.php | 19 +- .../File/Formatter/MarkdownFormatter.php | 7 +- .../File/Formatter/SerializeFormatter.php | 2 +- .../File/Formatter/YamlFormatter.php | 6 +- system/src/Grav/Framework/File/IniFile.php | 11 +- .../Interfaces/FileFormatterInterface.php | 2 +- .../File/Interfaces/FileInterface.php | 2 +- system/src/Grav/Framework/File/JsonFile.php | 2 +- .../src/Grav/Framework/File/MarkdownFile.php | 11 +- system/src/Grav/Framework/File/YamlFile.php | 11 +- .../Grav/Framework/Filesystem/Filesystem.php | 32 +- .../Interfaces/FilesystemInterface.php | 10 +- system/src/Grav/Framework/Flex/Flex.php | 10 +- .../Grav/Framework/Flex/FlexCollection.php | 34 +- .../src/Grav/Framework/Flex/FlexDirectory.php | 64 +- .../Grav/Framework/Flex/FlexDirectoryForm.php | 7 +- system/src/Grav/Framework/Flex/FlexForm.php | 7 +- .../src/Grav/Framework/Flex/FlexFormFlash.php | 2 +- system/src/Grav/Framework/Flex/FlexIndex.php | 45 +- system/src/Grav/Framework/Flex/FlexObject.php | 21 +- .../Interfaces/FlexAuthorizeInterface.php | 2 +- .../Interfaces/FlexCollectionInterface.php | 4 +- .../Flex/Interfaces/FlexCommonInterface.php | 2 +- .../Interfaces/FlexDirectoryFormInterface.php | 2 +- .../Interfaces/FlexDirectoryInterface.php | 7 +- .../Flex/Interfaces/FlexFormInterface.php | 7 +- .../Flex/Interfaces/FlexIndexInterface.php | 2 +- .../Flex/Interfaces/FlexInterface.php | 4 +- .../Interfaces/FlexObjectFormInterface.php | 2 +- .../Flex/Interfaces/FlexObjectInterface.php | 3 +- .../Flex/Interfaces/FlexStorageInterface.php | 2 +- .../Interfaces/FlexTranslateInterface.php | 2 +- .../Flex/Pages/FlexPageCollection.php | 20 +- .../Framework/Flex/Pages/FlexPageIndex.php | 2 +- .../Framework/Flex/Pages/FlexPageObject.php | 3 +- .../Flex/Pages/Traits/PageAuthorsTrait.php | 2 +- .../Flex/Pages/Traits/PageContentTrait.php | 20 +- .../Flex/Pages/Traits/PageLegacyTrait.php | 14 +- .../Flex/Pages/Traits/PageRoutableTrait.php | 6 +- .../Flex/Pages/Traits/PageTranslateTrait.php | 10 +- .../Storage/AbstractFilesystemStorage.php | 6 +- .../Framework/Flex/Storage/FileStorage.php | 5 +- .../Framework/Flex/Storage/FolderStorage.php | 6 +- .../Framework/Flex/Storage/SimpleStorage.php | 11 +- .../Flex/Traits/FlexAuthorizeTrait.php | 2 +- .../Framework/Flex/Traits/FlexMediaTrait.php | 18 +- .../Flex/Traits/FlexRelatedDirectoryTrait.php | 10 +- system/src/Grav/Framework/Form/FormFlash.php | 4 +- .../src/Grav/Framework/Form/FormFlashFile.php | 24 +- .../Form/Interfaces/FormFactoryInterface.php | 2 +- .../Form/Interfaces/FormFlashInterface.php | 2 +- .../Form/Interfaces/FormInterface.php | 2 +- .../Grav/Framework/Form/Traits/FormTrait.php | 28 +- .../Framework/Interfaces/RenderInterface.php | 2 +- .../Logger/Processors/UserProcessor.php | 2 +- .../Interfaces/MediaCollectionInterface.php | 10 +- .../Media/Interfaces/MediaInterface.php | 2 +- .../Interfaces/MediaManipulationInterface.php | 2 +- .../Media/Interfaces/MediaObjectInterface.php | 2 +- system/src/Grav/Framework/Mime/MimeTypes.php | 2 +- .../Object/Access/ArrayAccessTrait.php | 2 +- .../Object/Access/NestedArrayAccessTrait.php | 2 +- .../Access/NestedPropertyCollectionTrait.php | 2 +- .../Object/Access/NestedPropertyTrait.php | 14 +- .../Object/Access/OverloadedPropertyTrait.php | 6 +- .../src/Grav/Framework/Object/ArrayObject.php | 3 +- .../Object/Base/ObjectCollectionTrait.php | 19 +- .../Framework/Object/Base/ObjectTrait.php | 4 +- .../Collection/ObjectExpressionVisitor.php | 7 +- .../NestedObjectCollectionInterface.php | 2 +- .../Interfaces/NestedObjectInterface.php | 2 +- .../Interfaces/ObjectCollectionInterface.php | 2 +- .../Object/Interfaces/ObjectInterface.php | 2 +- .../src/Grav/Framework/Object/LazyObject.php | 3 +- .../Framework/Object/ObjectCollection.php | 15 +- .../src/Grav/Framework/Object/ObjectIndex.php | 27 +- .../Object/Property/ArrayPropertyTrait.php | 4 +- .../Object/Property/LazyPropertyTrait.php | 5 +- .../Object/Property/MixedPropertyTrait.php | 2 +- .../Object/Property/ObjectPropertyTrait.php | 2 +- .../Grav/Framework/Object/PropertyObject.php | 4 +- .../Pagination/AbstractPagination.php | 4 +- .../Pagination/AbstractPaginationPage.php | 4 +- .../Interfaces/PaginationInterface.php | 3 +- .../Interfaces/PaginationPageInterface.php | 2 +- .../Grav/Framework/Pagination/Pagination.php | 2 +- .../Framework/Pagination/PaginationPage.php | 2 +- .../src/Grav/Framework/Psr7/AbstractUri.php | 3 +- system/src/Grav/Framework/Psr7/Request.php | 2 +- system/src/Grav/Framework/Psr7/Response.php | 5 +- .../src/Grav/Framework/Psr7/ServerRequest.php | 16 +- system/src/Grav/Framework/Psr7/Stream.php | 2 +- .../Psr7/Traits/MessageDecoratorTrait.php | 2 +- .../Psr7/Traits/RequestDecoratorTrait.php | 2 +- .../Psr7/Traits/ResponseDecoratorTrait.php | 2 +- .../Traits/ServerRequestDecoratorTrait.php | 2 +- .../Psr7/Traits/StreamDecoratorTrait.php | 3 +- .../Traits/UploadedFileDecoratorTrait.php | 2 +- .../Psr7/Traits/UriDecorationTrait.php | 2 +- .../src/Grav/Framework/Psr7/UploadedFile.php | 2 +- system/src/Grav/Framework/Psr7/Uri.php | 5 +- .../Exception/InvalidArgumentException.php | 2 +- .../Exception/NotFoundException.php | 10 +- .../Exception/NotHandledException.php | 2 +- .../Exception/PageExpiredException.php | 2 +- .../Exception/RequestException.php | 2 +- .../RequestHandler/Middlewares/Exceptions.php | 2 +- .../RequestHandler/RequestHandler.php | 16 +- .../Traits/RequestHandlerTrait.php | 2 +- system/src/Grav/Framework/Route/Route.php | 6 +- .../src/Grav/Framework/Route/RouteFactory.php | 2 +- .../Session/Exceptions/SessionException.php | 2 +- .../src/Grav/Framework/Session/Messages.php | 2 +- system/src/Grav/Framework/Session/Session.php | 25 +- .../Framework/Session/SessionInterface.php | 9 +- system/src/Grav/Framework/Uri/Uri.php | 2 +- system/src/Grav/Framework/Uri/UriFactory.php | 4 +- .../src/Grav/Framework/Uri/UriPartsFilter.php | 2 +- system/src/Grav/Installer/Install.php | 18 +- .../src/Grav/Installer/InstallException.php | 2 +- system/src/Grav/Installer/VersionUpdate.php | 3 +- system/src/Grav/Installer/Versions.php | 2 +- system/src/Grav/Installer/YamlUpdater.php | 3 +- .../DeferredNodeVisitorCompat.php | 21 +- user/config/versions.yaml | 3 +- .../05.demande-de-devis/form.fr.md | 169 ++++ .../pages_offline/05.demande-de-devis/form.md | 169 ++++ .../05.demande-de-devis/vue_ext.jpg | Bin 0 -> 407754 bytes user/themes/lecampus/scss/theme/_form3.scss | 119 +++ webserver-configs/htaccess.txt | 4 +- webserver-configs/lighttpd.conf | 2 +- webserver-configs/nginx.conf | 4 +- webserver-configs/web.config | 6 +- 476 files changed, 4612 insertions(+), 1563 deletions(-) create mode 100644 system/src/DOMLettersIterator.php create mode 100644 system/src/DOMWordsIterator.php create mode 100644 system/src/Grav/Common/Assets/BlockAssets.php create mode 100644 system/src/Grav/Common/Assets/InlineJsModule.php create mode 100644 system/src/Grav/Common/Assets/JsModule.php create mode 100644 system/src/Grav/Common/Assets/Link.php create mode 100644 system/src/Grav/Common/Page/Medium/VectorImageMedium.php create mode 100644 system/src/Grav/Common/Twig/Node/TwigNodeLink.php create mode 100644 system/src/Grav/Common/Twig/TokenParser/TwigTokenParserLink.php create mode 100644 user/pages_offline/05.demande-de-devis/form.fr.md create mode 100644 user/pages_offline/05.demande-de-devis/form.md create mode 100644 user/pages_offline/05.demande-de-devis/vue_ext.jpg create mode 100644 user/themes/lecampus/scss/theme/_form3.scss diff --git a/CHANGELOG.md b/CHANGELOG.md index b0c0eb3..5b396bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,120 @@ +# v1.7.31 +## 03/14/2022 + +1. [](#new) + * Added new local Multiavatar (local generation). **This will be default in Grav 1.8** + * Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533) + * Added XSS check for uploaded SVG files before they get stored + * Fixed phpstan issues (All level 2, Framework level 5) +2. [](#improved) + * Moved Accounts out of Experimental section of System configuration to new "Accounts" tab +3. [](#bugfix) + * Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504) + * Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542) + * Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540) + * Fixed entity sanitization for XSS detection + * Fixed avatar save location when `account://` stream points to custom directory + * Fixed bug in `Utils::url()` when path contains part of root + +# v1.7.30 +## 02/07/2022 + +1. [](#new) + * Added twig filter `|field_parent` to get parent field name +2. [](#bugfix) + * Fixed error while deleting retina image in admin + * Fixed "Page Authors" field in Security tab, wrongly loading and saving the value [#3525](https://github.com/getgrav/grav/issues/3525) + * Fixed accounts filter only matches against email address [getgrav/grav-plugin-admin#2224](https://github.com/getgrav/grav-plugin-admin/issues/2224) + +# v1.7.29.1 +## 01/31/2022 + +1. [](#bugfix) + * Fixed `Call to undefined method` error when upgrading from Grav 1.6 [#3523](https://github.com/getgrav/grav/issues/3523) + +# v1.7.29 +## 01/28/2022 + +1. [](#new) + * Added support for registering assets from `HtmlBlock` + * Added unicode-safe `Utils::basename()` and `Utils::pathinfo()` methods +2. [](#improved) + * Improved `Filesystem::basename()` and `Filesystem::pathinfo()` to be unicode-safe + * Made path handling unicode-safe, use new `Utils::basename()` and `Utils::pathinfo()` everywhere +3. [](#bugfix) + * Fixed error on thumbnail image creation + * Fixed MimeType for `gzip` (`application/x-gzip`) + +# v1.7.28 +## 01/24/2022 + +1. [](#new) + * Added links and modules support to `HtmlBlock` class + * Added module support for twig script tag: `{% script module 'theme://js/module.mjs' %}` + * Added twig tag for links: `{% link icon 'theme://images/favicon.png' priority: 20 with { type: 'image/png' } %}` + * Added `HtmlBlock` support for `{% style %}`, `{% script %}` and `{% link %}` tags + * Support for page-level `redirect_default_route` frontmatter header override +3. [](#bugfix) + * Fixed XSS check not detecting escaped `:` + +# v1.7.27.1 +## 01/12/2022 + +3. [](#bugfix) + * Fixed a typo in CSS Asset pipeline that was erroneously joining files with `;` + +# v1.7.27 +## 01/12/2022 + +1. [](#new) + * Support for `YubiKey OTP` 2-Factor authenticator + * Added support for generic `assets.link()` for external references. No pipeline support + * Added support for `assets.addJsModule()` with full pipeline support + * Added `Utils::getExtensionsByMime()` method to get all the registered extensions for the specific mime type + * Added `Media::getRoute()` and `Media::getRawRoute()` methods to get page route if available + * Added `Medium::getAlternatives()` to be able to list all the retina sizes +2. [](#improved) + * Improved `Utils::download()` method to allow overrides on download name, mime and expires header + * Improved `onPageFallBackUrl` event + * Reorganized the Asset system configuration blueprint for clarity +3. [](#bugfix) + * Fixed CLI `--env` and `--lang` options having no effect if they aren't added before all the other options + * Fixed scaled image medium filename when using non-existing retina file + * Fixed an issue with JS `imports` and pipelining Assets + +# v1.7.26.1 +## 01/04/2022 + +3. [](#bugfix) + * Fixed `UserObject::getAccess()` after cloning the object + +# v1.7.26 +## 01/03/2022 + +1. [](#new) + * Made `Grav::redirect()` to accept `Route` class + * Added `translated()` method to `PageTranslateInterface` + * Added second parameter to `UserObject::isMyself()` method + * Added `UserObject::$isAuthorizedCallable` to allow `$user->isAuthorized()` customization + * Use secure session cookies in HTTPS by default (`system.session.secure_https: true`) + * Added new `Plugin::inheritedConfigOption()` function to access plugin specific functions for page overrides +2. [](#improved) + * Upgraded vendor libs for PHP 8.1 compatibility + * Upgraded to **composer v2.1.14** for PHP 8.1 compatibility + * Added third `$name` parameter to `Blueprint::flattenData()` method, useful for flattening repeating data + * `ControllerResponseTrait`: Redirect response should be json if the extension is .json + * When symlinking Grav install, include also tests + * Updated copyright year to `2022` +3. [](#bugfix) + * Fixed bad key lookup in `FlexRelatedDirectoryTrait::getCollectionByProperty()` + * Fixed RequestHandlers `NotFoundException` having empty request + * Block `.json` files in web server configs + * Disabled pretty debug info for Flex as it slows down Twig rendering + * Fixed Twig being very slow when template overrides do not exist + * Fixed `UserObject::$authorizeCallable` binding to the user object + * Fixed `FlexIndex::call()` to return null instead of failing to call undefined method + * Fixed Flex directory configuration creating environment configuration when it should not + # v1.7.25 ## 11/16/2021 diff --git a/README.md b/README.md index 31a4a7e..f16f62b 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,18 @@ [![PHPStan](https://img.shields.io/badge/PHPStan-enabled-brightgreen.svg?style=flat)](https://github.com/phpstan/phpstan) [![Discord](https://img.shields.io/discord/501836936584101899.svg?logo=discord&colorB=728ADA&label=Discord%20Chat)](https://chat.getgrav.org) - [![PHP Tests](https://github.com/getgrav/grav/workflows/PHP%20Tests/badge.svg?branch=develop)](https://github.com/getgrav/grav/actions?query=workflow%3A%22PHP+Tests%22) [![OpenCollective](https://opencollective.com/grav/backers/badge.svg)](#backers) [![OpenCollective](https://opencollective.com/grav/sponsors/badge.svg)](#sponsors) + [![PHP Tests](https://github.com/getgrav/grav/workflows/PHP%20Tests/badge.svg?branch=develop)](https://github.com/getgrav/grav/actions?query=workflow%3A%22PHP+Tests%22) [![OpenCollective](https://opencollective.com/grav/tiers/backers/badge.svg?label=Backers&color=brightgreen)](#backers) [![OpenCollective](https://opencollective.com/grav/tiers/supporters/badge.svg?label=Supporters&color=brightgreen)](#supporters) [![OpenCollective](https://opencollective.com/grav/tiers/sponsors/badge.svg?label=Sponsors&color=brightgreen)](#sponsors) Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself. The underlying architecture of Grav is designed to use well-established and _best-in-class_ technologies to ensure that Grav is simple to use and easy to extend. Some of these key technologies include: -* [Twig Templating](https://twig.sensiolabs.org/): for powerful control of the user interface +* [Twig Templating](https://twig.symfony.com/): for powerful control of the user interface * [Markdown](https://en.wikipedia.org/wiki/Markdown): for easy content creation * [YAML](https://yaml.org): for simple configuration * [Parsedown](https://parsedown.org/): for fast Markdown and Markdown Extra support * [Doctrine Cache](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html): layer for performance -* [Pimple Dependency Injection Container](https://pimple.sensiolabs.org/): for extensibility and maintainability +* [Pimple Dependency Injection Container](https://github.com/silexphp/Pimple): for extensibility and maintainability * [Symfony Event Dispatcher](https://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling * [Symfony Console](https://symfony.com/doc/current/components/console/introduction.html): for CLI interface * [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation @@ -117,12 +117,19 @@ If you discover a possible security issue related to Grav or one of its plugins, * More [Awesome Grav Stuff](https://github.com/getgrav/awesome-grav) # Backers -Support Grav with a monthly donation to help us continue development. [[Become a backer](https://opencollective.com/grav#backer)] +Support Grav with a monthly donation to help us continue development. [[Become a backer](https://opencollective.com/grav/contribute)] + +# Supporters +Support Grav with a monthly donation to help us continue development. [[Become a supporter](https://opencollective.com/grav/contribute)] + + + + # Sponsors -Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/grav#sponsor)] +Support Grav with a yearly donation to help us continue development. [[Become a sponsor](https://opencollective.com/grav/contribute)] diff --git a/assets/.gitkeep b/assets/.gitkeep index 33a9aed..8efbf1f 100644 --- a/assets/.gitkeep +++ b/assets/.gitkeep @@ -1 +1 @@ -/* @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. */ +/* @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. */ diff --git a/bin/composer.phar b/bin/composer.phar index 3791ce36ed26e033e485226ed288050ead25032b..f0461904b59bf1fb3f0991c4b79bb066828338dc 100755 GIT binary patch delta 132308 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 delta 85578 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 user/pages/14.api/default.17.md", "post-create-project-cmd": "bin/grav install", - "phpstan": "vendor/bin/phpstan analyse -l 1 -c ./tests/phpstan/phpstan.neon --memory-limit=520M system/src", - "phpstan-framework": "vendor/bin/phpstan analyse -l 3 -c ./tests/phpstan/phpstan.neon --memory-limit=480M system/src/Grav/Framework system/src/Grav/Events system/src/Grav/Installer", + "phpstan": "vendor/bin/phpstan analyse -l 2 -c ./tests/phpstan/phpstan.neon --memory-limit=720M system/src", + "phpstan-framework": "vendor/bin/phpstan analyse -l 5 -c ./tests/phpstan/phpstan.neon --memory-limit=480M system/src/Grav/Framework system/src/Grav/Events system/src/Grav/Installer", "phpstan-plugins": "vendor/bin/phpstan analyse -l 1 -c ./tests/phpstan/plugins.neon --memory-limit=400M user/plugins", "test": "vendor/bin/codecept run unit", "test-windows": "vendor\\bin\\codecept run unit" diff --git a/composer.lock b/composer.lock index 3b66c8a..d0dc8df 100644 --- a/composer.lock +++ b/composer.lock @@ -4,56 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "072f00e1bf64b4ef43f7125fe80b15a7", + "content-hash": "f0530b0fd3e574fef0852376653da5a0", "packages": [ - { - "name": "antoligy/dom-string-iterators", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/antoligy/dom-string-iterators.git", - "reference": "fae88f66e1970d68c5585fc42db44f1217bf74e6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/antoligy/dom-string-iterators/zipball/fae88f66e1970d68c5585fc42db44f1217bf74e6", - "reference": "fae88f66e1970d68c5585fc42db44f1217bf74e6", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "CC0-1.0" - ], - "authors": [ - { - "name": "Alex Wilson", - "email": "a@ax.gy" - }, - { - "name": "Kornel Lesinski", - "email": "pornel@pornel.net" - }, - { - "name": "Patrick Galbraith", - "email": "patrick.j.galbraith@gmail.com" - } - ], - "description": "Composer package for DOMWordsIterator and DOMLettersIterator", - "support": { - "issues": "https://github.com/antoligy/dom-string-iterators/issues", - "source": "https://github.com/antoligy/dom-string-iterators/tree/v1.0.1" - }, - "time": "2018-02-03T16:01:11+00:00" - }, { "name": "composer/ca-bundle", "version": "1.3.1", @@ -596,16 +548,16 @@ }, { "name": "filp/whoops", - "version": "2.14.4", + "version": "2.14.5", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "f056f1fe935d9ed86e698905a957334029899895" + "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/f056f1fe935d9ed86e698905a957334029899895", - "reference": "f056f1fe935d9ed86e698905a957334029899895", + "url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", + "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", "shasum": "" }, "require": { @@ -655,7 +607,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.14.4" + "source": "https://github.com/filp/whoops/tree/2.14.5" }, "funding": [ { @@ -663,7 +615,7 @@ "type": "github" } ], - "time": "2021-10-03T12:00:00+00:00" + "time": "2022-01-07T12:00:00+00:00" }, { "name": "getgrav/cache", @@ -812,12 +764,12 @@ } }, "autoload": { - "psr-4": { - "GuzzleHttp\\Psr7\\": "src/" - }, "files": [ "src/functions_include.php" - ] + ], + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -888,22 +840,21 @@ }, { "name": "itsgoingd/clockwork", - "version": "v5.1.1", + "version": "v5.1.5", "source": { "type": "git", "url": "https://github.com/itsgoingd/clockwork.git", - "reference": "2daf30fa6dfc5a1ccfdb2142df59243a72c473d8" + "reference": "6a7b3942224fa53cf3704d9adba636e1f3dfeb9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/2daf30fa6dfc5a1ccfdb2142df59243a72c473d8", - "reference": "2daf30fa6dfc5a1ccfdb2142df59243a72c473d8", + "url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/6a7b3942224fa53cf3704d9adba636e1f3dfeb9a", + "reference": "6a7b3942224fa53cf3704d9adba636e1f3dfeb9a", "shasum": "" }, "require": { "ext-json": "*", - "php": ">=5.6", - "psr/log": "1.* || ^2.0" + "php": ">=5.6" }, "type": "library", "extra": { @@ -945,7 +896,7 @@ ], "support": { "issues": "https://github.com/itsgoingd/clockwork/issues", - "source": "https://github.com/itsgoingd/clockwork/tree/v5.1.1" + "source": "https://github.com/itsgoingd/clockwork/tree/v5.1.5" }, "funding": [ { @@ -953,20 +904,20 @@ "type": "github" } ], - "time": "2021-11-01T17:38:35+00:00" + "time": "2022-02-13T22:57:42+00:00" }, { "name": "league/climate", - "version": "3.7.0", + "version": "3.8.1", "source": { "type": "git", "url": "https://github.com/thephpleague/climate.git", - "reference": "5c717c3032c5118be7ad2395dbe0813d9894e8c7" + "reference": "22243322c6f049240e0fa6ad6c3873343b6f6055" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/climate/zipball/5c717c3032c5118be7ad2395dbe0813d9894e8c7", - "reference": "5c717c3032c5118be7ad2395dbe0813d9894e8c7", + "url": "https://api.github.com/repos/thephpleague/climate/zipball/22243322c6f049240e0fa6ad6c3873343b6f6055", + "reference": "22243322c6f049240e0fa6ad6c3873343b6f6055", "shasum": "" }, "require": { @@ -1016,9 +967,9 @@ ], "support": { "issues": "https://github.com/thephpleague/climate/issues", - "source": "https://github.com/thephpleague/climate/tree/3.7.0" + "source": "https://github.com/thephpleague/climate/tree/3.8.1" }, - "time": "2021-01-10T20:18:52+00:00" + "time": "2022-01-23T14:38:49+00:00" }, { "name": "matthiasmullie/minify", @@ -1153,25 +1104,26 @@ }, { "name": "maximebf/debugbar", - "version": "v1.17.3", + "version": "v1.18.0", "source": { "type": "git", "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "e8ac3499af0ea5b440908e06cc0abe5898008b3c" + "reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/e8ac3499af0ea5b440908e06cc0abe5898008b3c", - "reference": "e8ac3499af0ea5b440908e06cc0abe5898008b3c", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6", + "reference": "0d44b75f3b5d6d41ae83b79c7a4bceae7fbc78b6", "shasum": "" }, "require": { "php": "^7.1|^8", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^2.6|^3|^4|^5" + "symfony/var-dumper": "^2.6|^3|^4|^5|^6" }, "require-dev": { - "phpunit/phpunit": "^7.5.20 || ^9.4.2" + "phpunit/phpunit": "^7.5.20 || ^9.4.2", + "twig/twig": "^1.38|^2.7|^3.0" }, "suggest": { "kriswallsmith/assetic": "The best way to manage assets", @@ -1212,9 +1164,9 @@ ], "support": { "issues": "https://github.com/maximebf/php-debugbar/issues", - "source": "https://github.com/maximebf/php-debugbar/tree/v1.17.3" + "source": "https://github.com/maximebf/php-debugbar/tree/v1.18.0" }, - "time": "2021-10-19T12:33:27+00:00" + "time": "2021-12-27T18:49:48+00:00" }, { "name": "miljar/php-exif", @@ -1363,17 +1315,64 @@ "time": "2021-05-28T08:32:12+00:00" }, { - "name": "nyholm/psr7", - "version": "1.4.1", + "name": "multiavatar/multiavatar-php", + "version": "v1.0.5", "source": { "type": "git", - "url": "https://github.com/Nyholm/psr7.git", - "reference": "2212385b47153ea71b1c1b1374f8cb5e4f7892ec" + "url": "https://github.com/multiavatar/multiavatar-php.git", + "reference": "13a62a656b1c2ca1c62dee57b4c1d8a3b04e6574" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Nyholm/psr7/zipball/2212385b47153ea71b1c1b1374f8cb5e4f7892ec", - "reference": "2212385b47153ea71b1c1b1374f8cb5e4f7892ec", + "url": "https://api.github.com/repos/multiavatar/multiavatar-php/zipball/13a62a656b1c2ca1c62dee57b4c1d8a3b04e6574", + "reference": "13a62a656b1c2ca1c62dee57b4c1d8a3b04e6574", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "Multiavatar.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "proprietary" + ], + "authors": [ + { + "name": "Gie Katon", + "homepage": "https://giekaton.com" + } + ], + "description": "Multicultural Avatar Generator", + "homepage": "https://multiavatar.com", + "keywords": [ + "avatar", + "creator", + "generator", + "image", + "maker", + "picture", + "profile" + ], + "support": { + "issues": "https://github.com/multiavatar/multiavatar-php/issues", + "source": "https://github.com/multiavatar/multiavatar-php/tree/v1.0.5" + }, + "time": "2021-03-02T07:33:46+00:00" + }, + { + "name": "nyholm/psr7", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "1461e07a0f2a975a52082ca3b769ca912b816226" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/1461e07a0f2a975a52082ca3b769ca912b816226", + "reference": "1461e07a0f2a975a52082ca3b769ca912b816226", "shasum": "" }, "require": { @@ -1425,7 +1424,7 @@ ], "support": { "issues": "https://github.com/Nyholm/psr7/issues", - "source": "https://github.com/Nyholm/psr7/tree/1.4.1" + "source": "https://github.com/Nyholm/psr7/tree/1.5.0" }, "funding": [ { @@ -1437,7 +1436,7 @@ "type": "github" } ], - "time": "2021-07-02T08:32:20+00:00" + "time": "2022-02-02T18:37:57+00:00" }, { "name": "nyholm/psr7-server", @@ -1561,29 +1560,29 @@ }, { "name": "pimple/pimple", - "version": "v3.3.1", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/silexphp/Pimple.git", - "reference": "21e45061c3429b1e06233475cc0e1f6fc774d5b0" + "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/21e45061c3429b1e06233475cc0e1f6fc774d5b0", - "reference": "21e45061c3429b1e06233475cc0e1f6fc774d5b0", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a94b3a4db7fb774b3d78dad2315ddc07629e1bed", + "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.0" + "psr/container": "^1.1 || ^2.0" }, "require-dev": { - "symfony/phpunit-bridge": "^5.0" + "symfony/phpunit-bridge": "^5.4@dev" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3.x-dev" + "dev-master": "3.4.x-dev" } }, "autoload": { @@ -1608,9 +1607,9 @@ "dependency injection" ], "support": { - "source": "https://github.com/silexphp/Pimple/tree/v3.3.1" + "source": "https://github.com/silexphp/Pimple/tree/v3.5.0" }, - "time": "2020-11-24T20:35:42+00:00" + "time": "2021-10-28T11:13:42+00:00" }, { "name": "psr/cache", @@ -1663,27 +1662,22 @@ }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -1696,7 +1690,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -1710,9 +1704,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/master" + "source": "https://github.com/php-fig/container/tree/1.1.1" }, - "time": "2017-02-14T16:28:37+00:00" + "time": "2021-03-05T17:36:06+00:00" }, { "name": "psr/http-factory", @@ -2128,43 +2122,41 @@ }, { "name": "rockettheme/toolbox", - "version": "1.5.10", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/rockettheme/toolbox.git", - "reference": "d9738de013fa12df77754a0f11dded220b246efb" + "reference": "fdf0195ced25b83525d3b084c3e81f05de96ac8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/d9738de013fa12df77754a0f11dded220b246efb", - "reference": "d9738de013fa12df77754a0f11dded220b246efb", + "url": "https://api.github.com/repos/rockettheme/toolbox/zipball/fdf0195ced25b83525d3b084c3e81f05de96ac8c", + "reference": "fdf0195ced25b83525d3b084c3e81f05de96ac8c", "shasum": "" }, "require": { "ext-json": "*", "php": ">=5.6.0", - "pimple/pimple": "~3.0", - "symfony/event-dispatcher": "^3.4|^4.0", - "symfony/yaml": "^3.4|^4.0" - }, - "require-dev": { - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-deprecation-rules": "^0.12", - "phpunit/phpunit": "~7.0" + "pimple/pimple": "^3.0", + "symfony/event-dispatcher": "^3.4|^4.0|^5.0", + "symfony/yaml": "^3.4|^4.0|^5.0" }, "type": "library", "autoload": { "psr-4": { - "RocketTheme\\Toolbox\\ArrayTraits\\": "ArrayTraits/src", - "RocketTheme\\Toolbox\\Blueprints\\": "Blueprints/src", - "RocketTheme\\Toolbox\\Compat\\": "Compat/src", "RocketTheme\\Toolbox\\DI\\": "DI/src", - "RocketTheme\\Toolbox\\Event\\": "Event/src", "RocketTheme\\Toolbox\\File\\": "File/src", - "RocketTheme\\Toolbox\\ResourceLocator\\": "ResourceLocator/src", + "RocketTheme\\Toolbox\\Event\\": "Event/src", + "RocketTheme\\Toolbox\\Compat\\": "Compat/src", "RocketTheme\\Toolbox\\Session\\": "Session/src", - "RocketTheme\\Toolbox\\StreamWrapper\\": "StreamWrapper/src" - } + "RocketTheme\\Toolbox\\Blueprints\\": "Blueprints/src", + "RocketTheme\\Toolbox\\ArrayTraits\\": "ArrayTraits/src", + "RocketTheme\\Toolbox\\StreamWrapper\\": "StreamWrapper/src", + "RocketTheme\\Toolbox\\ResourceLocator\\": "ResourceLocator/src" + }, + "exclude-from-classmap": [ + "**/tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2178,9 +2170,9 @@ ], "support": { "issues": "https://github.com/rockettheme/toolbox/issues", - "source": "https://github.com/rockettheme/toolbox/tree/1.5.10" + "source": "https://github.com/rockettheme/toolbox/tree/1.6.1" }, - "time": "2021-09-29T16:50:13+00:00" + "time": "2022-02-08T08:36:03+00:00" }, { "name": "seld/cli-prompt", @@ -2239,16 +2231,16 @@ }, { "name": "symfony/console", - "version": "v4.4.33", + "version": "v4.4.38", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "8dbd23ef7a8884051482183ddee8d9061b5feed0" + "reference": "5a50085bf5460f0c0d60a50b58388c1249826b8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8dbd23ef7a8884051482183ddee8d9061b5feed0", - "reference": "8dbd23ef7a8884051482183ddee8d9061b5feed0", + "url": "https://api.github.com/repos/symfony/console/zipball/5a50085bf5460f0c0d60a50b58388c1249826b8a", + "reference": "5a50085bf5460f0c0d60a50b58388c1249826b8a", "shasum": "" }, "require": { @@ -2309,7 +2301,7 @@ "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/console/tree/v4.4.33" + "source": "https://github.com/symfony/console/tree/v4.4.38" }, "funding": [ { @@ -2325,25 +2317,25 @@ "type": "tidelift" } ], - "time": "2021-10-25T16:36:08+00:00" + "time": "2022-01-30T21:23:57+00:00" }, { "name": "symfony/contracts", - "version": "v1.1.10", + "version": "v1.1.11", "source": { "type": "git", "url": "https://github.com/symfony/contracts.git", - "reference": "011c20407c4b99d454f44021d023fb39ce23b73d" + "reference": "cf2984f7a99bfae197f9c96f5a16a4041ff6ffb1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/contracts/zipball/011c20407c4b99d454f44021d023fb39ce23b73d", - "reference": "011c20407c4b99d454f44021d023fb39ce23b73d", + "url": "https://api.github.com/repos/symfony/contracts/zipball/cf2984f7a99bfae197f9c96f5a16a4041ff6ffb1", + "reference": "cf2984f7a99bfae197f9c96f5a16a4041ff6ffb1", "shasum": "" }, "require": { "php": ">=7.1.3", - "psr/cache": "^1.0", + "psr/cache": "^1.0|^2.0|^3.0", "psr/container": "^1.0" }, "replace": { @@ -2367,7 +2359,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-main": "1.1-dev" } }, "autoload": { @@ -2403,7 +2395,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/contracts/tree/v1.1.10" + "source": "https://github.com/symfony/contracts/tree/v1.1.11" }, "funding": [ { @@ -2419,20 +2411,20 @@ "type": "tidelift" } ], - "time": "2020-09-02T16:08:58+00:00" + "time": "2021-11-04T13:32:43+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.30", + "version": "v4.4.37", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "2fe81680070043c4c80e7cedceb797e34f377bac" + "reference": "3ccfcfb96ecce1217d7b0875a0736976bc6e63dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/2fe81680070043c4c80e7cedceb797e34f377bac", - "reference": "2fe81680070043c4c80e7cedceb797e34f377bac", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3ccfcfb96ecce1217d7b0875a0736976bc6e63dc", + "reference": "3ccfcfb96ecce1217d7b0875a0736976bc6e63dc", "shasum": "" }, "require": { @@ -2487,7 +2479,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.30" + "source": "https://github.com/symfony/event-dispatcher/tree/v4.4.37" }, "funding": [ { @@ -2503,20 +2495,20 @@ "type": "tidelift" } ], - "time": "2021-08-04T20:31:23+00:00" + "time": "2022-01-02T09:41:36+00:00" }, { "name": "symfony/http-client", - "version": "v4.4.33", + "version": "v4.4.39", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "9a5fdf129b522a06a46d13400500d326c41d8a73" + "reference": "40342406a975385c5b21e929df46e3fc0278853d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/9a5fdf129b522a06a46d13400500d326c41d8a73", - "reference": "9a5fdf129b522a06a46d13400500d326c41d8a73", + "url": "https://api.github.com/repos/symfony/http-client/zipball/40342406a975385c5b21e929df46e3fc0278853d", + "reference": "40342406a975385c5b21e929df46e3fc0278853d", "shasum": "" }, "require": { @@ -2568,7 +2560,7 @@ "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-client/tree/v4.4.33" + "source": "https://github.com/symfony/http-client/tree/v4.4.39" }, "funding": [ { @@ -2584,25 +2576,28 @@ "type": "tidelift" } ], - "time": "2021-10-18T16:39:13+00:00" + "time": "2022-02-28T13:17:32+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.23.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + "reference": "30885182c981ab175d4d034db0f6f469898070ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-ctype": "*" + }, "suggest": { "ext-ctype": "For best performance" }, @@ -2617,12 +2612,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2647,7 +2642,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" }, "funding": [ { @@ -2663,25 +2658,28 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2021-10-20T20:35:02+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.23.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "63b5bb7db83e5673936d6e3b8b3e022ff6474933" + "reference": "f1aed619e28cb077fc83fac8c4c0383578356e40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/63b5bb7db83e5673936d6e3b8b3e022ff6474933", - "reference": "63b5bb7db83e5673936d6e3b8b3e022ff6474933", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/f1aed619e28cb077fc83fac8c4c0383578356e40", + "reference": "f1aed619e28cb077fc83fac8c4c0383578356e40", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-iconv": "*" + }, "suggest": { "ext-iconv": "For best performance" }, @@ -2696,12 +2694,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Iconv\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Iconv\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2727,7 +2725,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.25.0" }, "funding": [ { @@ -2743,25 +2741,28 @@ "type": "tidelift" } ], - "time": "2021-05-27T09:27:20+00:00" + "time": "2022-01-04T09:04:05+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.23.1", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-mbstring": "*" + }, "suggest": { "ext-mbstring": "For best performance" }, @@ -2776,12 +2777,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2807,7 +2808,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" }, "funding": [ { @@ -2823,11 +2824,11 @@ "type": "tidelift" } ], - "time": "2021-05-27T12:26:48+00:00" + "time": "2021-11-30T18:21:41+00:00" }, { "name": "symfony/polyfill-php74", - "version": "v1.23.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php74.git", @@ -2853,12 +2854,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php74\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Php74\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2887,7 +2888,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php74/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-php74/tree/v1.25.0" }, "funding": [ { @@ -2907,16 +2908,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.23.1", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" + "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", "shasum": "" }, "require": { @@ -2933,12 +2934,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -2970,7 +2971,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" }, "funding": [ { @@ -2986,20 +2987,20 @@ "type": "tidelift" } ], - "time": "2021-07-28T13:41:28+00:00" + "time": "2022-03-04T08:16:47+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.23.0", + "version": "v1.25.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "e66119f3de95efc359483f810c4c3e6436279436" + "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/e66119f3de95efc359483f810c4c3e6436279436", - "reference": "e66119f3de95efc359483f810c4c3e6436279436", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", "shasum": "" }, "require": { @@ -3016,12 +3017,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -3049,7 +3050,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0" }, "funding": [ { @@ -3065,20 +3066,20 @@ "type": "tidelift" } ], - "time": "2021-05-21T13:25:03+00:00" + "time": "2021-09-13T13:58:11+00:00" }, { "name": "symfony/process", - "version": "v4.4.30", + "version": "v4.4.37", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "13d3161ef63a8ec21eeccaaf9a4d7f784a87a97d" + "reference": "b2d924e5a4cb284f293d5092b1dbf0d364cb8b67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/13d3161ef63a8ec21eeccaaf9a4d7f784a87a97d", - "reference": "13d3161ef63a8ec21eeccaaf9a4d7f784a87a97d", + "url": "https://api.github.com/repos/symfony/process/zipball/b2d924e5a4cb284f293d5092b1dbf0d364cb8b67", + "reference": "b2d924e5a4cb284f293d5092b1dbf0d364cb8b67", "shasum": "" }, "require": { @@ -3111,7 +3112,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v4.4.30" + "source": "https://github.com/symfony/process/tree/v4.4.37" }, "funding": [ { @@ -3127,20 +3128,20 @@ "type": "tidelift" } ], - "time": "2021-08-04T20:31:23+00:00" + "time": "2022-01-27T17:14:04+00:00" }, { "name": "symfony/var-dumper", - "version": "v4.4.33", + "version": "v4.4.39", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "50286e2b7189bfb4f419c0731e86632cddf7c5ee" + "reference": "35237c5e5dcb6593a46a860ba5b29c1d4683d80e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/50286e2b7189bfb4f419c0731e86632cddf7c5ee", - "reference": "50286e2b7189bfb4f419c0731e86632cddf7c5ee", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/35237c5e5dcb6593a46a860ba5b29c1d4683d80e", + "reference": "35237c5e5dcb6593a46a860ba5b29c1d4683d80e", "shasum": "" }, "require": { @@ -3200,7 +3201,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v4.4.33" + "source": "https://github.com/symfony/var-dumper/tree/v4.4.39" }, "funding": [ { @@ -3216,20 +3217,20 @@ "type": "tidelift" } ], - "time": "2021-10-25T20:24:58+00:00" + "time": "2022-02-25T10:38:15+00:00" }, { "name": "symfony/yaml", - "version": "v4.4.29", + "version": "v4.4.37", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "3abcc4db06d4e776825eaa3ed8ad924d5bc7432a" + "reference": "d7f637cc0f0cc14beb0984f2bb50da560b271311" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/3abcc4db06d4e776825eaa3ed8ad924d5bc7432a", - "reference": "3abcc4db06d4e776825eaa3ed8ad924d5bc7432a", + "url": "https://api.github.com/repos/symfony/yaml/zipball/d7f637cc0f0cc14beb0984f2bb50da560b271311", + "reference": "d7f637cc0f0cc14beb0984f2bb50da560b271311", "shasum": "" }, "require": { @@ -3271,7 +3272,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v4.4.29" + "source": "https://github.com/symfony/yaml/tree/v4.4.37" }, "funding": [ { @@ -3287,20 +3288,20 @@ "type": "tidelift" } ], - "time": "2021-07-27T16:19:30+00:00" + "time": "2022-01-24T20:11:01+00:00" }, { "name": "twig/twig", - "version": "v1.44.5", + "version": "v1.44.6", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "dd4353357c5a116322e92a00d16043a31881a81e" + "reference": "ae39480f010ef88adc7938503c9b02d3baf2f3b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/dd4353357c5a116322e92a00d16043a31881a81e", - "reference": "dd4353357c5a116322e92a00d16043a31881a81e", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/ae39480f010ef88adc7938503c9b02d3baf2f3b3", + "reference": "ae39480f010ef88adc7938503c9b02d3baf2f3b3", "shasum": "" }, "require": { @@ -3353,7 +3354,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v1.44.5" + "source": "https://github.com/twigphp/Twig/tree/v1.44.6" }, "funding": [ { @@ -3365,20 +3366,20 @@ "type": "tidelift" } ], - "time": "2021-09-17T08:35:19+00:00" + "time": "2021-11-25T13:31:46+00:00" }, { "name": "willdurand/negotiation", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/willdurand/Negotiation.git", - "reference": "04e14f38d4edfcc974114a07d2777d90c98f3d9c" + "reference": "68e9ea0553ef6e2ee8db5c1d98829f111e623ec2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/04e14f38d4edfcc974114a07d2777d90c98f3d9c", - "reference": "04e14f38d4edfcc974114a07d2777d90c98f3d9c", + "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/68e9ea0553ef6e2ee8db5c1d98829f111e623ec2", + "reference": "68e9ea0553ef6e2ee8db5c1d98829f111e623ec2", "shasum": "" }, "require": { @@ -3419,9 +3420,9 @@ ], "support": { "issues": "https://github.com/willdurand/Negotiation/issues", - "source": "https://github.com/willdurand/Negotiation/tree/3.0.0" + "source": "https://github.com/willdurand/Negotiation/tree/3.1.0" }, - "time": "2020-09-25T08:01:41+00:00" + "time": "2022-01-30T20:08:53+00:00" } ], "packages-dev": [ @@ -3490,23 +3491,23 @@ }, { "name": "codeception/codeception", - "version": "4.1.22", + "version": "4.1.30", "source": { "type": "git", "url": "https://github.com/Codeception/Codeception.git", - "reference": "9777ec3690ceedc4bce2ed13af7af4ca4ee3088f" + "reference": "a035d77d070fa57fad438e07a65447aeca248c45" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/Codeception/zipball/9777ec3690ceedc4bce2ed13af7af4ca4ee3088f", - "reference": "9777ec3690ceedc4bce2ed13af7af4ca4ee3088f", + "url": "https://api.github.com/repos/Codeception/Codeception/zipball/a035d77d070fa57fad438e07a65447aeca248c45", + "reference": "a035d77d070fa57fad438e07a65447aeca248c45", "shasum": "" }, "require": { "behat/gherkin": "^4.4.0", - "codeception/lib-asserts": "^1.0", + "codeception/lib-asserts": "^1.0 | 2.0.*@dev", "codeception/phpunit-wrapper": ">6.0.15 <6.1.0 | ^6.6.1 | ^7.7.1 | ^8.1.1 | ^9.0", - "codeception/stub": "^2.0 | ^3.0", + "codeception/stub": "^2.0 | ^3.0 | ^4.0", "ext-curl": "*", "ext-json": "*", "ext-mbstring": "*", @@ -3519,11 +3520,11 @@ "symfony/yaml": ">=2.7 <6.0" }, "require-dev": { - "codeception/module-asserts": "1.*@dev", - "codeception/module-cli": "1.*@dev", - "codeception/module-db": "1.*@dev", - "codeception/module-filesystem": "1.*@dev", - "codeception/module-phpbrowser": "1.*@dev", + "codeception/module-asserts": "^1.0 | 2.0.*@dev", + "codeception/module-cli": "^1.0 | 2.0.*@dev", + "codeception/module-db": "^1.0 | 2.0.*@dev", + "codeception/module-filesystem": "^1.0 | 2.0.*@dev", + "codeception/module-phpbrowser": "^1.0 | 2.0.*@dev", "codeception/specify": "~0.3", "codeception/util-universalframework": "*@dev", "monolog/monolog": "~1.8", @@ -3546,6 +3547,9 @@ "branch-alias": [] }, "autoload": { + "files": [ + "functions.php" + ], "psr-4": { "Codeception\\": "src/Codeception", "Codeception\\Extension\\": "ext" @@ -3573,7 +3577,7 @@ ], "support": { "issues": "https://github.com/Codeception/Codeception/issues", - "source": "https://github.com/Codeception/Codeception/tree/4.1.22" + "source": "https://github.com/Codeception/Codeception/tree/4.1.30" }, "funding": [ { @@ -3581,7 +3585,7 @@ "type": "open_collective" } ], - "time": "2021-08-06T17:15:34+00:00" + "time": "2022-03-05T18:12:30+00:00" }, { "name": "codeception/lib-asserts", @@ -3816,16 +3820,16 @@ }, { "name": "codeception/phpunit-wrapper", - "version": "9.0.6", + "version": "9.0.7", "source": { "type": "git", "url": "https://github.com/Codeception/phpunit-wrapper.git", - "reference": "b0c06abb3181eedca690170f7ed0fd26a70bfacc" + "reference": "7d6b1a5ea4ed28d010e5d36b993db813eb49710b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/b0c06abb3181eedca690170f7ed0fd26a70bfacc", - "reference": "b0c06abb3181eedca690170f7ed0fd26a70bfacc", + "url": "https://api.github.com/repos/Codeception/phpunit-wrapper/zipball/7d6b1a5ea4ed28d010e5d36b993db813eb49710b", + "reference": "7d6b1a5ea4ed28d010e5d36b993db813eb49710b", "shasum": "" }, "require": { @@ -3859,9 +3863,9 @@ "description": "PHPUnit classes used by Codeception", "support": { "issues": "https://github.com/Codeception/phpunit-wrapper/issues", - "source": "https://github.com/Codeception/phpunit-wrapper/tree/9.0.6" + "source": "https://github.com/Codeception/phpunit-wrapper/tree/9.0.7" }, - "time": "2020-12-28T13:59:47+00:00" + "time": "2022-01-26T14:43:10+00:00" }, { "name": "codeception/stub", @@ -3899,29 +3903,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", + "doctrine/coding-standard": "^9", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", "autoload": { @@ -3948,7 +3953,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" }, "funding": [ { @@ -3964,7 +3969,7 @@ "type": "tidelift" } ], - "time": "2020-11-10T18:47:58+00:00" + "time": "2022-03-03T08:28:38+00:00" }, { "name": "getgrav/markdowndocs", @@ -4020,16 +4025,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "7.4.0", + "version": "7.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "868b3571a039f0ebc11ac8f344f4080babe2cb94" + "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/868b3571a039f0ebc11ac8f344f4080babe2cb94", - "reference": "868b3571a039f0ebc11ac8f344f4080babe2cb94", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ee0a041b1760e6a53d2a39c8c34115adc2af2c79", + "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79", "shasum": "" }, "require": { @@ -4038,7 +4043,7 @@ "guzzlehttp/psr7": "^1.8.3 || ^2.1", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2" + "symfony/deprecation-contracts": "^2.2 || ^3.0" }, "provide": { "psr/http-client-implementation": "1.0" @@ -4062,12 +4067,12 @@ } }, "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, "files": [ "src/functions_include.php" - ] + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4124,7 +4129,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.4.0" + "source": "https://github.com/guzzle/guzzle/tree/7.4.1" }, "funding": [ { @@ -4140,7 +4145,7 @@ "type": "tidelift" } ], - "time": "2021-10-18T09:52:00+00:00" + "time": "2021-12-06T18:43:05+00:00" }, { "name": "guzzlehttp/promises", @@ -4169,12 +4174,12 @@ } }, "autoload": { - "psr-4": { - "GuzzleHttp\\Promise\\": "src/" - }, "files": [ "src/functions_include.php" - ] + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4228,37 +4233,38 @@ }, { "name": "myclabs/deep-copy", - "version": "1.10.2", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, "files": [ "src/DeepCopy/deep_copy.php" - ] + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4274,7 +4280,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" }, "funding": [ { @@ -4282,20 +4288,20 @@ "type": "tidelift" } ], - "time": "2020-11-13T09:40:50+00:00" + "time": "2022-03-03T13:19:32+00:00" }, { "name": "nikic/php-parser", - "version": "v4.13.1", + "version": "v4.13.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", "shasum": "" }, "require": { @@ -4336,9 +4342,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" }, - "time": "2021-11-03T20:52:16+00:00" + "time": "2021-11-30T19:35:32+00:00" }, { "name": "phar-io/manifest", @@ -4402,16 +4408,16 @@ }, { "name": "phar-io/version", - "version": "3.1.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "bae7c545bef187884426f042434e561ab1ddb182" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", - "reference": "bae7c545bef187884426f042434e561ab1ddb182", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { @@ -4447,9 +4453,9 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.1.0" + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "time": "2021-02-23T14:00:09+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -4563,16 +4569,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.5.1", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", "shasum": "" }, "require": { @@ -4607,22 +4613,22 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" }, - "time": "2021-10-02T14:08:47+00:00" + "time": "2022-01-04T19:58:01+00:00" }, { "name": "phpspec/prophecy", - "version": "1.14.0", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", "shasum": "" }, "require": { @@ -4674,22 +4680,22 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.14.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" }, - "time": "2021-09-10T09:02:12+00:00" + "time": "2021-12-08T12:19:24+00:00" }, { "name": "phpstan/phpstan", - "version": "1.1.2", + "version": "1.4.8", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "bcea0ae85868a89d5789c75f012c93129f842934" + "reference": "2a6d6704b17c4db6190cc3104056c0aad740cb15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/bcea0ae85868a89d5789c75f012c93129f842934", - "reference": "bcea0ae85868a89d5789c75f012c93129f842934", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/2a6d6704b17c4db6190cc3104056c0aad740cb15", + "reference": "2a6d6704b17c4db6190cc3104056c0aad740cb15", "shasum": "" }, "require": { @@ -4705,7 +4711,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -4720,7 +4726,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.1.2" + "source": "https://github.com/phpstan/phpstan/tree/1.4.8" }, "funding": [ { @@ -4740,7 +4746,7 @@ "type": "tidelift" } ], - "time": "2021-11-09T12:41:09+00:00" + "time": "2022-03-04T13:03:56+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -4794,16 +4800,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.8", + "version": "9.2.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "cf04e88a2e3c56fc1a65488afd493325b4c1bc3e" + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/cf04e88a2e3c56fc1a65488afd493325b4c1bc3e", - "reference": "cf04e88a2e3c56fc1a65488afd493325b4c1bc3e", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", "shasum": "" }, "require": { @@ -4859,7 +4865,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.8" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" }, "funding": [ { @@ -4867,20 +4873,20 @@ "type": "github" } ], - "time": "2021-10-30T08:01:38+00:00" + "time": "2022-03-07T09:28:20+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.5", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { @@ -4919,7 +4925,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" }, "funding": [ { @@ -4927,7 +4933,7 @@ "type": "github" } ], - "time": "2020-09-28T05:57:25+00:00" + "time": "2021-12-02T12:48:52+00:00" }, { "name": "phpunit/php-invoker", @@ -5112,16 +5118,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.10", + "version": "9.5.18", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" + "reference": "1b5856028273bfd855e60a887278857d872ec67a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1b5856028273bfd855e60a887278857d872ec67a", + "reference": "1b5856028273bfd855e60a887278857d872ec67a", "shasum": "" }, "require": { @@ -5137,7 +5143,7 @@ "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.7", + "phpunit/php-code-coverage": "^9.2.13", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -5172,11 +5178,11 @@ } }, "autoload": { - "classmap": [ - "src/" - ], "files": [ "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -5199,11 +5205,11 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.18" }, "funding": [ { - "url": "https://phpunit.de/donate.html", + "url": "https://phpunit.de/sponsors.html", "type": "custom" }, { @@ -5211,7 +5217,7 @@ "type": "github" } ], - "time": "2021-09-25T07:38:51+00:00" + "time": "2022-03-08T06:52:28+00:00" }, { "name": "psr/http-client", @@ -5771,16 +5777,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.3", + "version": "5.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", "shasum": "" }, "require": { @@ -5823,7 +5829,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" }, "funding": [ { @@ -5831,7 +5837,7 @@ "type": "github" } ], - "time": "2021-06-11T13:31:12+00:00" + "time": "2022-02-14T08:28:10+00:00" }, { "name": "sebastian/lines-of-code", @@ -6231,28 +6237,28 @@ }, { "name": "symfony/browser-kit", - "version": "v5.3.4", + "version": "v5.4.3", "source": { "type": "git", "url": "https://github.com/symfony/browser-kit.git", - "reference": "c1e3f64fcc631c96e2c5843b666db66679ced11c" + "reference": "18e73179c6a33d520de1b644941eba108dd811ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/browser-kit/zipball/c1e3f64fcc631c96e2c5843b666db66679ced11c", - "reference": "c1e3f64fcc631c96e2c5843b666db66679ced11c", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/18e73179c6a33d520de1b644941eba108dd811ad", + "reference": "18e73179c6a33d520de1b644941eba108dd811ad", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/dom-crawler": "^4.4|^5.0", + "symfony/dom-crawler": "^4.4|^5.0|^6.0", "symfony/polyfill-php80": "^1.16" }, "require-dev": { - "symfony/css-selector": "^4.4|^5.0", - "symfony/http-client": "^4.4|^5.0", - "symfony/mime": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0" + "symfony/css-selector": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", + "symfony/mime": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0" }, "suggest": { "symfony/process": "" @@ -6283,7 +6289,7 @@ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/browser-kit/tree/v5.3.4" + "source": "https://github.com/symfony/browser-kit/tree/v5.4.3" }, "funding": [ { @@ -6299,20 +6305,20 @@ "type": "tidelift" } ], - "time": "2021-07-21T12:40:44+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/css-selector", - "version": "v5.3.4", + "version": "v5.4.3", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "7fb120adc7f600a59027775b224c13a33530dd90" + "reference": "b0a190285cd95cb019237851205b8140ef6e368e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/7fb120adc7f600a59027775b224c13a33530dd90", - "reference": "7fb120adc7f600a59027775b224c13a33530dd90", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/b0a190285cd95cb019237851205b8140ef6e368e", + "reference": "b0a190285cd95cb019237851205b8140ef6e368e", "shasum": "" }, "require": { @@ -6349,7 +6355,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.3.4" + "source": "https://github.com/symfony/css-selector/tree/v5.4.3" }, "funding": [ { @@ -6365,20 +6371,20 @@ "type": "tidelift" } ], - "time": "2021-07-21T12:38:00+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", "shasum": "" }, "require": { @@ -6387,7 +6393,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -6416,7 +6422,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" }, "funding": [ { @@ -6432,25 +6438,25 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2021-07-12T14:48:14+00:00" }, { "name": "symfony/dom-crawler", - "version": "v5.3.7", + "version": "v5.4.6", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "c7eef3a60ccfdd8eafe07f81652e769ac9c7146c" + "reference": "c0bda97480d96337bd3866026159a8b358665457" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/c7eef3a60ccfdd8eafe07f81652e769ac9c7146c", - "reference": "c7eef3a60ccfdd8eafe07f81652e769ac9c7146c", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/c0bda97480d96337bd3866026159a8b358665457", + "reference": "c0bda97480d96337bd3866026159a8b358665457", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "^1.16" @@ -6460,7 +6466,7 @@ }, "require-dev": { "masterminds/html5": "^2.6", - "symfony/css-selector": "^4.4|^5.0" + "symfony/css-selector": "^4.4|^5.0|^6.0" }, "suggest": { "symfony/css-selector": "" @@ -6491,7 +6497,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v5.3.7" + "source": "https://github.com/symfony/dom-crawler/tree/v5.4.6" }, "funding": [ { @@ -6507,24 +6513,25 @@ "type": "tidelift" } ], - "time": "2021-08-29T19:32:13+00:00" + "time": "2022-03-02T12:42:23+00:00" }, { "name": "symfony/finder", - "version": "v5.3.7", + "version": "v5.4.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93" + "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a10000ada1e600d109a6c7632e9ac42e8bf2fb93", - "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93", + "url": "https://api.github.com/repos/symfony/finder/zipball/231313534dded84c7ecaa79d14bc5da4ccb69b7d", + "reference": "231313534dded84c7ecaa79d14bc5da4ccb69b7d", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-php80": "^1.16" }, "type": "library", @@ -6553,7 +6560,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.3.7" + "source": "https://github.com/symfony/finder/tree/v5.4.3" }, "funding": [ { @@ -6569,7 +6576,7 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" + "time": "2022-01-26T16:34:36+00:00" }, { "name": "theseer/tokenizer", @@ -6698,5 +6705,5 @@ "platform-overrides": { "php": "7.3.6" }, - "plugin-api-version": "2.0.0" + "plugin-api-version": "2.2.0" } diff --git a/index.php b/index.php index 091e9a8..b6b86e1 100644 --- a/index.php +++ b/index.php @@ -3,7 +3,7 @@ /** * @package Grav.Core * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -12,10 +12,6 @@ namespace Grav; \define('GRAV_REQUEST_TIME', microtime(true)); \define('GRAV_PHP_MIN', '7.3.6'); -if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) { - die(sprintf('You are running PHP %s, but Grav needs at least PHP %s to run.', $ver, $req)); -} - if (PHP_SAPI === 'cli-server') { $symfony_server = stripos(getenv('_'), 'symfony') !== false || stripos($_SERVER['SERVER_SOFTWARE'] ?? '', 'symfony') !== false || stripos($_ENV['SERVER_SOFTWARE'] ?? '', 'symfony') !== false; @@ -24,16 +20,6 @@ if (PHP_SAPI === 'cli-server') { } } -// Set timezone to default, falls back to system if php.ini not set -date_default_timezone_set(@date_default_timezone_get()); - -// Set internal encoding. -if (!\extension_loaded('mbstring')) { - die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); -} -@ini_set('default_charset', 'UTF-8'); -mb_internal_encoding('UTF-8'); - // Ensure vendor libraries exist $autoload = __DIR__ . '/vendor/autoload.php'; if (!is_file($autoload)) { @@ -43,23 +29,23 @@ if (!is_file($autoload)) { // Register the auto-loader. $loader = require $autoload; +// Set timezone to default, falls back to system if php.ini not set +date_default_timezone_set(@date_default_timezone_get()); + +// Set internal encoding. +@ini_set('default_charset', 'UTF-8'); +mb_internal_encoding('UTF-8'); + use Grav\Common\Grav; use RocketTheme\Toolbox\Event\Event; // Get the Grav instance -$grav = Grav::instance( - array( - 'loader' => $loader - ) -); +$grav = Grav::instance(array('loader' => $loader)); // Process the page try { $grav->process(); -} catch (\Error $e) { - $grav->fireEvent('onFatalException', new Event(array('exception' => $e))); - throw $e; -} catch (\Exception $e) { +} catch (\Error|\Exception $e) { $grav->fireEvent('onFatalException', new Event(array('exception' => $e))); throw $e; } diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 1aeaf2b..787fcd5 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -888,9 +888,45 @@ form: title: PLUGIN_ADMIN.ASSETS fields: - assets_section: + general_config_section: type: section - title: PLUGIN_ADMIN.ASSETS + title: PLUGIN_ADMIN.GENERAL_CONFIG + underline: true + + assets.enable_asset_timestamp: + type: toggle + label: PLUGIN_ADMIN.ENABLED_TIMESTAMPS_ON_ASSETS + help: PLUGIN_ADMIN.ENABLED_TIMESTAMPS_ON_ASSETS_HELP + highlight: 0 + options: + 1: PLUGIN_ADMIN.YES + 0: PLUGIN_ADMIN.NO + validate: + type: bool + + assets.enable_asset_sri: + type: toggle + label: PLUGIN_ADMIN.ENABLED_SRI_ON_ASSETS + help: PLUGIN_ADMIN.ENABLED_SRI_ON_ASSETS_HELP + highlight: 0 + options: + 1: PLUGIN_ADMIN.YES + 0: PLUGIN_ADMIN.NO + validate: + type: bool + + assets.collections: + type: multilevel + label: PLUGIN_ADMIN.COLLECTIONS + placeholder_key: collection_name + placeholder_value: collection_path + validate: + type: array + + + css_assets_section: + type: section + title: PLUGIN_ADMIN.CSS_ASSETS underline: true assets.css_pipeline: @@ -959,6 +995,11 @@ form: validate: type: bool + js_assets_section: + type: section + title: PLUGIN_ADMIN.JS_ASSETS + underline: true + assets.js_pipeline: type: toggle label: PLUGIN_ADMIN.JAVASCRIPT_PIPELINE @@ -1003,10 +1044,15 @@ form: validate: type: bool - assets.enable_asset_timestamp: + js_module_assets_section: + type: section + title: PLUGIN_ADMIN.JS_MODULE_ASSETS + underline: true + + assets.js_module_pipeline: type: toggle - label: PLUGIN_ADMIN.ENABLED_TIMESTAMPS_ON_ASSETS - help: PLUGIN_ADMIN.ENABLED_TIMESTAMPS_ON_ASSETS_HELP + label: PLUGIN_ADMIN.JAVASCRIPT_MODULE_PIPELINE + help: PLUGIN_ADMIN.JAVASCRIPT_MODULE_PIPELINE_HELP highlight: 0 options: 1: PLUGIN_ADMIN.YES @@ -1014,24 +1060,29 @@ form: validate: type: bool - assets.enable_asset_sri: + assets.js_module_pipeline_include_externals: type: toggle - label: PLUGIN_ADMIN.ENABLED_SRI_ON_ASSETS - help: PLUGIN_ADMIN.ENABLED_SRI_ON_ASSETS_HELP - highlight: 0 + label: PLUGIN_ADMIN.JAVASCRIPT_MODULE_PIPELINE_INCLUDE_EXTERNALS + help: PLUGIN_ADMIN.JAVASCRIPT_MODULE_PIPELINE_INCLUDE_EXTERNALS_HELP + highlight: 1 options: 1: PLUGIN_ADMIN.YES 0: PLUGIN_ADMIN.NO validate: type: bool - assets.collections: - type: multilevel - label: PLUGIN_ADMIN.COLLECTIONS - placeholder_key: collection_name - placeholder_value: collection_path + assets.js_module_pipeline_before_excludes: + type: toggle + label: PLUGIN_ADMIN.JAVASCRIPT_MODULE_PIPELINE_BEFORE_EXCLUDES + help: PLUGIN_ADMIN.JAVASCRIPT_MODULE_PIPELINE_BEFORE_EXCLUDES_HELP + highlight: 1 + options: + 1: PLUGIN_ADMIN.YES + 0: PLUGIN_ADMIN.NO validate: - type: array + type: bool + + errors: type: tab @@ -1394,6 +1445,18 @@ form: validate: type: bool + session.secure_https: + type: toggle + label: PLUGIN_ADMIN.SESSION_SECURE_HTTPS + help: PLUGIN_ADMIN.SESSION_SECURE_HTTPS_HELP + highlight: 1 + options: + 1: PLUGIN_ADMIN.YES + 0: PLUGIN_ADMIN.NO + default: true + validate: + type: bool + session.httponly: type: toggle label: PLUGIN_ADMIN.SESSION_HTTPONLY @@ -1723,35 +1786,15 @@ form: validate: type: bool - experimental: + + accounts: type: tab - title: PLUGIN_ADMIN.EXPERIMENTAL + title: PLUGIN_ADMIN.ACCOUNTS fields: - experimental_section: - type: section - title: PLUGIN_ADMIN.EXPERIMENTAL - underline: true - -# flex_pages: -# type: section -# title: Flex Pages -# -# pages.type: -# type: select -# label: PLUGIN_ADMIN.PAGES_TYPE -# highlight: regular -# help: PLUGIN_ADMIN.PAGES_TYPE_HELP -# options: -# regular: PLUGIN_ADMIN.REGULAR -# flex: PLUGIN_ADMIN.FLEX - - pages.type: - type: hidden - flex_accounts: type: section - title: Flex Accounts + title: User Accounts accounts.type: type: select @@ -1770,3 +1813,41 @@ form: options: file: PLUGIN_ADMIN.FILE folder: PLUGIN_ADMIN.FOLDER + + accounts.avatar: + type: select + label: PLUGIN_ADMIN.AVATAR + default: gravatar + help: PLUGIN_ADMIN.AVATAR_HELP + options: + multiavatar: Multiavatar [local] + gravatar: Gravatar [external] + +# experimental: +# type: tab +# title: PLUGIN_ADMIN.EXPERIMENTAL +# +# fields: +# experimental_section: +# type: section +# title: PLUGIN_ADMIN.EXPERIMENTAL +# underline: true +# +# flex_pages: +# type: section +# title: Flex Pages +# +# pages.type: +# type: select +# label: PLUGIN_ADMIN.PAGES_TYPE +# highlight: regular +# help: PLUGIN_ADMIN.PAGES_TYPE_HELP +# options: +# regular: PLUGIN_ADMIN.REGULAR +# flex: PLUGIN_ADMIN.FLEX +# +# pages.type: +# type: hidden + + + diff --git a/system/blueprints/flex/pages.yaml b/system/blueprints/flex/pages.yaml index 5c6ed8e..89dab6a 100644 --- a/system/blueprints/flex/pages.yaml +++ b/system/blueprints/flex/pages.yaml @@ -104,7 +104,7 @@ config: edit: title: - template: "{% if object.root %}Root ( <root> ){% else %}{{ (form.value('header.title') ?? form.value('folder'))|e }} ( {{ (object.getRoute().toString(false) ?: '/')|e }} ){% endif %}" + template: "{% if object.root %}Root ( <root> ){% else %}{{ (form.value('header.title') ?? form.value('folder'))|e }} ( {{ (object.getRoute().toString(false) ?: '/')|e }} ){% endif %}" # TODO: not used yet buttons: diff --git a/system/blueprints/flex/user-accounts.yaml b/system/blueprints/flex/user-accounts.yaml index 384bf97..8d336f9 100644 --- a/system/blueprints/flex/user-accounts.yaml +++ b/system/blueprints/flex/user-accounts.yaml @@ -122,6 +122,8 @@ config: fields: - key - email + - username + - fullname blueprints: configure: diff --git a/system/blueprints/flex/user-groups.yaml b/system/blueprints/flex/user-groups.yaml index 05ba87b..a5d348b 100644 --- a/system/blueprints/flex/user-groups.yaml +++ b/system/blueprints/flex/user-groups.yaml @@ -113,6 +113,7 @@ config: fields: - key - groupname + - readableName - description blueprints: diff --git a/system/blueprints/pages/default.yaml b/system/blueprints/pages/default.yaml index f3ef29f..a573a83 100644 --- a/system/blueprints/pages/default.yaml +++ b/system/blueprints/pages/default.yaml @@ -320,6 +320,18 @@ form: fields: + header.redirect_default_route: + type: toggle + toggleable: true + label: PLUGIN_ADMIN.REDIRECT_DEFAULT_ROUTE + help: PLUGIN_ADMIN.REDIRECT_DEFAULT_ROUTE_HELP + config-highlight@: system.pages.redirect_default_route + options: + 1: PLUGIN_ADMIN.YES + 0: PLUGIN_ADMIN.NO + validate: + type: bool + header.routes.default: type: text toggleable: true diff --git a/system/blueprints/pages/external.yaml b/system/blueprints/pages/external.yaml index df1d7b0..d3bb57a 100644 --- a/system/blueprints/pages/external.yaml +++ b/system/blueprints/pages/external.yaml @@ -1,7 +1,7 @@ -title: PLUGIN_ADMIN:EXTERNAL +title: PLUGIN_ADMIN.EXTERNAL extends@: - type: default - context: blueprints://pages + type: default + context: blueprints://pages form: validation: loose @@ -29,16 +29,16 @@ form: unset@: true header.external_url: - type: text - label: PLUGIN_ADMIN.EXTERNAL_URL - placeholder: https://getgrav.org - validate: - required: true + type: text + label: PLUGIN_ADMIN.EXTERNAL_URL + placeholder: https://getgrav.org + validate: + required: true + options: fields: publishing: - fields: header.date: diff --git a/system/blueprints/pages/partials/security.yaml b/system/blueprints/pages/partials/security.yaml index d7619b9..26d8c7d 100644 --- a/system/blueprints/pages/partials/security.yaml +++ b/system/blueprints/pages/partials/security.yaml @@ -51,17 +51,13 @@ form: type: bool header.permissions.authors: - type: list + type: array toggleable: true + value_only: true + placeholder_value: PLUGIN_ADMIN.USERNAME label: PLUGIN_ADMIN.PAGE_AUTHORS help: PLUGIN_ADMIN.PAGE_AUTHORS_HELP - fields: - value: - type: text - placeholder: PLUGIN_ADMIN.USERNAME - style: vertical - header.permissions.groups: ignore@: true type: acl_picker diff --git a/system/blueprints/user/account.yaml b/system/blueprints/user/account.yaml index 127a99e..ef5f25b 100644 --- a/system/blueprints/user/account.yaml +++ b/system/blueprints/user/account.yaml @@ -11,10 +11,21 @@ form: avatar: type: file size: large - destination: 'user://accounts/avatars' + destination: 'account://avatars' multiple: false random_name: true + multiavatar_only: + type: conditional + condition: config.system.accounts.avatar == 'multiavatar' + fields: + avatar_hash: + type: text + label: '' + placeholder: 'e.g. dceaadcfda491f4e45' + description: PLUGIN_ADMIN.AVATAR_HASH + size: large + content: type: section title: PLUGIN_ADMIN.ACCOUNT @@ -107,6 +118,12 @@ form: label: PLUGIN_ADMIN.2FA_SECRET sublabel: PLUGIN_ADMIN.2FA_SECRET_HELP + yubikey_id: + type: text + label: PLUGIN_ADMIN.YUBIKEY_ID + description: PLUGIN_ADMIN.YUBIKEY_HELP + size: small + maxlength: 12 diff --git a/system/config/media.yaml b/system/config/media.yaml index b118a21..fad5e0d 100644 --- a/system/config/media.yaml +++ b/system/config/media.yaml @@ -199,7 +199,7 @@ types: gz: type: file thumb: media/thumb-gz.png - mime: application/gzip + mime: application/x-gzip tar: type: file thumb: media/thumb-tar.png diff --git a/system/config/system.yaml b/system/config/system.yaml index 652910d..380d650 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -127,6 +127,9 @@ assets: # Configuration for Assets Mana js_pipeline: false # The JS pipeline is the unification of multiple JS resources into one file js_pipeline_include_externals: true # Include external URLs in the pipeline by default js_pipeline_before_excludes: true # Render the pipeline before any excluded files + js_module_pipeline: false # The JS Module pipeline is the unification of multiple JS Module resources into one file + js_module_pipeline_include_externals: true # Include external URLs in the pipeline by default + js_module_pipeline_before_excludes: true # Render the pipeline before any excluded files js_minify: true # Minify the JS during pipelining enable_asset_timestamp: false # Enable asset timestamps enable_asset_sri: false # Enable asset SRI @@ -182,6 +185,7 @@ session: name: grav-site # Name prefix of the session cookie. Use alphanumeric, dashes or underscores only. Do not use dots in the session name uniqueness: path # Should sessions be `path` based or `security.salt` based secure: false # Set session secure. If true, indicates that communication for this cookie must be over an encrypted transmission. Enable this only on sites that run exclusively on HTTPS + secure_https: true # Set session secure on HTTPS but not on HTTP. Has no effect if you have `session.secure: true`. Set to false if your site jumps between HTTP and HTTPS. httponly: true # Set session HTTP only. If true, indicates that cookies should be used only over HTTP, and JavaScript modification is not allowed. samesite: Lax # Set session SameSite. Possible values are Lax, Strict and None. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite split: true # Sessions should be independent between site and plugins (such as admin) @@ -204,6 +208,7 @@ http: accounts: type: regular # EXPERIMENTAL: Account type: regular or flex storage: file # EXPERIMENTAL: Flex storage type: file or folder + avatar: gravatar # Avatar generator [multiavatar|gravatar] flex: cache: diff --git a/system/defines.php b/system/defines.php index f5ccba9..5f743db 100644 --- a/system/defines.php +++ b/system/defines.php @@ -3,13 +3,13 @@ /** * @package Grav\Core * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.7.25'); +define('GRAV_VERSION', '1.7.31'); define('GRAV_SCHEMA', '1.7.0_2020-11-20_1'); define('GRAV_TESTING', false); diff --git a/system/install.php b/system/install.php index e8cd582..5c9440f 100644 --- a/system/install.php +++ b/system/install.php @@ -2,7 +2,7 @@ /** * @package Grav\Core * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/languages/es.yaml b/system/languages/es.yaml index 95827ee..a8a47aa 100644 --- a/system/languages/es.yaml +++ b/system/languages/es.yaml @@ -44,7 +44,7 @@ GRAV: WK: sem MO: mes YR: año - DEC: dic + DEC: déc SECOND_PLURAL: segundos MINUTE_PLURAL: minutos HOUR_PLURAL: horas @@ -64,7 +64,7 @@ GRAV: VALIDATION_FAIL: 'Falló la validación: ' INVALID_INPUT: 'Dato inválido en: ' MISSING_REQUIRED_FIELD: 'Falta el campo requerido: ' - XSS_ISSUES: "Se detectaron problemas XSS potenciales en el campo '%s'" + XSS_ISSUES: "Se detectaron potenciales problemas XSS en el campo '%s'" MONTHS_OF_THE_YEAR: - 'Enero' - 'Febrero' @@ -86,7 +86,7 @@ GRAV: - 'Viernes' - 'Sábado' - 'Domingo' - YES: "Si" + YES: "Sí" NO: "No" CRON: EVERY: cada @@ -96,12 +96,12 @@ GRAV: EVERY_DAY_OF_MONTH: cada día del mes EVERY_MONTH: cada mes TEXT_PERIOD: Cada - TEXT_MINS: ' a minuto(s) despues de la hora' + TEXT_MINS: ' a minuto(s) después de la hora' TEXT_TIME: ' a :' TEXT_DOW: ' en ' TEXT_MONTH: ' de' TEXT_DOM: ' en' - ERROR1: La etiqueta %s no está soportada! - ERROR2: El número de elementos es erroneo + ERROR1: '¡La etiqueta %s no está soportada!' + ERROR2: El número de elementos es erróneo ERROR3: El jquery_element debería establecerse en la configuración del jqCron ERROR4: Expresión no reconocida diff --git a/system/router.php b/system/router.php index d58609c..c19f814 100644 --- a/system/router.php +++ b/system/router.php @@ -3,7 +3,7 @@ /** * @package Grav\Core * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -22,9 +22,9 @@ if ($path !== '/index.php' && is_file($root . $path)) { // Block all direct access for these folders || preg_match('`^/(\.git|cache|bin|logs|backup|webserver-configs|tests)/`ui', $path) // Block access to specific file types for these system folders - || preg_match('`^/(system|vendor)/(.*)\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$`ui', $path) + || preg_match('`^/(system|vendor)/(.*)\.(txt|xml|md|html|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$`ui', $path) // Block access to specific file types for these user folders - || preg_match('`^/(user)/(.*)\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$`ui', $path) + || preg_match('`^/(user)/(.*)\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$`ui', $path) // Block all direct access to .md files || preg_match('`\.md$`ui', $path) // Block access to specific files in the root folder diff --git a/system/src/DOMLettersIterator.php b/system/src/DOMLettersIterator.php new file mode 100644 index 0000000..e3c2c4a --- /dev/null +++ b/system/src/DOMLettersIterator.php @@ -0,0 +1,165 @@ +load('example.xml'); + * foreach(new DOMLettersIterator($doc) as $letter) echo $letter; + * + * NB: If you only need characters without their position + * in the document, use DOMNode->textContent instead. + * + * @author porneL http://pornel.net + * @license Public Domain + * @url https://github.com/antoligy/dom-string-iterators + * + * @implements Iterator + */ +final class DOMLettersIterator implements Iterator +{ + /** @var DOMElement */ + private $start; + /** @var DOMElement|null */ + private $current; + /** @var int */ + private $offset = -1; + /** @var int|null */ + private $key; + /** @var array|null */ + private $letters; + + /** + * expects DOMElement or DOMDocument (see DOMDocument::load and DOMDocument::loadHTML) + * + * @param DOMNode $el + */ + public function __construct(DOMNode $el) + { + if ($el instanceof DOMDocument) { + $el = $el->documentElement; + } + + if (!$el instanceof DOMElement) { + throw new InvalidArgumentException('Invalid arguments, expected DOMElement or DOMDocument'); + } + + $this->start = $el; + } + + /** + * Returns position in text as DOMText node and character offset. + * (it's NOT a byte offset, you must use mb_substr() or similar to use this offset properly). + * node may be NULL if iterator has finished. + * + * @return array + */ + public function currentTextPosition(): array + { + return [$this->current, $this->offset]; + } + + /** + * Returns DOMElement that is currently being iterated or NULL if iterator has finished. + * + * @return DOMElement|null + */ + public function currentElement(): ?DOMElement + { + return $this->current ? $this->current->parentNode : null; + } + + // Implementation of Iterator interface + + /** + * @return int|null + */ + public function key(): ?int + { + return $this->key; + } + + /** + * @return void + */ + public function next(): void + { + if (null === $this->current) { + return; + } + + if ($this->current->nodeType === XML_TEXT_NODE || $this->current->nodeType === XML_CDATA_SECTION_NODE) { + if ($this->offset === -1) { + preg_match_all('/./us', $this->current->textContent, $m); + $this->letters = $m[0]; + } + + $this->offset++; + $this->key++; + if ($this->letters && $this->offset < count($this->letters)) { + return; + } + + $this->offset = -1; + } + + while ($this->current->nodeType === XML_ELEMENT_NODE && $this->current->firstChild) { + $this->current = $this->current->firstChild; + if ($this->current->nodeType === XML_TEXT_NODE || $this->current->nodeType === XML_CDATA_SECTION_NODE) { + $this->next(); + return; + } + } + + while (!$this->current->nextSibling && $this->current->parentNode) { + $this->current = $this->current->parentNode; + if ($this->current === $this->start) { + $this->current = null; + return; + } + } + + $this->current = $this->current->nextSibling; + + $this->next(); + } + + /** + * Return the current element + * @link https://php.net/manual/en/iterator.current.php + * + * @return string|null + */ + public function current(): ?string + { + return $this->letters ? $this->letters[$this->offset] : null; + } + + /** + * Checks if current position is valid + * @link https://php.net/manual/en/iterator.valid.php + * + * @return bool + */ + public function valid(): bool + { + return (bool)$this->current; + } + + /** + * @return void + */ + public function rewind(): void + { + $this->current = $this->start; + $this->offset = -1; + $this->key = 0; + $this->letters = []; + + $this->next(); + } +} + diff --git a/system/src/DOMWordsIterator.php b/system/src/DOMWordsIterator.php new file mode 100644 index 0000000..fb7c2e3 --- /dev/null +++ b/system/src/DOMWordsIterator.php @@ -0,0 +1,158 @@ +load('example.xml'); + * foreach(new DOMWordsIterator($doc) as $word) echo $word; + * + * @author pjgalbraith http://www.pjgalbraith.com + * @author porneL http://pornel.net (based on DOMLettersIterator available at http://pornel.net/source/domlettersiterator.php) + * @license Public Domain + * @url https://github.com/antoligy/dom-string-iterators + * + * @implements Iterator + */ + +final class DOMWordsIterator implements Iterator +{ + /** @var DOMElement */ + private $start; + /** @var DOMElement|null */ + private $current; + /** @var int */ + private $offset = -1; + /** @var int|null */ + private $key; + /** @var array>|null */ + private $words; + + /** + * expects DOMElement or DOMDocument (see DOMDocument::load and DOMDocument::loadHTML) + * + * @param DOMNode $el + */ + public function __construct(DOMNode $el) + { + if ($el instanceof DOMDocument) { + $el = $el->documentElement; + } + + if (!$el instanceof DOMElement) { + throw new InvalidArgumentException('Invalid arguments, expected DOMElement or DOMDocument'); + } + + $this->start = $el; + } + + /** + * Returns position in text as DOMText node and character offset. + * (it's NOT a byte offset, you must use mb_substr() or similar to use this offset properly). + * node may be NULL if iterator has finished. + * + * @return array + */ + public function currentWordPosition(): array + { + return [$this->current, $this->offset, $this->words]; + } + + /** + * Returns DOMElement that is currently being iterated or NULL if iterator has finished. + * + * @return DOMElement|null + */ + public function currentElement(): ?DOMElement + { + return $this->current ? $this->current->parentNode : null; + } + + // Implementation of Iterator interface + + /** + * Return the key of the current element + * @link https://php.net/manual/en/iterator.key.php + * @return int|null + */ + public function key(): ?int + { + return $this->key; + } + + /** + * @return void + */ + public function next(): void + { + if (null === $this->current) { + return; + } + + if ($this->current->nodeType === XML_TEXT_NODE || $this->current->nodeType === XML_CDATA_SECTION_NODE) { + if ($this->offset === -1) { + $this->words = preg_split("/[\n\r\t ]+/", $this->current->textContent, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_OFFSET_CAPTURE) ?: []; + } + $this->offset++; + + if ($this->words && $this->offset < count($this->words)) { + $this->key++; + return; + } + $this->offset = -1; + } + + while ($this->current->nodeType === XML_ELEMENT_NODE && $this->current->firstChild) { + $this->current = $this->current->firstChild; + if ($this->current->nodeType === XML_TEXT_NODE || $this->current->nodeType === XML_CDATA_SECTION_NODE) { + $this->next(); + return; + } + } + + while (!$this->current->nextSibling && $this->current->parentNode) { + $this->current = $this->current->parentNode; + if ($this->current === $this->start) { + $this->current = null; + return; + } + } + + $this->current = $this->current->nextSibling; + + $this->next(); + } + + /** + * Return the current element + * @link https://php.net/manual/en/iterator.current.php + * @return string|null + */ + public function current(): ?string + { + return $this->words ? (string)$this->words[$this->offset][0] : null; + } + + /** + * Checks if current position is valid + * @link https://php.net/manual/en/iterator.valid.php + * @return bool + */ + public function valid(): bool + { + return (bool)$this->current; + } + + public function rewind(): void + { + $this->current = $this->start; + $this->offset = -1; + $this->key = 0; + $this->words = []; + + $this->next(); + } +} diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index a9b930b..621a140 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -16,8 +16,8 @@ use Grav\Common\Assets\Traits\TestingAssetsTrait; use Grav\Common\Config\Config; use Grav\Framework\Object\PropertyObject; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; +use function array_slice; use function call_user_func_array; -use function count; use function func_get_args; use function is_array; @@ -30,14 +30,21 @@ class Assets extends PropertyObject use TestingAssetsTrait; use LegacyAssetsTrait; + const LINK = 'link'; const CSS = 'css'; const JS = 'js'; + const JS_MODULE = 'js_module'; + const LINK_COLLECTION = 'assets_link'; const CSS_COLLECTION = 'assets_css'; const JS_COLLECTION = 'assets_js'; + const JS_MODULE_COLLECTION = 'assets_js_module'; + const LINK_TYPE = Assets\Link::class; const CSS_TYPE = Assets\Css::class; const JS_TYPE = Assets\Js::class; + const JS_MODULE_TYPE = Assets\JsModule::class; const INLINE_CSS_TYPE = Assets\InlineCss::class; const INLINE_JS_TYPE = Assets\InlineJs::class; + const INLINE_JS_MODULE_TYPE = Assets\InlineJsModule::class; /** @const Regex to match CSS and JavaScript files */ const DEFAULT_REGEX = '/.\.(css|js)$/i'; @@ -48,15 +55,24 @@ class Assets extends PropertyObject /** @const Regex to match JavaScript files */ const JS_REGEX = '/.\.js$/i'; + /** @const Regex to match JavaScriptModyle files */ + const JS_MODULE_REGEX = '/.\.mjs$/i'; + /** @var string */ protected $assets_dir; /** @var string */ protected $assets_url; + /** @var array */ + protected $assets_link = []; /** @var array */ protected $assets_css = []; /** @var array */ protected $assets_js = []; + /** @var array */ + protected $assets_js_module = []; + + // Following variables come from the configuration: /** @var bool */ @@ -66,19 +82,17 @@ class Assets extends PropertyObject /** @var bool */ protected $css_pipeline_before_excludes; /** @var bool */ - protected $inlinecss_pipeline_include_externals; - /** @var bool */ - protected $inlinecss_pipeline_before_excludes; - /** @var bool */ protected $js_pipeline; /** @var bool */ protected $js_pipeline_include_externals; /** @var bool */ protected $js_pipeline_before_excludes; /** @var bool */ - protected $inlinejs_pipeline_include_externals; + protected $js_module_pipeline; /** @var bool */ - protected $inlinejs_pipeline_before_excludes; + protected $js_module_pipeline_include_externals; + /** @var bool */ + protected $js_module_pipeline_before_excludes; /** @var array */ protected $pipeline_options = []; @@ -160,6 +174,10 @@ class Assets extends PropertyObject */ public function add($asset) { + if (!$asset) { + return $this; + } + $args = func_get_args(); // More than one asset @@ -184,7 +202,8 @@ class Assets extends PropertyObject call_user_func_array([$this, 'add'], $args); } else { // Get extension - $extension = pathinfo(parse_url($asset, PHP_URL_PATH), PATHINFO_EXTENSION); + $path = parse_url($asset, PHP_URL_PATH); + $extension = $path ? Utils::pathinfo($path, PATHINFO_EXTENSION) : ''; // JavaScript or CSS if ($extension !== '') { @@ -193,6 +212,8 @@ class Assets extends PropertyObject call_user_func_array([$this, 'addCss'], $args); } elseif ($extension === 'js') { call_user_func_array([$this, 'addJs'], $args); + } elseif ($extension === 'mjs') { + call_user_func_array([$this, 'addJsModule'], $args); } } } @@ -222,7 +243,7 @@ class Assets extends PropertyObject return $this; } - if (($type === $this::CSS_TYPE || $type === $this::JS_TYPE) && isset($this->collections[$asset])) { + if ($this->isValidType($type) && isset($this->collections[$asset])) { $this->addType($collection, $type, $this->collections[$asset], $options); return $this; } @@ -230,7 +251,9 @@ class Assets extends PropertyObject // If pipeline disabled, set to position if provided, else after if (isset($options['pipeline'])) { if ($options['pipeline'] === false) { - $exclude_type = ($type === $this::JS_TYPE || $type === $this::INLINE_JS_TYPE) ? $this::JS : $this::CSS; + + $exclude_type = $this->getBaseType($type); + $excludes = strtolower($exclude_type . '_pipeline_before_excludes'); if ($this->{$excludes}) { $default = 'after'; @@ -269,6 +292,16 @@ class Assets extends PropertyObject return $this; } + /** + * Add a CSS asset or a collection of assets. + * + * @return $this + */ + public function addLink($asset) + { + return $this->addType($this::LINK_COLLECTION, $this::LINK_TYPE, $asset, $this->unifyLegacyArguments(func_get_args(), $this::LINK_TYPE)); + } + /** * Add a CSS asset or a collection of assets. * @@ -309,6 +342,25 @@ class Assets extends PropertyObject return $this->addType($this::JS_COLLECTION, $this::INLINE_JS_TYPE, $asset, $this->unifyLegacyArguments(func_get_args(), $this::INLINE_JS_TYPE)); } + /** + * Add a JS asset or a collection of assets. + * + * @return $this + */ + public function addJsModule($asset) + { + return $this->addType($this::JS_MODULE_COLLECTION, $this::JS_MODULE_TYPE, $asset, $this->unifyLegacyArguments(func_get_args(), $this::JS_MODULE_TYPE)); + } + + /** + * Add an Inline JS asset or a collection of assets. + * + * @return $this + */ + public function addInlineJsModule($asset) + { + return $this->addType($this::JS_MODULE_COLLECTION, $this::INLINE_JS_MODULE_TYPE, $asset, $this->unifyLegacyArguments(func_get_args(), $this::INLINE_JS_MODULE_TYPE)); + } /** * Add/replace collection. @@ -400,7 +452,7 @@ class Assets extends PropertyObject $after_assets = $this->filterAssets($group_assets, 'position', 'after', true); // Pipeline - if ($this->{$pipeline_enabled}) { + if ($this->{$pipeline_enabled} ?? false) { $options = array_merge($this->pipeline_options, ['timestamp' => $this->timestamp]); $pipeline = new Pipeline($options); @@ -432,9 +484,29 @@ class Assets extends PropertyObject * @param array $attributes * @return string */ - public function css($group = 'head', $attributes = []) + public function css($group = 'head', $attributes = [], $include_link = true) { - return $this->render('css', $group, $attributes); + $output = ''; + + if ($include_link) { + $output = $this->link($group, $attributes); + } + + $output .= $this->render(self::CSS, $group, $attributes); + + return $output; + } + + /** + * Build the CSS link tags. + * + * @param string $group name of the group + * @param array $attributes + * @return string + */ + public function link($group = 'head', $attributes = []) + { + return $this->render(self::LINK, $group, $attributes); } /** @@ -444,8 +516,71 @@ class Assets extends PropertyObject * @param array $attributes * @return string */ - public function js($group = 'head', $attributes = []) + public function js($group = 'head', $attributes = [], $include_js_module = true) { - return $this->render('js', $group, $attributes); + $output = $this->render(self::JS, $group, $attributes); + + if ($include_js_module) { + $output .= $this->jsModule($group, $attributes); + } + + return $output; + } + + /** + * Build the Javascript Modules tags + * + * @param string $group + * @param array $attributes + * @return string + */ + public function jsModule($group = 'head', $attributes = []) + { + return $this->render(self::JS_MODULE, $group, $attributes); + } + + /** + * @param string $group + * @param array $attributes + * @return string + */ + public function all($group = 'head', $attributes = []) + { + $output = $this->css($group, $attributes, false); + $output .= $this->link($group, $attributes); + $output .= $this->js($group, $attributes, false); + $output .= $this->jsModule($group, $attributes); + return $output; + } + + /** + * @param class-string $type + * @return bool + */ + protected function isValidType($type) + { + return in_array($type, [self::CSS_TYPE, self::JS_TYPE, self::JS_MODULE_TYPE]); + } + + /** + * @param class-string $type + * @return string + */ + protected function getBaseType($type) + { + switch ($type) { + case $this::JS_TYPE: + case $this::INLINE_JS_TYPE: + $base_type = $this::JS; + break; + case $this::JS_MODULE_TYPE: + case $this::INLINE_JS_MODULE_TYPE: + $base_type = $this::JS_MODULE; + break; + default: + $base_type = $this::CSS; + } + + return $base_type; } } diff --git a/system/src/Grav/Common/Assets/BaseAsset.php b/system/src/Grav/Common/Assets/BaseAsset.php index a115ce9..d062d75 100644 --- a/system/src/Grav/Common/Assets/BaseAsset.php +++ b/system/src/Grav/Common/Assets/BaseAsset.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Assets * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -26,8 +26,9 @@ abstract class BaseAsset extends PropertyObject { use AssetUtilsTrait; - protected const CSS_ASSET = true; - protected const JS_ASSET = false; + protected const CSS_ASSET = 1; + protected const JS_ASSET = 2; + protected const JS_MODULE_ASSET = 3; /** @var string|false */ protected $asset; @@ -69,7 +70,7 @@ abstract class BaseAsset extends PropertyObject * @param array $elements * @param string|null $key */ - public function __construct(array $elements = [], $key = null) + public function __construct(array $elements = [], ?string $key = null) { $base_config = [ 'group' => 'head', @@ -248,6 +249,7 @@ abstract class BaseAsset extends PropertyObject * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return ['type' => $this->getType(), 'elements' => $this->getElements()]; @@ -265,4 +267,17 @@ abstract class BaseAsset extends PropertyObject { return ''; } + + /** + * Finds relative JS urls() and rewrites the URL with an absolute one + * + * @param string $file the css source file + * @param string $dir local relative path to the css file + * @param bool $local is this a local or remote asset + * @return string + */ + protected function jsRewrite($file, $dir, $local) + { + return ''; + } } diff --git a/system/src/Grav/Common/Assets/BlockAssets.php b/system/src/Grav/Common/Assets/BlockAssets.php new file mode 100644 index 0000000..7d97960 --- /dev/null +++ b/system/src/Grav/Common/Assets/BlockAssets.php @@ -0,0 +1,207 @@ +getAssets(); + foreach ($types as $type => $groups) { + switch ($type) { + case 'frameworks': + static::registerFrameworks($assets, $groups); + break; + case 'styles': + static::registerStyles($assets, $groups); + break; + case 'scripts': + static::registerScripts($assets, $groups); + break; + case 'links': + static::registerLinks($assets, $groups); + break; + case 'html': + static::registerHtml($assets, $groups); + break; + } + } + } + + /** + * @param Assets $assets + * @param array $list + * @return void + */ + protected static function registerFrameworks(Assets $assets, array $list): void + { + if ($list) { + throw new \RuntimeException('Not Implemented'); + } + } + + /** + * @param Assets $assets + * @param array $groups + * @return void + */ + protected static function registerStyles(Assets $assets, array $groups): void + { + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + + foreach ($groups as $group => $styles) { + foreach ($styles as $style) { + switch ($style[':type']) { + case 'file': + $options = [ + 'priority' => $style[':priority'], + 'group' => $group, + 'type' => $style['type'], + 'media' => $style['media'] + ] + $style['element']; + + $assets->addCss(static::getRelativeUrl($style['href'], $config->get('system.assets.css_pipeline')), $options); + break; + case 'inline': + $options = [ + 'priority' => $style[':priority'], + 'group' => $group, + 'type' => $style['type'], + ] + $style['element']; + + $assets->addInlineCss($style['content'], $options); + break; + } + } + } + } + + /** + * @param Assets $assets + * @param array $groups + * @return void + */ + protected static function registerScripts(Assets $assets, array $groups): void + { + $grav = Grav::instance(); + + /** @var Config $config */ + $config = $grav['config']; + + foreach ($groups as $group => $scripts) { + $group = $group === 'footer' ? 'bottom' : $group; + + foreach ($scripts as $script) { + switch ($script[':type']) { + case 'file': + $options = [ + 'group' => $group, + 'priority' => $script[':priority'], + 'src' => $script['src'], + 'type' => $script['type'], + 'loading' => $script['loading'], + 'defer' => $script['defer'], + 'async' => $script['async'], + 'handle' => $script['handle'] + ] + $script['element']; + + $assets->addJs(static::getRelativeUrl($script['src'], $config->get('system.assets.js_pipeline')), $options); + break; + case 'inline': + $options = [ + 'priority' => $script[':priority'], + 'group' => $group, + 'type' => $script['type'], + 'loading' => $script['loading'] + ] + $script['element']; + + $assets->addInlineJs($script['content'], $options); + break; + } + } + } + } + + /** + * @param Assets $assets + * @param array $groups + * @return void + */ + protected static function registerLinks(Assets $assets, array $groups): void + { + foreach ($groups as $group => $links) { + foreach ($links as $link) { + $href = $link['href']; + $options = [ + 'group' => $group, + 'priority' => $link[':priority'], + 'rel' => $link['rel'], + ] + $link['element']; + + $assets->addLink($href, $options); + } + } + } + + /** + * @param Assets $assets + * @param array $groups + * @return void + */ + protected static function registerHtml(Assets $assets, array $groups): void + { + if ($groups) { + throw new \RuntimeException('Not Implemented'); + } + } + + /** + * @param string $url + * @param bool $pipeline + * @return string + */ + protected static function getRelativeUrl($url, $pipeline) + { + $grav = Grav::instance(); + + $base = rtrim($grav['base_url'], '/') ?: '/'; + + if (strpos($url, $base) === 0) { + if ($pipeline) { + // Remove file timestamp if CSS pipeline has been enabled. + $url = preg_replace('|[?#].*|', '', $url); + } + + return substr($url, strlen($base) - 1); + } + return $url; + } +} diff --git a/system/src/Grav/Common/Assets/Css.php b/system/src/Grav/Common/Assets/Css.php index 4c6a9c9..ea6b388 100644 --- a/system/src/Grav/Common/Assets/Css.php +++ b/system/src/Grav/Common/Assets/Css.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Assets * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -22,7 +22,7 @@ class Css extends BaseAsset * @param array $elements * @param string|null $key */ - public function __construct(array $elements = [], $key = null) + public function __construct(array $elements = [], ?string $key = null) { $base_options = [ 'asset_type' => 'css', diff --git a/system/src/Grav/Common/Assets/InlineCss.php b/system/src/Grav/Common/Assets/InlineCss.php index f024a95..4984db4 100644 --- a/system/src/Grav/Common/Assets/InlineCss.php +++ b/system/src/Grav/Common/Assets/InlineCss.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Assets * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -22,7 +22,7 @@ class InlineCss extends BaseAsset * @param array $elements * @param string|null $key */ - public function __construct(array $elements = [], $key = null) + public function __construct(array $elements = [], ?string $key = null) { $base_options = [ 'asset_type' => 'css', diff --git a/system/src/Grav/Common/Assets/InlineJs.php b/system/src/Grav/Common/Assets/InlineJs.php index 6787608..e38a51a 100644 --- a/system/src/Grav/Common/Assets/InlineJs.php +++ b/system/src/Grav/Common/Assets/InlineJs.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Assets * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -22,7 +22,7 @@ class InlineJs extends BaseAsset * @param array $elements * @param string|null $key */ - public function __construct(array $elements = [], $key = null) + public function __construct(array $elements = [], ?string $key = null) { $base_options = [ 'asset_type' => 'js', diff --git a/system/src/Grav/Common/Assets/InlineJsModule.php b/system/src/Grav/Common/Assets/InlineJsModule.php new file mode 100644 index 0000000..42ce6f1 --- /dev/null +++ b/system/src/Grav/Common/Assets/InlineJsModule.php @@ -0,0 +1,46 @@ + 'js_module', + 'attributes' => ['type' => 'module'], + 'position' => 'after' + ]; + + $merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements); + + parent::__construct($merged_attributes, $key); + } + + /** + * @return string + */ + public function render() + { + return 'renderAttributes(). ">\n" . trim($this->asset) . "\n\n"; + } + +} diff --git a/system/src/Grav/Common/Assets/Js.php b/system/src/Grav/Common/Assets/Js.php index fc2a472..8687a86 100644 --- a/system/src/Grav/Common/Assets/Js.php +++ b/system/src/Grav/Common/Assets/Js.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Assets * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -22,7 +22,7 @@ class Js extends BaseAsset * @param array $elements * @param string|null $key */ - public function __construct(array $elements = [], $key = null) + public function __construct(array $elements = [], ?string $key = null) { $base_options = [ 'asset_type' => 'js', diff --git a/system/src/Grav/Common/Assets/JsModule.php b/system/src/Grav/Common/Assets/JsModule.php new file mode 100644 index 0000000..5c2a836 --- /dev/null +++ b/system/src/Grav/Common/Assets/JsModule.php @@ -0,0 +1,49 @@ + 'js_module', + 'attributes' => ['type' => 'module'] + ]; + + $merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements); + + parent::__construct($merged_attributes, $key); + } + + /** + * @return string + */ + public function render() + { + if (isset($this->attributes['loading']) && $this->attributes['loading'] === 'inline') { + $buffer = $this->gatherLinks([$this], self::JS_MODULE_ASSET); + return 'renderAttributes() . ">\n" . trim($buffer) . "\n\n"; + } + + return '\n"; + } +} diff --git a/system/src/Grav/Common/Assets/Link.php b/system/src/Grav/Common/Assets/Link.php new file mode 100644 index 0000000..ecafcea --- /dev/null +++ b/system/src/Grav/Common/Assets/Link.php @@ -0,0 +1,43 @@ + 'link', + ]; + + $merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements); + + parent::__construct($merged_attributes, $key); + } + + /** + * @return string + */ + public function render() + { + return 'renderAttributes() . $this->integrityHash($this->asset) . ">\n"; + } +} diff --git a/system/src/Grav/Common/Assets/Pipeline.php b/system/src/Grav/Common/Assets/Pipeline.php index 948104a..0010d7b 100644 --- a/system/src/Grav/Common/Assets/Pipeline.php +++ b/system/src/Grav/Common/Assets/Pipeline.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Assets * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -29,12 +29,16 @@ class Pipeline extends PropertyObject { use AssetUtilsTrait; - protected const CSS_ASSET = true; - protected const JS_ASSET = false; + protected const CSS_ASSET = 1; + protected const JS_ASSET = 2; + protected const JS_MODULE_ASSET = 3; /** @const Regex to match CSS urls */ protected const CSS_URL_REGEX = '{url\(([\'\"]?)(.*?)\1\)}'; + /** @const Regex to match JS imports */ + protected const JS_IMPORT_REGEX = '{import.+from\s?[\'|\"](.+?)[\'|\"]}'; + /** @const Regex to match CSS sourcemap comments */ protected const CSS_SOURCEMAP_REGEX = '{\/\*# (.*?) \*\/}'; @@ -122,7 +126,7 @@ class Pipeline extends PropertyObject // Compute uid based on assets and timestamp $json_assets = json_encode($assets); - $uid = md5($json_assets . $this->css_minify . $this->css_rewrite . $group); + $uid = md5($json_assets . (int)$this->css_minify . (int)$this->css_rewrite . $group); $file = $uid . '.css'; $relative_path = "{$this->base_url}{$this->assets_url}/{$file}"; @@ -169,7 +173,7 @@ class Pipeline extends PropertyObject * @param array $attributes * @return bool|string URL or generated content if available, else false */ - public function renderJs($assets, $group, $attributes = []) + public function renderJs($assets, $group, $attributes = [], $type = self::JS_ASSET) { // temporary list of assets to pipeline $inline_group = false; @@ -198,7 +202,7 @@ class Pipeline extends PropertyObject } // Concatenate files - $buffer = $this->gatherLinks($assets, self::JS_ASSET); + $buffer = $this->gatherLinks($assets, $type); // Minify if required if ($this->shouldMinify('js')) { @@ -223,6 +227,19 @@ class Pipeline extends PropertyObject return $output; } + /** + * Minify and concatenate JS files. + * + * @param array $assets + * @param string $group + * @param array $attributes + * @return bool|string URL or generated content if available, else false + */ + public function renderJs_Module($assets, $group, $attributes = []) + { + $attributes['type'] = 'module'; + return $this->renderJs($assets, $group, $attributes, self::JS_MODULE_ASSET); + } /** * Finds relative CSS urls() and rewrites the URL with an absolute one @@ -262,6 +279,42 @@ class Pipeline extends PropertyObject return $file; } + /** + * Finds relative JS urls() and rewrites the URL with an absolute one + * + * @param string $file the css source file + * @param string $dir local relative path to the css file + * @param bool $local is this a local or remote asset + * @return string + */ + protected function jsRewrite($file, $dir, $local) + { + // Find any js import elements, grab the URLs and calculate an absolute path + // Then replace the old url with the new one + $file = (string)preg_replace_callback(self::JS_IMPORT_REGEX, function ($matches) use ($dir, $local) { + + $old_url = $matches[1]; + + // Ensure link is not rooted to web server, a data URL, or to a remote host + if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url) || $this->isRemoteLink($old_url)) { + return $matches[0]; + } + + // clean leading / + $old_url = Utils::normalizePath($dir . '/' . $old_url); + $old_url = str_replace('/./', '/', $old_url); + if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url)) { + $old_url = ltrim($old_url, '/'); + } + + $new_url = ($local ? $this->base_url : '') . $old_url; + + return str_replace($matches[1], $new_url, $matches[0]); + }, $file); + + return $file; + } + /** * @param string $type * @return bool diff --git a/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php b/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php index 3f5a690..0e3f392 100644 --- a/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php +++ b/system/src/Grav/Common/Assets/Traits/AssetUtilsTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Assets\Traits * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -62,13 +62,13 @@ trait AssetUtilsTrait * Download and concatenate the content of several links. * * @param array $assets - * @param bool $css + * @param int $type * @return string */ - protected function gatherLinks(array $assets, $css = true) + protected function gatherLinks(array $assets, int $type = self::CSS_ASSET): string { $buffer = ''; - foreach ($assets as $id => $asset) { + foreach ($assets as $asset) { $local = true; $link = $asset->getAsset(); @@ -100,21 +100,25 @@ trait AssetUtilsTrait } // Double check last character being - if (!$css) { + if ($type === self::JS_ASSET || $type === self::JS_MODULE_ASSET) { $file = rtrim($file, ' ;') . ';'; } // If this is CSS + the file is local + rewrite enabled - if ($css && $this->css_rewrite) { + if ($type === self::CSS_ASSET && $this->css_rewrite) { $file = $this->cssRewrite($file, $relative_dir, $local); } + if ($type === self::JS_MODULE_ASSET) { + $file = $this->jsRewrite($file, $relative_dir, $local); + } + $file = rtrim($file) . PHP_EOL; $buffer .= $file; } // Pull out @imports and move to top - if ($css) { + if ($type === self::CSS_ASSET) { $buffer = $this->moveImports($buffer); } diff --git a/system/src/Grav/Common/Assets/Traits/LegacyAssetsTrait.php b/system/src/Grav/Common/Assets/Traits/LegacyAssetsTrait.php index 36b2152..c1ef0a3 100644 --- a/system/src/Grav/Common/Assets/Traits/LegacyAssetsTrait.php +++ b/system/src/Grav/Common/Assets/Traits/LegacyAssetsTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Assets\Traits * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Assets/Traits/TestingAssetsTrait.php b/system/src/Grav/Common/Assets/Traits/TestingAssetsTrait.php index 15dc00e..b11b439 100644 --- a/system/src/Grav/Common/Assets/Traits/TestingAssetsTrait.php +++ b/system/src/Grav/Common/Assets/Traits/TestingAssetsTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Assets\Traits * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -285,6 +285,15 @@ trait TestingAssetsTrait return $this; } + // Add JavaScript Module files + if ($pattern === self::JS_MODULE_REGEX) { + foreach ($files as $file) { + $this->addJsModule($file); + } + + return $this; + } + // Unknown pattern. foreach ($files as $asset) { $this->add($asset); diff --git a/system/src/Grav/Common/Backup/Backups.php b/system/src/Grav/Common/Backup/Backups.php index 4680f85..ff4789d 100644 --- a/system/src/Grav/Common/Backup/Backups.php +++ b/system/src/Grav/Common/Backup/Backups.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Backup * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -104,8 +104,8 @@ class Backups */ public function getBackupDownloadUrl($backup, $base_url) { - $param_sep = $param_sep = Grav::instance()['config']->get('system.param_sep', ':'); - $download = urlencode(base64_encode(basename($backup))); + $param_sep = Grav::instance()['config']->get('system.param_sep', ':'); + $download = urlencode(base64_encode(Utils::basename($backup))); $url = rtrim(Grav::instance()['uri']->rootUrl(true), '/') . '/' . trim( $base_url, '/' @@ -145,7 +145,7 @@ class Backups { $backups = static::getAvailableBackups(); - return array_sum(array_column($backups, 'size')); + return $backups ? array_sum(array_column($backups, 'size')) : 0; } /** diff --git a/system/src/Grav/Common/Browser.php b/system/src/Grav/Common/Browser.php index e4a6513..ffc8da3 100644 --- a/system/src/Grav/Common/Browser.php +++ b/system/src/Grav/Common/Browser.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Cache.php b/system/src/Grav/Common/Cache.php index a503518..ed40a08 100644 --- a/system/src/Grav/Common/Cache.php +++ b/system/src/Grav/Common/Cache.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -177,7 +177,7 @@ class Cache extends Getters public function purgeOldCache() { $cache_dir = dirname($this->cache_dir); - $current = basename($this->cache_dir); + $current = Utils::basename($this->cache_dir); $count = 0; foreach (new DirectoryIterator($cache_dir) as $file) { diff --git a/system/src/Grav/Common/Composer.php b/system/src/Grav/Common/Composer.php index f1f6e5d..667edf2 100644 --- a/system/src/Grav/Common/Composer.php +++ b/system/src/Grav/Common/Composer.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Config/CompiledBase.php b/system/src/Grav/Common/Config/CompiledBase.php index 0764189..b462b4c 100644 --- a/system/src/Grav/Common/Config/CompiledBase.php +++ b/system/src/Grav/Common/Config/CompiledBase.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Config * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Config/CompiledBlueprints.php b/system/src/Grav/Common/Config/CompiledBlueprints.php index 7743054..e838591 100644 --- a/system/src/Grav/Common/Config/CompiledBlueprints.php +++ b/system/src/Grav/Common/Config/CompiledBlueprints.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Config * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Config/CompiledConfig.php b/system/src/Grav/Common/Config/CompiledConfig.php index 22225bc..2db6de5 100644 --- a/system/src/Grav/Common/Config/CompiledConfig.php +++ b/system/src/Grav/Common/Config/CompiledConfig.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Config * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Config/CompiledLanguages.php b/system/src/Grav/Common/Config/CompiledLanguages.php index 6674389..0a26686 100644 --- a/system/src/Grav/Common/Config/CompiledLanguages.php +++ b/system/src/Grav/Common/Config/CompiledLanguages.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Config * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Config/Config.php b/system/src/Grav/Common/Config/Config.php index 7adb523..ca027bf 100644 --- a/system/src/Grav/Common/Config/Config.php +++ b/system/src/Grav/Common/Config/Config.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Config * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Config/ConfigFileFinder.php b/system/src/Grav/Common/Config/ConfigFileFinder.php index e6b1afe..28f9dc1 100644 --- a/system/src/Grav/Common/Config/ConfigFileFinder.php +++ b/system/src/Grav/Common/Config/ConfigFileFinder.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Config * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Config/Languages.php b/system/src/Grav/Common/Config/Languages.php index 4a863a1..05798c5 100644 --- a/system/src/Grav/Common/Config/Languages.php +++ b/system/src/Grav/Common/Config/Languages.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Config * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Config/Setup.php b/system/src/Grav/Common/Config/Setup.php index 6ff7372..f8ce943 100644 --- a/system/src/Grav/Common/Config/Setup.php +++ b/system/src/Grav/Common/Config/Setup.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Config * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -401,7 +401,7 @@ class Setup extends Data } // Create security.yaml salt if it doesn't exist into existing configuration environment if possible. - $securityFile = basename(static::$securityFile); + $securityFile = Utils::basename(static::$securityFile); $securityFolder = substr(static::$securityFile, 0, -\strlen($securityFile)); $securityFolder = $locator->findResource($securityFolder, true) ?: $locator->findResource($securityFolder, true, true); $filename = "{$securityFolder}/{$securityFile}"; diff --git a/system/src/Grav/Common/Data/Blueprint.php b/system/src/Grav/Common/Data/Blueprint.php index 2878199..ef6aef5 100644 --- a/system/src/Grav/Common/Data/Blueprint.php +++ b/system/src/Grav/Common/Data/Blueprint.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Data * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -99,7 +99,7 @@ class Blueprint extends BlueprintForm */ public function getDefaultValue(string $name) { - $path = explode('.', $name) ?: []; + $path = explode('.', $name); $current = $this->getDefaults(); foreach ($path as $field) { @@ -293,15 +293,16 @@ class Blueprint extends BlueprintForm /** * Flatten data by using blueprints. * - * @param array $data - * @param bool $includeAll + * @param array $data Data to be flattened. + * @param bool $includeAll True if undefined properties should also be included. + * @param string $name Property which will be flattened, useful for flattening repeating data. * @return array */ - public function flattenData(array $data, bool $includeAll = false) + public function flattenData(array $data, bool $includeAll = false, string $name = '') { $this->initInternals(); - return $this->blueprintSchema->flattenData($data, $includeAll); + return $this->blueprintSchema->flattenData($data, $includeAll, $name); } diff --git a/system/src/Grav/Common/Data/BlueprintSchema.php b/system/src/Grav/Common/Data/BlueprintSchema.php index db5e6af..8cc6303 100644 --- a/system/src/Grav/Common/Data/BlueprintSchema.php +++ b/system/src/Grav/Common/Data/BlueprintSchema.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Data * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -115,23 +115,29 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface /** * Flatten data by using blueprints. * - * @param array $data Data to be flattened. - * @param bool $includeAll + * @param array $data Data to be flattened. + * @param bool $includeAll True if undefined properties should also be included. + * @param string $name Property which will be flattened, useful for flattening repeating data. * @return array */ - public function flattenData(array $data, bool $includeAll = false) + public function flattenData(array $data, bool $includeAll = false, string $name = '') { + $prefix = $name !== '' ? $name . '.' : ''; + $list = []; if ($includeAll) { - foreach ($this->items as $key => $rules) { + $items = $name !== '' ? $this->getProperty($name)['fields'] ?? [] : $this->items; + foreach ($items as $key => $rules) { $type = $rules['type'] ?? ''; if (!str_starts_with($type, '_') && !str_contains($key, '*')) { - $list[$key] = null; + $list[$prefix . $key] = null; } } } - return array_replace($list, $this->flattenArray($data, $this->nested, '')); + $nested = $this->getNestedRules($name); + + return array_replace($list, $this->flattenArray($data, $nested, $prefix)); } /** diff --git a/system/src/Grav/Common/Data/Blueprints.php b/system/src/Grav/Common/Data/Blueprints.php index abe153f..dfdd46f 100644 --- a/system/src/Grav/Common/Data/Blueprints.php +++ b/system/src/Grav/Common/Data/Blueprints.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Data * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Data/Data.php b/system/src/Grav/Common/Data/Data.php index 4de437d..0f09b2d 100644 --- a/system/src/Grav/Common/Data/Data.php +++ b/system/src/Grav/Common/Data/Data.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Data * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -335,6 +335,7 @@ class Data implements DataInterface, ArrayAccess, \Countable, JsonSerializable, /** * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->items; diff --git a/system/src/Grav/Common/Data/DataInterface.php b/system/src/Grav/Common/Data/DataInterface.php index b4452bb..a4bc214 100644 --- a/system/src/Grav/Common/Data/DataInterface.php +++ b/system/src/Grav/Common/Data/DataInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Data * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Data/Validation.php b/system/src/Grav/Common/Data/Validation.php index bfb4057..569ea51 100644 --- a/system/src/Grav/Common/Data/Validation.php +++ b/system/src/Grav/Common/Data/Validation.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Data * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -816,7 +816,7 @@ class Validation { $value = static::filterArray($value, $params, $field); - return Utils::arrayUnflattenDotNotation($value); + return is_array($value) ? Utils::arrayUnflattenDotNotation($value) : null; } /** diff --git a/system/src/Grav/Common/Data/ValidationException.php b/system/src/Grav/Common/Data/ValidationException.php index be6a674..9a3d900 100644 --- a/system/src/Grav/Common/Data/ValidationException.php +++ b/system/src/Grav/Common/Data/ValidationException.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Data * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Debugger.php b/system/src/Grav/Common/Debugger.php index b8143f6..e7b1624 100644 --- a/system/src/Grav/Common/Debugger.php +++ b/system/src/Grav/Common/Debugger.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -856,6 +856,10 @@ class Debugger $scope = 'grav'; } elseif (strpos($errfile, '/twig/') !== false) { $scope = 'twig'; + // TODO: remove when upgrading to Twig 2+ + if (str_contains($errstr, '#[\ReturnTypeWillChange]') || str_contains($errstr, 'Passing null to parameter')) { + return true; + } } elseif (stripos($errfile, '/yaml/') !== false) { $scope = 'yaml'; } elseif (strpos($errfile, '/vendor/') !== false) { diff --git a/system/src/Grav/Common/Errors/BareHandler.php b/system/src/Grav/Common/Errors/BareHandler.php index 206b57e..9093827 100644 --- a/system/src/Grav/Common/Errors/BareHandler.php +++ b/system/src/Grav/Common/Errors/BareHandler.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Errors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Errors/Errors.php b/system/src/Grav/Common/Errors/Errors.php index 3dc99c6..92f885b 100644 --- a/system/src/Grav/Common/Errors/Errors.php +++ b/system/src/Grav/Common/Errors/Errors.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Errors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Errors/SimplePageHandler.php b/system/src/Grav/Common/Errors/SimplePageHandler.php index 0118929..80c4f96 100644 --- a/system/src/Grav/Common/Errors/SimplePageHandler.php +++ b/system/src/Grav/Common/Errors/SimplePageHandler.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Errors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Errors/SystemFacade.php b/system/src/Grav/Common/Errors/SystemFacade.php index 8a7f1ce..edf2b53 100644 --- a/system/src/Grav/Common/Errors/SystemFacade.php +++ b/system/src/Grav/Common/Errors/SystemFacade.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Errors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/File/CompiledFile.php b/system/src/Grav/Common/File/CompiledFile.php index 66fa620..2228422 100644 --- a/system/src/Grav/Common/File/CompiledFile.php +++ b/system/src/Grav/Common/File/CompiledFile.php @@ -3,13 +3,14 @@ /** * @package Grav\Common\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Common\File; use Exception; +use Grav\Common\Utils; use RocketTheme\Toolbox\File\PhpFile; use RuntimeException; use Throwable; @@ -88,7 +89,7 @@ trait CompiledFile $this->content = $cache['data']; } } catch (Exception $e) { - throw new RuntimeException(sprintf('Failed to read %s: %s', basename($this->filename), $e->getMessage()), 500, $e); + throw new RuntimeException(sprintf('Failed to read %s: %s', Utils::basename($this->filename), $e->getMessage()), 500, $e); } return parent::content($var); diff --git a/system/src/Grav/Common/File/CompiledJsonFile.php b/system/src/Grav/Common/File/CompiledJsonFile.php index dae95ba..e8347bb 100644 --- a/system/src/Grav/Common/File/CompiledJsonFile.php +++ b/system/src/Grav/Common/File/CompiledJsonFile.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/File/CompiledMarkdownFile.php b/system/src/Grav/Common/File/CompiledMarkdownFile.php index 1107417..1083111 100644 --- a/system/src/Grav/Common/File/CompiledMarkdownFile.php +++ b/system/src/Grav/Common/File/CompiledMarkdownFile.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/File/CompiledYamlFile.php b/system/src/Grav/Common/File/CompiledYamlFile.php index 0fedeb7..0f0c64f 100644 --- a/system/src/Grav/Common/File/CompiledYamlFile.php +++ b/system/src/Grav/Common/File/CompiledYamlFile.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Filesystem/Archiver.php b/system/src/Grav/Common/Filesystem/Archiver.php index 090bc13..4c291a5 100644 --- a/system/src/Grav/Common/Filesystem/Archiver.php +++ b/system/src/Grav/Common/Filesystem/Archiver.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Filesystem * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php index ecbc6ce..8dac2e5 100644 --- a/system/src/Grav/Common/Filesystem/Folder.php +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Filesystem * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -513,7 +513,7 @@ abstract class Folder } $directories = glob($directory . '/*', GLOB_ONLYDIR); - return count($directories); + return $directories ? count($directories) : false; } /** @@ -530,7 +530,8 @@ abstract class Folder } // Go through all items in filesystem and recursively remove everything. - $files = array_diff(scandir($folder, SCANDIR_SORT_NONE), array('.', '..')); + $files = scandir($folder, SCANDIR_SORT_NONE); + $files = $files ? array_diff($files, ['.', '..']) : []; foreach ($files as $file) { $path = "{$folder}/{$file}"; is_dir($path) ? self::doDelete($path) : @unlink($path); diff --git a/system/src/Grav/Common/Filesystem/RecursiveDirectoryFilterIterator.php b/system/src/Grav/Common/Filesystem/RecursiveDirectoryFilterIterator.php index 0dac81c..75c19bc 100644 --- a/system/src/Grav/Common/Filesystem/RecursiveDirectoryFilterIterator.php +++ b/system/src/Grav/Common/Filesystem/RecursiveDirectoryFilterIterator.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Filesystem * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php b/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php index ded0259..12d6c6b 100644 --- a/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php +++ b/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Filesystem * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Filesystem/ZipArchiver.php b/system/src/Grav/Common/Filesystem/ZipArchiver.php index 6e53e70..4f2a9ee 100644 --- a/system/src/Grav/Common/Filesystem/ZipArchiver.php +++ b/system/src/Grav/Common/Filesystem/ZipArchiver.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Filesystem * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/FlexCollection.php b/system/src/Grav/Common/Flex/FlexCollection.php index 6429c9e..704e21f 100644 --- a/system/src/Grav/Common/Flex/FlexCollection.php +++ b/system/src/Grav/Common/Flex/FlexCollection.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/FlexIndex.php b/system/src/Grav/Common/Flex/FlexIndex.php index 44b6fdd..f903c88 100644 --- a/system/src/Grav/Common/Flex/FlexIndex.php +++ b/system/src/Grav/Common/Flex/FlexIndex.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/FlexObject.php b/system/src/Grav/Common/Flex/FlexObject.php index b64aea1..887d7a3 100644 --- a/system/src/Grav/Common/Flex/FlexObject.php +++ b/system/src/Grav/Common/Flex/FlexObject.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Traits/FlexCollectionTrait.php b/system/src/Grav/Common/Flex/Traits/FlexCollectionTrait.php index 29b640e..b919b40 100644 --- a/system/src/Grav/Common/Flex/Traits/FlexCollectionTrait.php +++ b/system/src/Grav/Common/Flex/Traits/FlexCollectionTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Traits/FlexCommonTrait.php b/system/src/Grav/Common/Flex/Traits/FlexCommonTrait.php index 1077e00..9291a42 100644 --- a/system/src/Grav/Common/Flex/Traits/FlexCommonTrait.php +++ b/system/src/Grav/Common/Flex/Traits/FlexCommonTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Traits/FlexGravTrait.php b/system/src/Grav/Common/Flex/Traits/FlexGravTrait.php index 9d5c9e0..c34b89d 100644 --- a/system/src/Grav/Common/Flex/Traits/FlexGravTrait.php +++ b/system/src/Grav/Common/Flex/Traits/FlexGravTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Traits/FlexIndexTrait.php b/system/src/Grav/Common/Flex/Traits/FlexIndexTrait.php index 1d0ee5c..a71eb99 100644 --- a/system/src/Grav/Common/Flex/Traits/FlexIndexTrait.php +++ b/system/src/Grav/Common/Flex/Traits/FlexIndexTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Traits/FlexObjectTrait.php b/system/src/Grav/Common/Flex/Traits/FlexObjectTrait.php index 1175a3b..3c81f07 100644 --- a/system/src/Grav/Common/Flex/Traits/FlexObjectTrait.php +++ b/system/src/Grav/Common/Flex/Traits/FlexObjectTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/Generic/GenericCollection.php b/system/src/Grav/Common/Flex/Types/Generic/GenericCollection.php index 6b2fbc1..e4ec3d4 100644 --- a/system/src/Grav/Common/Flex/Types/Generic/GenericCollection.php +++ b/system/src/Grav/Common/Flex/Types/Generic/GenericCollection.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/Generic/GenericIndex.php b/system/src/Grav/Common/Flex/Types/Generic/GenericIndex.php index 81dbf95..fdba503 100644 --- a/system/src/Grav/Common/Flex/Types/Generic/GenericIndex.php +++ b/system/src/Grav/Common/Flex/Types/Generic/GenericIndex.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/Generic/GenericObject.php b/system/src/Grav/Common/Flex/Types/Generic/GenericObject.php index 4a56752..eba642b 100644 --- a/system/src/Grav/Common/Flex/Types/Generic/GenericObject.php +++ b/system/src/Grav/Common/Flex/Types/Generic/GenericObject.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/Pages/PageCollection.php b/system/src/Grav/Common/Flex/Types/Pages/PageCollection.php index 7503653..b6c5230 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/PageCollection.php +++ b/system/src/Grav/Common/Flex/Types/Pages/PageCollection.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -34,7 +34,9 @@ use function is_string; * Class GravPageCollection * @package Grav\Plugin\FlexObjects\Types\GravPages * - * @extends FlexPageCollection + * @template T as PageObject + * @extends FlexPageCollection + * @implements PageCollectionInterface * * Incompatibilities with Grav\Common\Page\Collection: * $page = $collection->key() will not work at all @@ -46,10 +48,6 @@ use function is_string; * $collection->prev() does not rewind the internal pointer * AND most methods are immutable; they do not update the current collection, but return updated one * - * @method static shuffle() - * @method static select(array $keys) - * @method static unselect(array $keys) - * @method static createFrom(array $elements, string $keyField = null) * @method PageIndex getIndex() */ class PageCollection extends FlexPageCollection implements PageCollectionInterface @@ -108,13 +106,11 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa } /** - * @return PageObject + * @return PageInterface */ public function getRoot() { - $index = $this->getIndex(); - - return $index->getRoot(); + return $this->getIndex()->getRoot(); } /** @@ -154,7 +150,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Add a single page to a collection * * @param PageInterface $page - * @return static + * @return $this */ public function addPage(PageInterface $page) { @@ -174,6 +170,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * * @param PageCollectionInterface $collection * @return static + * @phpstan-return static */ public function merge(PageCollectionInterface $collection) { @@ -185,6 +182,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * * @param PageCollectionInterface $collection * @return static + * @phpstan-return static */ public function intersect(PageCollectionInterface $collection) { @@ -203,7 +201,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Return previous item. * * @return PageInterface|false - * @phpstan-return PageObject|false + * @phpstan-return T|false */ public function prev() { @@ -218,7 +216,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Return nth item. * @param int $key * @return PageInterface|bool - * @phpstan-return PageObject|false + * @phpstan-return T|false */ public function nth($key) { @@ -230,6 +228,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * * @param int $num Specifies how many entries should be picked. * @return static + * @phpstan-return static */ public function random($num = 1) { @@ -241,6 +240,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * * @param array $items Items to be appended. Existing keys will be overridden with the new values. * @return static + * @phpstan-return static */ public function append($items) { @@ -252,6 +252,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * * @param int $size * @return static[] + * @phpstan-return static[] */ public function batch($size): array { @@ -273,6 +274,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * @param array|null $manual * @param int|null $sort_flags * @return static + * @phpstan-return static */ public function order($by, $dir = 'asc', $manual = null, $sort_flags = null) { @@ -333,7 +335,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa $list[$key] = $child->slug(); break; case 'basename': - $list[$key] = basename($key); + $list[$key] = Utils::basename($key); break; case 'folder': $list[$key] = $child->folder(); @@ -441,6 +443,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * @param string|null $endDate * @param string|null $field * @return static + * @phpstan-return static * @throws Exception */ public function dateRange($startDate = null, $endDate = null, $field = null) @@ -468,6 +471,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Creates new collection with only visible pages * * @return static The collection with only visible pages + * @phpstan-return static */ public function visible() { @@ -485,6 +489,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Creates new collection with only non-visible pages * * @return static The collection with only non-visible pages + * @phpstan-return static */ public function nonVisible() { @@ -502,6 +507,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Creates new collection with only pages * * @return static The collection with only pages + * @phpstan-return static */ public function pages() { @@ -523,6 +529,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Creates new collection with only modules * * @return static The collection with only modules + * @phpstan-return static */ public function modules() { @@ -544,6 +551,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Alias of modules() * * @return static + * @phpstan-return static */ public function modular() { @@ -554,6 +562,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Alias of pages() * * @return static + * @phpstan-return static */ public function nonModular() { @@ -564,6 +573,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Creates new collection with only published pages * * @return static The collection with only published pages + * @phpstan-return static */ public function published() { @@ -581,6 +591,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Creates new collection with only non-published pages * * @return static The collection with only non-published pages + * @phpstan-return static */ public function nonPublished() { @@ -598,6 +609,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Creates new collection with only routable pages * * @return static The collection with only routable pages + * @phpstan-return static */ public function routable() { @@ -615,6 +627,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * Creates new collection with only non-routable pages * * @return static The collection with only non-routable pages + * @phpstan-return static */ public function nonRoutable() { @@ -633,6 +646,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * * @param string $type * @return static The collection + * @phpstan-return static */ public function ofType($type) { @@ -651,6 +665,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * * @param string[] $types * @return static The collection + * @phpstan-return static */ public function ofOneOfTheseTypes($types) { @@ -669,6 +684,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * * @param array $accessLevels * @return static The collection + * @phpstan-return static */ public function ofOneOfTheseAccessLevels($accessLevels) { @@ -710,6 +726,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa /** * @param bool $bool * @return static + * @phpstan-return static */ public function withOrdered(bool $bool = true) { @@ -721,6 +738,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa /** * @param bool $bool * @return static + * @phpstan-return static */ public function withModules(bool $bool = true) { @@ -732,6 +750,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa /** * @param bool $bool * @return static + * @phpstan-return static */ public function withPages(bool $bool = true) { @@ -745,6 +764,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * @param string|null $languageCode * @param bool|null $fallback * @return static + * @phpstan-return static */ public function withTranslation(bool $bool = true, string $languageCode = null, bool $fallback = null) { @@ -778,6 +798,7 @@ class PageCollection extends FlexPageCollection implements PageCollectionInterfa * @param array $filters * @param bool $recursive * @return static + * @phpstan-return static */ public function filterBy(array $filters, bool $recursive = false) { diff --git a/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php b/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php index 5a7d773..f3978bc 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php +++ b/system/src/Grav/Common/Flex/Types/Pages/PageIndex.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -39,7 +39,10 @@ use function is_string; * Class GravPageObject * @package Grav\Plugin\FlexObjects\Types\GravPages * - * @extends FlexPageIndex + * @template T of PageObject + * @template C of PageCollection + * @extends FlexPageIndex + * @implements PageCollectionInterface * * @method PageIndex withModules(bool $bool = true) * @method PageIndex withPages(bool $bool = true) @@ -101,6 +104,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface /** * @param string $key * @return PageObject|null + * @phpstan-return T|null */ public function get($key) { @@ -117,11 +121,13 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface $element = $element->getTranslation(ltrim($params, '.')); } + \assert(null === $element || $element instanceof PageObject); + return $element; } /** - * @return PageObject + * @return PageInterface */ public function getRoot() { @@ -172,7 +178,8 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface /** * @param string|null $languageCode * @param bool|null $fallback - * @return PageIndex + * @return static + * @phpstan-return static */ public function withTranslated(string $languageCode = null, bool $fallback = null) { @@ -276,6 +283,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * @param array $filters * @param bool $recursive * @return static + * @phpstan-return static */ public function filterBy(array $filters, bool $recursive = false) { @@ -332,6 +340,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface /** * @param array $filters * @return static + * @phpstan-return static */ protected function filterByParent(array $filters) { @@ -402,6 +411,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * @param array $entries * @param string|null $keyField * @return static + * @phpstan-return static */ protected function createFrom(array $entries, string $keyField = null) { @@ -596,8 +606,10 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface } } + /** @var PageCollection|PageIndex $children */ + $children = $page->children(); /** @var PageIndex $children */ - $children = $page->children()->getIndex(); + $children = $children->getIndex(); $selectedChildren = $children->filterBy($filters, true); /** @var Header $header */ @@ -627,7 +639,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface $payload = [ 'name' => $child->menu(), 'value' => $child->rawRoute(), - 'item-key' => basename($child->rawRoute() ?? ''), + 'item-key' => Utils::basename($child->rawRoute() ?? ''), 'filename' => $child->folder(), 'extension' => $child->extension(), 'type' => 'dir', @@ -676,13 +688,15 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface $extras = array_filter($extras, static function ($v) { return $v !== null; }); + + /** @var PageIndex $tmp */ $tmp = $child->children()->getIndex(); $child_count = $tmp->count(); $count = $filters ? $tmp->filterBy($filters, true)->count() : null; $route = $child->getRoute(); $route = $route ? ($route->toString(false) ?: '/') : ''; $payload = [ - 'item-key' => htmlspecialchars(basename($child->rawRoute() ?? $child->getKey())), + 'item-key' => htmlspecialchars(Utils::basename($child->rawRoute() ?? $child->getKey())), 'icon' => $icon, 'title' => htmlspecialchars($child->menu()), 'route' => [ @@ -787,6 +801,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * * @param PageInterface $page * @return PageCollection + * @phpstan-return C */ public function addPage(PageInterface $page) { @@ -798,6 +813,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Create a copy of this collection * * @return static + * @phpstan-return static */ public function copy() { @@ -810,6 +826,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * * @param PageCollectionInterface $collection * @return PageCollection + * @phpstan-return C */ public function merge(PageCollectionInterface $collection) { @@ -822,6 +839,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * * @param PageCollectionInterface $collection * @return PageCollection + * @phpstan-return C */ public function intersect(PageCollectionInterface $collection) { @@ -833,6 +851,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * * @param int $size * @return PageCollection[] + * @phpstan-return C[] */ public function batch($size) { @@ -844,6 +863,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * * @param string $key * @return PageObject|null + * @phpstan-return T|null * @throws InvalidArgumentException */ public function remove($key) @@ -859,6 +879,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * @param array $manual * @param string $sort_flags * @return static + * @phpstan-return static */ public function order($by, $dir = 'asc', $manual = null, $sort_flags = null) { @@ -902,6 +923,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * * @param string $path * @return PageObject|null The previous item. + * @phpstan-return T|null */ public function prevSibling($path) { @@ -916,6 +938,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * * @param string $path * @return PageObject|null The next item. + * @phpstan-return T|null */ public function nextSibling($path) { @@ -931,6 +954,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * @param string $path * @param int $direction either -1 or +1 * @return PageObject|false The sibling item. + * @phpstan-return T|false */ public function adjacentSibling($path, $direction = 1) { @@ -964,6 +988,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * @param string|null $endDate * @param string|null $field * @return static + * @phpstan-return static * @throws Exception */ public function dateRange($startDate = null, $endDate = null, $field = null) @@ -988,6 +1013,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Creates new collection with only visible pages * * @return static The collection with only visible pages + * @phpstan-return static */ public function visible() { @@ -1000,6 +1026,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Creates new collection with only non-visible pages * * @return static The collection with only non-visible pages + * @phpstan-return static */ public function nonVisible() { @@ -1012,6 +1039,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Creates new collection with only non-modular pages * * @return static The collection with only non-modular pages + * @phpstan-return static */ public function pages() { @@ -1024,6 +1052,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Creates new collection with only modular pages * * @return static The collection with only modular pages + * @phpstan-return static */ public function modules() { @@ -1036,6 +1065,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Creates new collection with only modular pages * * @return static The collection with only modular pages + * @phpstan-return static */ public function modular() { @@ -1046,6 +1076,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Creates new collection with only non-modular pages * * @return static The collection with only non-modular pages + * @phpstan-return static */ public function nonModular() { @@ -1056,6 +1087,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Creates new collection with only published pages * * @return static The collection with only published pages + * @phpstan-return static */ public function published() { @@ -1068,6 +1100,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Creates new collection with only non-published pages * * @return static The collection with only non-published pages + * @phpstan-return static */ public function nonPublished() { @@ -1080,6 +1113,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Creates new collection with only routable pages * * @return static The collection with only routable pages + * @phpstan-return static */ public function routable() { @@ -1092,6 +1126,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * Creates new collection with only non-routable pages * * @return static The collection with only non-routable pages + * @phpstan-return static */ public function nonRoutable() { @@ -1105,6 +1140,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * * @param string $type * @return static The collection + * @phpstan-return static */ public function ofType($type) { @@ -1118,6 +1154,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * * @param string[] $types * @return static The collection + * @phpstan-return static */ public function ofOneOfTheseTypes($types) { @@ -1131,6 +1168,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface * * @param array $accessLevels * @return static The collection + * @phpstan-return static */ public function ofOneOfTheseAccessLevels($accessLevels) { diff --git a/system/src/Grav/Common/Flex/Types/Pages/PageObject.php b/system/src/Grav/Common/Flex/Types/Pages/PageObject.php index 4c83f95..a05f0eb 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/PageObject.php +++ b/system/src/Grav/Common/Flex/Types/Pages/PageObject.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -25,9 +25,9 @@ use Grav\Common\Page\Pages; use Grav\Common\User\Interfaces\UserInterface; use Grav\Common\Utils; use Grav\Framework\Filesystem\Filesystem; -use Grav\Framework\Flex\FlexObject; use Grav\Framework\Flex\Interfaces\FlexObjectInterface; use Grav\Framework\Flex\Pages\FlexPageObject; +use Grav\Framework\Object\ObjectCollection; use Grav\Framework\Route\Route; use Grav\Framework\Route\RouteFactory; use Grav\Plugin\Admin\Admin; @@ -93,11 +93,6 @@ class PageObject extends FlexPageObject } } - public function translated(): bool - { - return $this->translatedLanguages(true) ? true : false; - } - /** * @param string|array $query * @return Route|null @@ -282,7 +277,7 @@ class PageObject extends FlexPageObject /** * @param array|bool $reorder - * @return FlexObject|FlexObjectInterface + * @return static */ public function save($reorder = true) { @@ -317,7 +312,7 @@ class PageObject extends FlexPageObject } /** - * @return PageObject + * @return static */ public function delete() { @@ -391,6 +386,7 @@ class PageObject extends FlexPageObject /** * @param array $ordering * @return PageCollection|null + * @phpstan-return ObjectCollection|null */ protected function reorderSiblings(array $ordering) { @@ -466,7 +462,9 @@ class PageObject extends FlexPageObject if ($isMoved && $this->order() !== false) { $parentKey = $this->getProperty('parent_key'); if ($parentKey === '') { - $newParent = $this->getFlexDirectory()->getIndex()->getRoot(); + /** @var PageIndex $index */ + $index = $this->getFlexDirectory()->getIndex(); + $newParent = $index->getRoot(); } else { $newParent = $this->getFlexDirectory()->getObject($parentKey, 'storage_key'); if (!$newParent instanceof PageInterface) { @@ -627,7 +625,14 @@ class PageObject extends FlexPageObject // If current filter does not match, we still may have match as a parent. if ($matches === false) { - return $recursive && $this->children()->getIndex()->filterBy($filters, true)->count() > 0; + if (!$recursive) { + return false; + } + + /** @var PageIndex $index */ + $index = $this->children()->getIndex(); + + return $index->filterBy($filters, true)->count() > 0; } } diff --git a/system/src/Grav/Common/Flex/Types/Pages/Storage/PageStorage.php b/system/src/Grav/Common/Flex/Types/Pages/Storage/PageStorage.php index ba7fa06..f590e36 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/Storage/PageStorage.php +++ b/system/src/Grav/Common/Flex/Types/Pages/Storage/PageStorage.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -16,13 +16,13 @@ use Grav\Common\Debugger; use Grav\Common\Flex\Types\Pages\PageIndex; use Grav\Common\Grav; use Grav\Common\Language\Language; +use Grav\Common\Utils; use Grav\Framework\Filesystem\Filesystem; use Grav\Framework\Flex\Storage\FolderStorage; use RocketTheme\Toolbox\File\MarkdownFile; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use RuntimeException; use SplFileInfo; -use function assert; use function in_array; use function is_string; @@ -277,7 +277,7 @@ class PageStorage extends FolderStorage } else { $params = $template = $language = ''; } - $objectKey = basename($key); + $objectKey = Utils::basename($key); if (preg_match('|^(\d+)\.(.+)$|', $objectKey, $matches)) { [, $order, $folder] = $matches; } else { @@ -584,7 +584,7 @@ class PageStorage extends FolderStorage $mark = $matches[2] ?? ''; $ext = $matches[1] ?? ''; $ext .= $this->dataExt; - $markdown[$mark][basename($k, $ext)] = $timestamp; + $markdown[$mark][Utils::basename($k, $ext)] = $timestamp; } $modified = max($modified, $timestamp); @@ -675,7 +675,7 @@ class PageStorage extends FolderStorage /** @phpstan-var array{'storage_key': string, 'storage_timestamp': int, 'children': array} $parent */ $parent = &$list[$parentKey]; - $basename = basename($storage_key); + $basename = Utils::basename($storage_key); if (isset($parent['children'][$basename])) { $timestamp = $meta['storage_timestamp']; diff --git a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageContentTrait.php b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageContentTrait.php index 1bde7b0..9a2c7c3 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageContentTrait.php +++ b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageContentTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageLegacyTrait.php b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageLegacyTrait.php index 589ea88..98f3949 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageLegacyTrait.php +++ b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageLegacyTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageRoutableTrait.php b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageRoutableTrait.php index 3b490a5..ace74dc 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageRoutableTrait.php +++ b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageRoutableTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageTranslateTrait.php b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageTranslateTrait.php index dff42c9..a30ae1a 100644 --- a/system/src/Grav/Common/Flex/Types/Pages/Traits/PageTranslateTrait.php +++ b/system/src/Grav/Common/Flex/Types/Pages/Traits/PageTranslateTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupCollection.php b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupCollection.php index 93abbf8..3a91d77 100644 --- a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupCollection.php +++ b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupCollection.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -27,7 +27,7 @@ class UserGroupCollection extends FlexCollection public static function getCachedMethods(): array { return [ - 'authorize' => 'session', + 'authorize' => false, ] + parent::getCachedMethods(); } diff --git a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupIndex.php b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupIndex.php index 4bee5ac..66de52e 100644 --- a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupIndex.php +++ b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupIndex.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php index ea68fa1..4a59d52 100644 --- a/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php +++ b/system/src/Grav/Common/Flex/Types/UserGroups/UserGroupObject.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -37,7 +37,7 @@ class UserGroupObject extends FlexObject implements UserGroupInterface public static function getCachedMethods(): array { return [ - 'authorize' => 'session', + 'authorize' => false, ] + parent::getCachedMethods(); } diff --git a/system/src/Grav/Common/Flex/Types/Users/Storage/UserFileStorage.php b/system/src/Grav/Common/Flex/Types/Users/Storage/UserFileStorage.php index f565c9f..664f24f 100644 --- a/system/src/Grav/Common/Flex/Types/Users/Storage/UserFileStorage.php +++ b/system/src/Grav/Common/Flex/Types/Users/Storage/UserFileStorage.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/Users/Storage/UserFolderStorage.php b/system/src/Grav/Common/Flex/Types/Users/Storage/UserFolderStorage.php index 7d9924e..a037f0e 100644 --- a/system/src/Grav/Common/Flex/Types/Users/Storage/UserFolderStorage.php +++ b/system/src/Grav/Common/Flex/Types/Users/Storage/UserFolderStorage.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/Users/Traits/UserObjectLegacyTrait.php b/system/src/Grav/Common/Flex/Types/Users/Traits/UserObjectLegacyTrait.php index b0fc0c4..07acf66 100644 --- a/system/src/Grav/Common/Flex/Types/Users/Traits/UserObjectLegacyTrait.php +++ b/system/src/Grav/Common/Flex/Types/Users/Traits/UserObjectLegacyTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -84,6 +84,7 @@ trait UserObjectLegacyTrait * @return int * @deprecated 1.6 Method makes no sense for user account. */ + #[\ReturnTypeWillChange] public function count() { user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED); diff --git a/system/src/Grav/Common/Flex/Types/Users/UserCollection.php b/system/src/Grav/Common/Flex/Types/Users/UserCollection.php index 9b6490a..f5641e7 100644 --- a/system/src/Grav/Common/Flex/Types/Users/UserCollection.php +++ b/system/src/Grav/Common/Flex/Types/Users/UserCollection.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Flex/Types/Users/UserIndex.php b/system/src/Grav/Common/Flex/Types/Users/UserIndex.php index 6e0bc65..4a33b73 100644 --- a/system/src/Grav/Common/Flex/Types/Users/UserIndex.php +++ b/system/src/Grav/Common/Flex/Types/Users/UserIndex.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -164,7 +164,7 @@ class UserIndex extends FlexIndex implements UserCollectionInterface */ protected static function filterUsername(string $key, FlexStorageInterface $storage): string { - return $storage->normalizeKey($key); + return method_exists($storage, 'normalizeKey') ? $storage->normalizeKey($key) : $key; } /** diff --git a/system/src/Grav/Common/Flex/Types/Users/UserObject.php b/system/src/Grav/Common/Flex/Types/Users/UserObject.php index 424e5eb..9dec972 100644 --- a/system/src/Grav/Common/Flex/Types/Users/UserObject.php +++ b/system/src/Grav/Common/Flex/Types/Users/UserObject.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -30,6 +30,7 @@ use Grav\Common\Flex\Types\UserGroups\UserGroupCollection; use Grav\Common\Flex\Types\UserGroups\UserGroupIndex; use Grav\Common\User\Interfaces\UserInterface; use Grav\Common\User\Traits\UserTrait; +use Grav\Common\Utils; use Grav\Framework\File\Formatter\JsonFormatter; use Grav\Framework\File\Formatter\YamlFormatter; use Grav\Framework\Filesystem\Filesystem; @@ -79,6 +80,8 @@ class UserObject extends FlexObject implements UserInterface, Countable /** @var Closure|null */ static public $authorizeCallable; + /** @var Closure|null */ + static public $isAuthorizedCallable; /** @var array|null */ protected $_uploads_original; @@ -123,7 +126,8 @@ class UserObject extends FlexObject implements UserInterface, Countable // Define username if it's not set. if (!isset($elements['username'])) { $storageKey = $elements['__META']['storage_key'] ?? null; - if (null !== $storageKey && $key === $directory->getStorage()->normalizeKey($storageKey)) { + $storage = $directory->getStorage(); + if (null !== $storageKey && method_exists($storage, 'normalizeKey') && $key === $storage->normalizeKey($storageKey)) { $elements['username'] = $storageKey; } else { $elements['username'] = $key; @@ -138,6 +142,14 @@ class UserObject extends FlexObject implements UserInterface, Countable parent::__construct($elements, $key, $directory, $validate); } + public function __clone() + { + $this->_access = null; + $this->_groups = null; + + parent::__clone(); + } + /** * @return void */ @@ -231,13 +243,19 @@ class UserObject extends FlexObject implements UserInterface, Countable } /** + * @param UserInterface|null $user * @return bool */ - public function isMyself(): bool + public function isMyself(?UserInterface $user = null): bool { - $me = $this->getActiveUser(); + if (null === $user) { + $user = $this->getActiveUser(); + if ($user && !$user->authenticated) { + $user = null; + } + } - return $me && $me->authenticated && $this->username === $me->username; + return $user && $this->username === $user->username; } /** @@ -277,8 +295,8 @@ class UserObject extends FlexObject implements UserInterface, Countable // Check custom application access. $authorizeCallable = static::$authorizeCallable; if ($authorizeCallable instanceof Closure) { - $authorizeCallable->bindTo($this); - $authorized = $authorizeCallable($action, $scope); + $callable = $authorizeCallable->bindTo($this, $this); + $authorized = $callable($action, $scope); if (is_bool($authorized)) { return $authorized; } @@ -628,7 +646,7 @@ class UserObject extends FlexObject implements UserInterface, Countable $medium = MediumFactory::fromFile($path); if ($medium) { $media->add($path, $medium); - $name = basename($path); + $name = Utils::basename($path); if ($name !== $path) { $media->add($name, $medium); } @@ -648,7 +666,7 @@ class UserObject extends FlexObject implements UserInterface, Countable // Check for shared media if (!$folder && !$this->getFlexDirectory()->getMediaFolder()) { $this->_loadMedia = false; - $folder = $this->getBlueprint()->fields()['avatar']['destination'] ?? 'user://accounts/avatars'; + $folder = $this->getBlueprint()->fields()['avatar']['destination'] ?? 'account://avatars'; } return $folder; @@ -683,6 +701,16 @@ class UserObject extends FlexObject implements UserInterface, Countable */ protected function isAuthorizedOverride(UserInterface $user, string $action, string $scope, bool $isMe = false): ?bool { + // Check custom application access. + $isAuthorizedCallable = static::$isAuthorizedCallable; + if ($isAuthorizedCallable instanceof Closure) { + $callable = $isAuthorizedCallable->bindTo($this, $this); + $authorized = $callable($user, $action, $scope, $isMe); + if (is_bool($authorized)) { + return $authorized; + } + } + if ($user instanceof self && $user->getStorageKey() === $this->getStorageKey()) { // User cannot delete his own account, otherwise he has full access. return $action !== 'delete'; @@ -787,7 +815,7 @@ class UserObject extends FlexObject implements UserInterface, Countable } // Calculate path without the retina scaling factor. - $realpath = $filesystem->pathname($filepath) . str_replace(['@3x', '@2x'], '', basename($filepath)); + $realpath = $filesystem->pathname($filepath) . str_replace(['@3x', '@2x'], '', Utils::basename($filepath)); $list[$filename] = [$file, $settings]; @@ -898,7 +926,9 @@ class UserObject extends FlexObject implements UserInterface, Countable protected function getGroups() { if (null === $this->_groups) { - $this->_groups = $this->getUserGroups()->select((array)$this->getProperty('groups')); + /** @var UserGroupIndex $groups */ + $groups = $this->getUserGroups()->select((array)$this->getProperty('groups')); + $this->_groups = $groups; } return $this->_groups; @@ -910,7 +940,7 @@ class UserObject extends FlexObject implements UserInterface, Countable protected function getAccess(): Access { if (null === $this->_access) { - $this->getProperty('access'); + $this->_access = new Access($this->getProperty('access')); } return $this->_access; @@ -926,8 +956,6 @@ class UserObject extends FlexObject implements UserInterface, Countable $value = new Access($value); } - $this->_access = $value; - return $value->jsonSerialize(); } diff --git a/system/src/Grav/Common/Form/FormFlash.php b/system/src/Grav/Common/Form/FormFlash.php index 430f15e..7acaf7f 100644 --- a/system/src/Grav/Common/Form/FormFlash.php +++ b/system/src/Grav/Common/Form/FormFlash.php @@ -3,13 +3,14 @@ /** * @package Grav\Common\Form * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Common\Form; use Grav\Common\Filesystem\Folder; +use Grav\Common\Utils; use Grav\Framework\Form\FormFlash as FrameworkFormFlash; use function is_array; @@ -58,7 +59,7 @@ class FormFlash extends FrameworkFormFlash Folder::create($tmp_dir); $tmp_file = $upload['file']['tmp_name']; - $basename = basename($tmp_file); + $basename = Utils::basename($tmp_file); if (!move_uploaded_file($tmp_file, $tmp_dir . '/' . $basename)) { return false; @@ -90,7 +91,7 @@ class FormFlash extends FrameworkFormFlash Folder::create($tmp_dir); $tmp_file = $upload['file']['tmp_name']; - $basename = basename($tmp_file); + $basename = Utils::basename($tmp_file); if (!move_uploaded_file($tmp_file, $tmp_dir . '/' . $basename)) { return false; diff --git a/system/src/Grav/Common/GPM/AbstractCollection.php b/system/src/Grav/Common/GPM/AbstractCollection.php index b5b867e..91fa69e 100644 --- a/system/src/Grav/Common/GPM/AbstractCollection.php +++ b/system/src/Grav/Common/GPM/AbstractCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Common/AbstractPackageCollection.php b/system/src/Grav/Common/GPM/Common/AbstractPackageCollection.php index 5d6ad9f..7b918e0 100644 --- a/system/src/Grav/Common/GPM/Common/AbstractPackageCollection.php +++ b/system/src/Grav/Common/GPM/Common/AbstractPackageCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Common/CachedCollection.php b/system/src/Grav/Common/GPM/Common/CachedCollection.php index 172ba93..c3b62e5 100644 --- a/system/src/Grav/Common/GPM/Common/CachedCollection.php +++ b/system/src/Grav/Common/GPM/Common/CachedCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Common/Package.php b/system/src/Grav/Common/GPM/Common/Package.php index e06ebb6..5d96011 100644 --- a/system/src/Grav/Common/GPM/Common/Package.php +++ b/system/src/Grav/Common/GPM/Common/Package.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -45,6 +45,7 @@ class Package * @param string $key * @return mixed */ + #[\ReturnTypeWillChange] public function __get($key) { return $this->data->get($key); @@ -55,6 +56,7 @@ class Package * @param mixed $value * @return void */ + #[\ReturnTypeWillChange] public function __set($key, $value) { $this->data->set($key, $value); @@ -64,6 +66,7 @@ class Package * @param string $key * @return bool */ + #[\ReturnTypeWillChange] public function __isset($key) { return isset($this->data->{$key}); @@ -72,6 +75,7 @@ class Package /** * @return string */ + #[\ReturnTypeWillChange] public function __toString() { return $this->toJson(); diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php index 4505696..7031945 100644 --- a/system/src/Grav/Common/GPM/GPM.php +++ b/system/src/Grav/Common/GPM/GPM.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -74,6 +74,7 @@ class GPM extends Iterator * @param string $offset Asset name value * @return mixed Asset value */ + #[\ReturnTypeWillChange] public function __get($offset) { switch ($offset) { @@ -90,6 +91,7 @@ class GPM extends Iterator * @param string $offset Asset name value * @return bool True if the value is set */ + #[\ReturnTypeWillChange] public function __isset($offset) { switch ($offset) { @@ -629,7 +631,7 @@ class GPM extends Iterator throw new \RuntimeException("Malformed GPM URL: {$package_file}"); } - $filename = basename($package['path'] ?? ''); + $filename = Utils::basename($package['path'] ?? ''); if (Grav::instance()['config']->get('system.gpm.official_gpm_only') && ($package['host'] ?? null) !== 'getgrav.org') { throw new RuntimeException('Only official GPM URLs are allowed. You can modify this behavior in the System configuration.'); @@ -658,7 +660,7 @@ class GPM extends Iterator $package_file = realpath($package_file); if ($package_file && file_exists($package_file)) { - $filename = basename($package_file); + $filename = Utils::basename($package_file); Folder::create($tmp); copy($package_file, $tmp . DS . $filename); return $tmp . DS . $filename; @@ -690,7 +692,7 @@ class GPM extends Iterator } // either theme or plugin - $name = basename($source); + $name = Utils::basename($source); if (Utils::contains($name, 'theme')) { return 'theme'; } @@ -728,7 +730,7 @@ class GPM extends Iterator $glob = glob($source . '*.yaml') ?: []; foreach ($glob as $filename) { - $name = strtolower(basename($filename, '.yaml')); + $name = strtolower(Utils::basename($filename, '.yaml')); if (in_array($name, $ignore_yaml_files)) { continue; } diff --git a/system/src/Grav/Common/GPM/Installer.php b/system/src/Grav/Common/GPM/Installer.php index 639240b..8a1a530 100644 --- a/system/src/Grav/Common/GPM/Installer.php +++ b/system/src/Grav/Common/GPM/Installer.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -12,6 +12,7 @@ namespace Grav\Common\GPM; use DirectoryIterator; use Grav\Common\Filesystem\Folder; use Grav\Common\Grav; +use Grav\Common\Utils; use RuntimeException; use ZipArchive; use function count; @@ -192,7 +193,7 @@ class Installer $package_folder_name = $zip->getNameIndex(0); if ($package_folder_name === false) { - throw new \RuntimeException('Bad package file: ' . basename($zip_file)); + throw new \RuntimeException('Bad package file: ' . Utils::basename($zip_file)); } $package_folder_name = preg_replace('#\./$#', '', $package_folder_name); $zip->close(); diff --git a/system/src/Grav/Common/GPM/Licenses.php b/system/src/Grav/Common/GPM/Licenses.php index 825343d..e932bd4 100644 --- a/system/src/Grav/Common/GPM/Licenses.php +++ b/system/src/Grav/Common/GPM/Licenses.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Local/AbstractPackageCollection.php b/system/src/Grav/Common/GPM/Local/AbstractPackageCollection.php index d1f3e46..bc7ceab 100644 --- a/system/src/Grav/Common/GPM/Local/AbstractPackageCollection.php +++ b/system/src/Grav/Common/GPM/Local/AbstractPackageCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Local/Package.php b/system/src/Grav/Common/GPM/Local/Package.php index ffe2c63..08444a7 100644 --- a/system/src/Grav/Common/GPM/Local/Package.php +++ b/system/src/Grav/Common/GPM/Local/Package.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Local/Packages.php b/system/src/Grav/Common/GPM/Local/Packages.php index 0290296..b63b93b 100644 --- a/system/src/Grav/Common/GPM/Local/Packages.php +++ b/system/src/Grav/Common/GPM/Local/Packages.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Local/Plugins.php b/system/src/Grav/Common/GPM/Local/Plugins.php index 8a6574b..a1626f8 100644 --- a/system/src/Grav/Common/GPM/Local/Plugins.php +++ b/system/src/Grav/Common/GPM/Local/Plugins.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Local/Themes.php b/system/src/Grav/Common/GPM/Local/Themes.php index 73253cc..d153794 100644 --- a/system/src/Grav/Common/GPM/Local/Themes.php +++ b/system/src/Grav/Common/GPM/Local/Themes.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Remote/AbstractPackageCollection.php b/system/src/Grav/Common/GPM/Remote/AbstractPackageCollection.php index 9e68d66..02e98e7 100644 --- a/system/src/Grav/Common/GPM/Remote/AbstractPackageCollection.php +++ b/system/src/Grav/Common/GPM/Remote/AbstractPackageCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Remote/GravCore.php b/system/src/Grav/Common/GPM/Remote/GravCore.php index f93209e..2998975 100644 --- a/system/src/Grav/Common/GPM/Remote/GravCore.php +++ b/system/src/Grav/Common/GPM/Remote/GravCore.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Remote/Package.php b/system/src/Grav/Common/GPM/Remote/Package.php index c37d6a0..5193255 100644 --- a/system/src/Grav/Common/GPM/Remote/Package.php +++ b/system/src/Grav/Common/GPM/Remote/Package.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -32,6 +32,7 @@ class Package extends BasePackage implements \JsonSerializable /** * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->data->toArray(); diff --git a/system/src/Grav/Common/GPM/Remote/Packages.php b/system/src/Grav/Common/GPM/Remote/Packages.php index f55c12d..0ac2ef9 100644 --- a/system/src/Grav/Common/GPM/Remote/Packages.php +++ b/system/src/Grav/Common/GPM/Remote/Packages.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Remote/Plugins.php b/system/src/Grav/Common/GPM/Remote/Plugins.php index a134a10..8383cd7 100644 --- a/system/src/Grav/Common/GPM/Remote/Plugins.php +++ b/system/src/Grav/Common/GPM/Remote/Plugins.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Remote/Themes.php b/system/src/Grav/Common/GPM/Remote/Themes.php index 160ac97..a8ee9fa 100644 --- a/system/src/Grav/Common/GPM/Remote/Themes.php +++ b/system/src/Grav/Common/GPM/Remote/Themes.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/GPM/Upgrader.php b/system/src/Grav/Common/GPM/Upgrader.php index dfa6eb1..b3e6869 100644 --- a/system/src/Grav/Common/GPM/Upgrader.php +++ b/system/src/Grav/Common/GPM/Upgrader.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\GPM * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Getters.php b/system/src/Grav/Common/Getters.php index 916d524..ed03499 100644 --- a/system/src/Grav/Common/Getters.php +++ b/system/src/Grav/Common/Getters.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -28,6 +28,7 @@ abstract class Getters implements ArrayAccess, Countable * @param int|string $offset Medium name value * @param mixed $value Medium value */ + #[\ReturnTypeWillChange] public function __set($offset, $value) { $this->offsetSet($offset, $value); @@ -39,6 +40,7 @@ abstract class Getters implements ArrayAccess, Countable * @param int|string $offset Medium name value * @return mixed Medium value */ + #[\ReturnTypeWillChange] public function __get($offset) { return $this->offsetGet($offset); @@ -50,6 +52,7 @@ abstract class Getters implements ArrayAccess, Countable * @param int|string $offset Medium name value * @return boolean True if the value is set */ + #[\ReturnTypeWillChange] public function __isset($offset) { return $this->offsetExists($offset); @@ -60,6 +63,7 @@ abstract class Getters implements ArrayAccess, Countable * * @param int|string $offset The name value to unset */ + #[\ReturnTypeWillChange] public function __unset($offset) { $this->offsetUnset($offset); @@ -129,6 +133,7 @@ abstract class Getters implements ArrayAccess, Countable /** * @return int */ + #[\ReturnTypeWillChange] public function count() { if ($this->gettersVariable) { diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 2398c11..b9b44a4 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -49,7 +49,9 @@ use Grav\Common\Twig\Twig; use Grav\Framework\DI\Container; use Grav\Framework\Psr7\Response; use Grav\Framework\RequestHandler\RequestHandler; +use Grav\Framework\Route\Route; use Grav\Framework\Session\Messages; +use InvalidArgumentException; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use RocketTheme\Toolbox\Event\Event; @@ -60,8 +62,10 @@ use function call_user_func_array; use function function_exists; use function get_class; use function in_array; +use function is_array; use function is_callable; use function is_int; +use function is_string; use function strlen; /** @@ -343,7 +347,7 @@ class Grav extends Container * Please use this method instead of calling `die();` or `exit();`. Note that you need to create a response object. * * @param ResponseInterface $response - * @return void + * @return never-return */ public function close(ResponseInterface $response): void { @@ -395,7 +399,7 @@ class Grav extends Container /** * @param ResponseInterface $response - * @return void + * @return never-return * @deprecated 1.7 Do not use */ public function exit(ResponseInterface $response): void @@ -408,9 +412,9 @@ class Grav extends Container * * Please use this method instead of calling `header("Location: {$url}", true, 302); exit();`. * - * @param string $route Internal route. + * @param Route|string $route Internal route. * @param int|null $code Redirection code (30x) - * @return void + * @return never-return */ public function redirect($route, $code = null): void { @@ -422,7 +426,7 @@ class Grav extends Container /** * Returns redirect response object from Grav. * - * @param string $route Internal route. + * @param Route|string $route Internal route. * @param int|null $code Redirection code (30x) * @return ResponseInterface */ @@ -431,39 +435,45 @@ class Grav extends Container /** @var Uri $uri */ $uri = $this['uri']; - // Clean route for redirect - $route = preg_replace("#^\/[\\\/]+\/#", '/', $route); + if (is_string($route)) { + // Clean route for redirect + $route = preg_replace("#^\/[\\\/]+\/#", '/', $route); + + if (null === $code) { + // Check for redirect code in the route: e.g. /new/[301], /new[301]/route or /new[301].html + $regex = '/.*(\[(30[1-7])\])(.\w+|\/.*?)?$/'; + preg_match($regex, $route, $matches); + if ($matches) { + $route = str_replace($matches[1], '', $matches[0]); + $code = $matches[2]; + } + } + + if ($uri::isExternal($route)) { + $url = $route; + } else { + $url = rtrim($uri->rootUrl(), '/') . '/'; + + if ($this['config']->get('system.pages.redirect_trailing_slash', true)) { + $url .= trim($route, '/'); // Remove trailing slash + } else { + $url .= ltrim($route, '/'); // Support trailing slash default routes + } + } + } elseif ($route instanceof Route) { + $url = $route->toString(true); + } else { + throw new InvalidArgumentException('Bad $route'); + } if ($code < 300 || $code > 399) { $code = null; } - if (null === $code) { - // Check for redirect code in the route: e.g. /new/[301], /new[301]/route or /new[301].html - $regex = '/.*(\[(30[1-7])\])(.\w+|\/.*?)?$/'; - preg_match($regex, $route, $matches); - if ($matches) { - $route = str_replace($matches[1], '', $matches[0]); - $code = $matches[2]; - } - } - if ($code === null) { $code = $this['config']->get('system.pages.redirect_default_code', 302); } - if ($uri::isExternal($route)) { - $url = $route; - } else { - $url = rtrim($uri->rootUrl(), '/') . '/'; - - if ($this['config']->get('system.pages.redirect_trailing_slash', true)) { - $url .= trim($route, '/'); // Remove trailing slash - } else { - $url .= ltrim($route, '/'); // Support trailing slash default routes - } - } - if ($uri->extension() === 'json') { return new Response(200, ['Content-Type' => 'application/json'], json_encode(['code' => $code, 'redirect' => $url], JSON_THROW_ON_ERROR)); } @@ -643,6 +653,7 @@ class Grav extends Container * @param array $args * @return mixed|null */ + #[\ReturnTypeWillChange] public function __call($method, $args) { $closure = $this->{$method} ?? null; @@ -719,7 +730,10 @@ class Grav extends Container */ public function fallbackUrl($path) { - $this->fireEvent('onPageFallBackUrl'); + $path_parts = Utils::pathinfo($path); + if (!is_array($path_parts)) { + return false; + } /** @var Uri $uri */ $uri = $this['uri']; @@ -727,10 +741,28 @@ class Grav extends Container /** @var Config $config */ $config = $this['config']; - $uri_extension = strtolower($uri->extension()); - $fallback_types = $config->get('system.media.allowed_fallback_types', null); + /** @var Pages $pages */ + $pages = $this['pages']; + $page = $pages->find($path_parts['dirname'], true); + + $uri_extension = strtolower($uri->extension() ?? ''); + $fallback_types = $config->get('system.media.allowed_fallback_types'); $supported_types = $config->get('media.types'); + $parsed_url = parse_url(rawurldecode($uri->basename())); + $media_file = $parsed_url['path']; + + $event = new Event([ + 'uri' => $uri, + 'page' => &$page, + 'filename' => &$media_file, + 'extension' => $uri_extension, + 'allowed_fallback_types' => &$fallback_types, + 'media_types' => &$supported_types + ]); + + $this->fireEvent('onPageFallBackUrl', $event); + // Check whitelist first, then ensure extension is a valid media type if (!empty($fallback_types) && !in_array($uri_extension, $fallback_types, true)) { return false; @@ -739,16 +771,8 @@ class Grav extends Container return false; } - $path_parts = pathinfo($path); - - /** @var Pages $pages */ - $pages = $this['pages']; - $page = $pages->find($path_parts['dirname'], true); - if ($page) { $media = $page->media()->all(); - $parsed_url = parse_url(rawurldecode($uri->basename())); - $media_file = $parsed_url['path']; // if this is a media object, try actions first if (isset($media[$media_file])) { diff --git a/system/src/Grav/Common/GravTrait.php b/system/src/Grav/Common/GravTrait.php index 4638905..5416286 100644 --- a/system/src/Grav/Common/GravTrait.php +++ b/system/src/Grav/Common/GravTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/HTTP/Client.php b/system/src/Grav/Common/HTTP/Client.php index cd4f8db..c85d6b2 100644 --- a/system/src/Grav/Common/HTTP/Client.php +++ b/system/src/Grav/Common/HTTP/Client.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\HTTP * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/HTTP/Response.php b/system/src/Grav/Common/HTTP/Response.php index 4a05136..4a5bc8b 100644 --- a/system/src/Grav/Common/HTTP/Response.php +++ b/system/src/Grav/Common/HTTP/Response.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\HTTP * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Helpers/Base32.php b/system/src/Grav/Common/Helpers/Base32.php index 825c1ec..0d1c21a 100644 --- a/system/src/Grav/Common/Helpers/Base32.php +++ b/system/src/Grav/Common/Helpers/Base32.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Helpers * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Helpers/Excerpts.php b/system/src/Grav/Common/Helpers/Excerpts.php index 173850a..a62c7e5 100644 --- a/system/src/Grav/Common/Helpers/Excerpts.php +++ b/system/src/Grav/Common/Helpers/Excerpts.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Helpers * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Helpers/Exif.php b/system/src/Grav/Common/Helpers/Exif.php index 36e391f..a7dc973 100644 --- a/system/src/Grav/Common/Helpers/Exif.php +++ b/system/src/Grav/Common/Helpers/Exif.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Helpers * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Helpers/LogViewer.php b/system/src/Grav/Common/Helpers/LogViewer.php index 187828a..cf5ffe9 100644 --- a/system/src/Grav/Common/Helpers/LogViewer.php +++ b/system/src/Grav/Common/Helpers/LogViewer.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Helpers * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -145,7 +145,7 @@ class LogViewer 'logger' => $data['logger'], 'level' => $data['level'], 'message' => $data['message'], - 'trace' => isset($data['trace']) ? $this->parseTrace($data['trace']) : null, + 'trace' => isset($data['trace']) ? self::parseTrace($data['trace']) : null, 'context' => json_decode($data['context'], true), 'extra' => json_decode($data['extra'], true) ]; diff --git a/system/src/Grav/Common/Helpers/Truncator.php b/system/src/Grav/Common/Helpers/Truncator.php index 0a701b6..03c3eea 100644 --- a/system/src/Grav/Common/Helpers/Truncator.php +++ b/system/src/Grav/Common/Helpers/Truncator.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Helpers * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Helpers/YamlLinter.php b/system/src/Grav/Common/Helpers/YamlLinter.php index 45b5144..b31180f 100644 --- a/system/src/Grav/Common/Helpers/YamlLinter.php +++ b/system/src/Grav/Common/Helpers/YamlLinter.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Helpers * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -11,6 +11,7 @@ namespace Grav\Common\Helpers; use Exception; use Grav\Common\Grav; +use Grav\Common\Utils; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; use RegexIterator; @@ -108,7 +109,7 @@ class YamlLinter */ protected static function extractYaml($path) { - $extension = pathinfo($path, PATHINFO_EXTENSION); + $extension = Utils::pathinfo($path, PATHINFO_EXTENSION); if ($extension === 'md') { $file = MarkdownFile::instance($path); $contents = $file->frontmatter(); diff --git a/system/src/Grav/Common/Inflector.php b/system/src/Grav/Common/Inflector.php index 50c218f..216b733 100644 --- a/system/src/Grav/Common/Inflector.php +++ b/system/src/Grav/Common/Inflector.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Iterator.php b/system/src/Grav/Common/Iterator.php index 6e80b94..5db7bd0 100644 --- a/system/src/Grav/Common/Iterator.php +++ b/system/src/Grav/Common/Iterator.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -38,6 +38,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable * @param mixed $args * @return mixed */ + #[\ReturnTypeWillChange] public function __call($key, $args) { return $this->items[$key] ?? null; @@ -46,6 +47,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable /** * Clone the iterator. */ + #[\ReturnTypeWillChange] public function __clone() { foreach ($this as $key => $value) { @@ -60,6 +62,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable * * @return string */ + #[\ReturnTypeWillChange] public function __toString() { return implode(',', $this->items); diff --git a/system/src/Grav/Common/Language/Language.php b/system/src/Grav/Common/Language/Language.php index 6709754..fe006ed 100644 --- a/system/src/Grav/Common/Language/Language.php +++ b/system/src/Grav/Common/Language/Language.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Language * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -636,6 +636,7 @@ class Language /** * @return array */ + #[\ReturnTypeWillChange] public function __debugInfo() { $vars = get_object_vars($this); diff --git a/system/src/Grav/Common/Language/LanguageCodes.php b/system/src/Grav/Common/Language/LanguageCodes.php index e637bdd..3fa4948 100644 --- a/system/src/Grav/Common/Language/LanguageCodes.php +++ b/system/src/Grav/Common/Language/LanguageCodes.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Language * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -93,7 +93,7 @@ class LanguageCodes 'la' => [ 'name' => 'Latin', 'nativeName' => 'Latina' ], 'lb' => [ 'name' => 'Luxembourgish', 'nativeName' => 'Lëtzebuergesch' ], 'lg' => [ 'name' => 'Luganda', 'nativeName' => 'Luganda' ], - 'lo' => [ 'name' => 'Lao', 'nativeName' => 'Lao' ], + 'lo' => [ 'name' => 'Lao', 'nativeName' => 'Lao' ], 'lt' => [ 'name' => 'Lithuanian', 'nativeName' => 'Lietuvių' ], 'lv' => [ 'name' => 'Latvian', 'nativeName' => 'Latviešu' ], 'mai' => [ 'name' => 'Maithili', 'nativeName' => 'मैथिली মৈথিলী' ], @@ -103,7 +103,7 @@ class LanguageCodes 'ml' => [ 'name' => 'Malayalam', 'nativeName' => 'മലയാളം' ], 'mn' => [ 'name' => 'Mongolian', 'nativeName' => 'Монгол' ], 'mr' => [ 'name' => 'Marathi', 'nativeName' => 'मराठी' ], - 'my' => [ 'name' => 'Myanmar (Burmese)', 'nativeName' => 'ဗမာी' ], + 'my' => [ 'name' => 'Myanmar (Burmese)', 'nativeName' => 'ဗမာी' ], 'no' => [ 'name' => 'Norwegian', 'nativeName' => 'Norsk' ], 'nb' => [ 'name' => 'Norwegian', 'nativeName' => 'Norsk' ], 'nb-NO' => [ 'name' => 'Norwegian (Bokmål)', 'nativeName' => 'Norsk bokmål' ], diff --git a/system/src/Grav/Common/Markdown/Parsedown.php b/system/src/Grav/Common/Markdown/Parsedown.php index bdc5bdc..f0d8a48 100644 --- a/system/src/Grav/Common/Markdown/Parsedown.php +++ b/system/src/Grav/Common/Markdown/Parsedown.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Markdown * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Markdown/ParsedownExtra.php b/system/src/Grav/Common/Markdown/ParsedownExtra.php index b8e760e..ef450fe 100644 --- a/system/src/Grav/Common/Markdown/ParsedownExtra.php +++ b/system/src/Grav/Common/Markdown/ParsedownExtra.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Markdown * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php index 7c2b0d6..a593dd7 100644 --- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Markdown * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -289,6 +289,7 @@ trait ParsedownGravTrait * @param array $args * @return mixed|null */ + #[\ReturnTypeWillChange] public function __call($method, $args) { if (isset($this->{$method}) === true) { diff --git a/system/src/Grav/Common/Media/Interfaces/AudioMediaInterface.php b/system/src/Grav/Common/Media/Interfaces/AudioMediaInterface.php index d9c69d2..6465d6b 100644 --- a/system/src/Grav/Common/Media/Interfaces/AudioMediaInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/AudioMediaInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Interfaces/ImageManipulateInterface.php b/system/src/Grav/Common/Media/Interfaces/ImageManipulateInterface.php index 702cfda..eb38ea8 100644 --- a/system/src/Grav/Common/Media/Interfaces/ImageManipulateInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/ImageManipulateInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Interfaces/ImageMediaInterface.php b/system/src/Grav/Common/Media/Interfaces/ImageMediaInterface.php index 377258c..cbf8f1d 100644 --- a/system/src/Grav/Common/Media/Interfaces/ImageMediaInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/ImageMediaInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Interfaces/MediaCollectionInterface.php b/system/src/Grav/Common/Media/Interfaces/MediaCollectionInterface.php index ad9fe96..62c531c 100644 --- a/system/src/Grav/Common/Media/Interfaces/MediaCollectionInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/MediaCollectionInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Interfaces/MediaFileInterface.php b/system/src/Grav/Common/Media/Interfaces/MediaFileInterface.php index 07a5c26..c20e4de 100644 --- a/system/src/Grav/Common/Media/Interfaces/MediaFileInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/MediaFileInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Interfaces/MediaInterface.php b/system/src/Grav/Common/Media/Interfaces/MediaInterface.php index 436fe16..273556a 100644 --- a/system/src/Grav/Common/Media/Interfaces/MediaInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/MediaInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Interfaces/MediaLinkInterface.php b/system/src/Grav/Common/Media/Interfaces/MediaLinkInterface.php index 4f229c2..41747be 100644 --- a/system/src/Grav/Common/Media/Interfaces/MediaLinkInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/MediaLinkInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Interfaces/MediaObjectInterface.php b/system/src/Grav/Common/Media/Interfaces/MediaObjectInterface.php index 6438881..9334759 100644 --- a/system/src/Grav/Common/Media/Interfaces/MediaObjectInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/MediaObjectInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -16,6 +16,8 @@ use Grav\Common\Data\Data; * Class implements media object interface. * * @property string $type + * @property string $filename + * @property string $filepath */ interface MediaObjectInterface extends \Grav\Framework\Media\Interfaces\MediaObjectInterface, ArrayAccess { @@ -63,6 +65,14 @@ interface MediaObjectInterface extends \Grav\Framework\Media\Interfaces\MediaObj */ public function addAlternative($ratio, MediaObjectInterface $alternative); + /** + * Get list of image alternatives. Includes the current media image as well. + * + * @param bool $withDerived If true, include generated images as well. If false, only return existing files. + * @return array + */ + public function getAlternatives(bool $withDerived = true): array; + /** * Return string representation of the object (html). * @@ -208,6 +218,7 @@ interface MediaObjectInterface extends \Grav\Framework\Media\Interfaces\MediaObj * @param mixed $args * @return $this */ + #[\ReturnTypeWillChange] public function __call($method, $args); /** diff --git a/system/src/Grav/Common/Media/Interfaces/MediaPlayerInterface.php b/system/src/Grav/Common/Media/Interfaces/MediaPlayerInterface.php index 9307915..fbe6f65 100644 --- a/system/src/Grav/Common/Media/Interfaces/MediaPlayerInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/MediaPlayerInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Interfaces/MediaUploadInterface.php b/system/src/Grav/Common/Media/Interfaces/MediaUploadInterface.php index 8bfef84..7362599 100644 --- a/system/src/Grav/Common/Media/Interfaces/MediaUploadInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/MediaUploadInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Interfaces/VideoMediaInterface.php b/system/src/Grav/Common/Media/Interfaces/VideoMediaInterface.php index ff0655a..6d42fef 100644 --- a/system/src/Grav/Common/Media/Interfaces/VideoMediaInterface.php +++ b/system/src/Grav/Common/Media/Interfaces/VideoMediaInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Traits/AudioMediaTrait.php b/system/src/Grav/Common/Media/Traits/AudioMediaTrait.php index 160837d..a083472 100644 --- a/system/src/Grav/Common/Media/Traits/AudioMediaTrait.php +++ b/system/src/Grav/Common/Media/Traits/AudioMediaTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Traits/ImageLoadingTrait.php b/system/src/Grav/Common/Media/Traits/ImageLoadingTrait.php index c023763..75e23ca 100644 --- a/system/src/Grav/Common/Media/Traits/ImageLoadingTrait.php +++ b/system/src/Grav/Common/Media/Traits/ImageLoadingTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Traits/ImageMediaTrait.php b/system/src/Grav/Common/Media/Traits/ImageMediaTrait.php index f6e2222..c1c46dc 100644 --- a/system/src/Grav/Common/Media/Traits/ImageMediaTrait.php +++ b/system/src/Grav/Common/Media/Traits/ImageMediaTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Traits/MediaFileTrait.php b/system/src/Grav/Common/Media/Traits/MediaFileTrait.php index 7198133..63906fc 100644 --- a/system/src/Grav/Common/Media/Traits/MediaFileTrait.php +++ b/system/src/Grav/Common/Media/Traits/MediaFileTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Traits/MediaObjectTrait.php b/system/src/Grav/Common/Media/Traits/MediaObjectTrait.php index 3c2a38b..85ed6d2 100644 --- a/system/src/Grav/Common/Media/Traits/MediaObjectTrait.php +++ b/system/src/Grav/Common/Media/Traits/MediaObjectTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -128,16 +128,35 @@ trait MediaObjectTrait } $alternative->set('ratio', $ratio); - $width = $alternative->get('width'); + $width = $alternative->get('width', 0); $this->alternatives[$width] = $alternative; } + /** + * @param bool $withDerived + * @return array + */ + public function getAlternatives(bool $withDerived = true): array + { + $alternatives = []; + foreach ($this->alternatives + [$this->get('width', 0) => $this] as $size => $alternative) { + if ($withDerived || $alternative->filename === Utils::basename($alternative->filepath)) { + $alternatives[$size] = $alternative; + } + } + + ksort($alternatives, SORT_NUMERIC); + + return $alternatives; + } + /** * Return string representation of the object (html). * * @return string */ + #[\ReturnTypeWillChange] abstract public function __toString(); /** @@ -478,6 +497,7 @@ trait MediaObjectTrait * @param array $args * @return $this */ + #[\ReturnTypeWillChange] public function __call($method, $args) { $count = count($args); @@ -554,11 +574,12 @@ trait MediaObjectTrait foreach ($types as $type) { $thumb = $this->get("thumbnails.{$type}", false); - if ($thumb) { - $thumb = $thumb instanceof ThumbnailImageMedium ? $thumb : $this->createThumbnail($thumb); - $thumb->parent = $this; - $this->_thumbnail = $thumb; + $image = $thumb instanceof ThumbnailImageMedium ? $thumb : $this->createThumbnail($thumb); + if($image) { + $image->parent = $this; + $this->_thumbnail = $image; + } break; } } diff --git a/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php b/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php index 66e9f47..7e59d64 100644 --- a/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php +++ b/system/src/Grav/Common/Media/Traits/MediaPlayerTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -25,7 +25,7 @@ trait MediaPlayerTrait public function controls($status = true) { if ($status) { - $this->attributes['controls'] = true; + $this->attributes['controls'] = 'controls'; } else { unset($this->attributes['controls']); } @@ -42,7 +42,7 @@ trait MediaPlayerTrait public function loop($status = false) { if ($status) { - $this->attributes['loop'] = true; + $this->attributes['loop'] = 'loop'; } else { unset($this->attributes['loop']); } @@ -59,7 +59,7 @@ trait MediaPlayerTrait public function autoplay($status = false) { if ($status) { - $this->attributes['autoplay'] = true; + $this->attributes['autoplay'] = 'autoplay'; } else { unset($this->attributes['autoplay']); } @@ -76,7 +76,7 @@ trait MediaPlayerTrait public function muted($status = false) { if ($status) { - $this->attributes['muted'] = true; + $this->attributes['muted'] = 'muted'; } else { unset($this->attributes['muted']); } @@ -108,6 +108,6 @@ trait MediaPlayerTrait */ public function resetPlayer() { - $this->attributes['controls'] = true; + $this->attributes['controls'] = 'controls'; } } diff --git a/system/src/Grav/Common/Media/Traits/MediaTrait.php b/system/src/Grav/Common/Media/Traits/MediaTrait.php index 5faba82..14bfa90 100644 --- a/system/src/Grav/Common/Media/Traits/MediaTrait.php +++ b/system/src/Grav/Common/Media/Traits/MediaTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php b/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php index 7a1f55d..88591f6 100644 --- a/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php +++ b/system/src/Grav/Common/Media/Traits/MediaUploadTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -100,6 +100,10 @@ trait MediaUploadTrait 'size' => $uploadedFile->getSize(), ]; + if ($uploadedFile instanceof FormFlashFile) { + $uploadedFile->checkXss(); + } + return $this->checkFileMetadata($metadata, $filename, $settings); } @@ -132,9 +136,9 @@ trait MediaUploadTrait if ($folder === '.') { $folder = ''; } - $filename = basename($filename); + $filename = Utils::basename($filename); } - $extension = pathinfo($filename, PATHINFO_EXTENSION); + $extension = Utils::pathinfo($filename, PATHINFO_EXTENSION); // Decide which filename to use. if ($settings['random_name']) { @@ -573,6 +577,8 @@ trait MediaUploadTrait } } } + + $this->hide($filename); } /** diff --git a/system/src/Grav/Common/Media/Traits/StaticResizeTrait.php b/system/src/Grav/Common/Media/Traits/StaticResizeTrait.php index 49d75be..d8a4b08 100644 --- a/system/src/Grav/Common/Media/Traits/StaticResizeTrait.php +++ b/system/src/Grav/Common/Media/Traits/StaticResizeTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Traits/ThumbnailMediaTrait.php b/system/src/Grav/Common/Media/Traits/ThumbnailMediaTrait.php index eab7320..100b532 100644 --- a/system/src/Grav/Common/Media/Traits/ThumbnailMediaTrait.php +++ b/system/src/Grav/Common/Media/Traits/ThumbnailMediaTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php b/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php index e03fbbd..07f0c3f 100644 --- a/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php +++ b/system/src/Grav/Common/Media/Traits/VideoMediaTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -40,7 +40,7 @@ trait VideoMediaTrait public function playsinline($status = false) { if ($status) { - $this->attributes['playsinline'] = true; + $this->attributes['playsinline'] = 'playsinline'; } else { unset($this->attributes['playsinline']); } diff --git a/system/src/Grav/Common/Page/Collection.php b/system/src/Grav/Common/Page/Collection.php index 930aeda..987b8d9 100644 --- a/system/src/Grav/Common/Page/Collection.php +++ b/system/src/Grav/Common/Page/Collection.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -27,6 +27,7 @@ use function is_string; /** * Class Collection * @package Grav\Common\Page + * @implements PageCollectionInterface */ class Collection extends Iterator implements PageCollectionInterface { @@ -162,6 +163,7 @@ class Collection extends Iterator implements PageCollectionInterface * * @return PageInterface */ + #[\ReturnTypeWillChange] public function current() { $current = parent::key(); @@ -174,6 +176,7 @@ class Collection extends Iterator implements PageCollectionInterface * * @return mixed */ + #[\ReturnTypeWillChange] public function key() { $current = parent::current(); diff --git a/system/src/Grav/Common/Page/Header.php b/system/src/Grav/Common/Page/Header.php index 71c7b16..c18b58d 100644 --- a/system/src/Grav/Common/Page/Header.php +++ b/system/src/Grav/Common/Page/Header.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -30,6 +30,7 @@ class Header implements ArrayAccess, ExportInterface, JsonSerializable /** * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); diff --git a/system/src/Grav/Common/Page/Interfaces/PageCollectionInterface.php b/system/src/Grav/Common/Page/Interfaces/PageCollectionInterface.php index 5002911..493ab43 100644 --- a/system/src/Grav/Common/Page/Interfaces/PageCollectionInterface.php +++ b/system/src/Grav/Common/Page/Interfaces/PageCollectionInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -19,6 +19,11 @@ use Traversable; /** * Interface PageCollectionInterface * @package Grav\Common\Page\Interfaces + * + * @template TKey of array-key + * @template T + * @extends Traversable + * @extends ArrayAccess */ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, Serializable { @@ -68,6 +73,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * * @param PageCollectionInterface $collection * @return PageCollectionInterface + * @phpstan-return PageCollectionInterface */ public function merge(PageCollectionInterface $collection); @@ -76,6 +82,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * * @param PageCollectionInterface $collection * @return PageCollectionInterface + * @phpstan-return PageCollectionInterface */ public function intersect(PageCollectionInterface $collection); @@ -84,6 +91,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * * @param int $size * @return PageCollectionInterface[] + * @phpstan-return array> */ public function batch($size); @@ -92,6 +100,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * * @param PageInterface|string|null $key * @return PageCollectionInterface + * @phpstan-return PageCollectionInterface * @throws InvalidArgumentException */ //public function remove($key = null); @@ -104,6 +113,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * @param array|null $manual * @param string|null $sort_flags * @return PageCollectionInterface + * @phpstan-return PageCollectionInterface */ public function order($by, $dir = 'asc', $manual = null, $sort_flags = null); @@ -128,6 +138,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * * @param string $path * @return PageInterface The previous item. + * @phpstan-return T */ public function prevSibling($path); @@ -136,6 +147,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * * @param string $path * @return PageInterface The next item. + * @phpstan-return T */ public function nextSibling($path); @@ -145,6 +157,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * @param string $path * @param int $direction either -1 or +1 * @return PageInterface|PageCollectionInterface|false The sibling item. + * @phpstan-return T|false */ public function adjacentSibling($path, $direction = 1); @@ -166,6 +179,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * @param string|null $endDate * @param string|null $field * @return PageCollectionInterface + * @phpstan-return PageCollectionInterface * @throws Exception */ public function dateRange($startDate = null, $endDate = null, $field = null); @@ -174,6 +188,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * Creates new collection with only visible pages * * @return PageCollectionInterface The collection with only visible pages + * @phpstan-return PageCollectionInterface */ public function visible(); @@ -181,6 +196,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * Creates new collection with only non-visible pages * * @return PageCollectionInterface The collection with only non-visible pages + * @phpstan-return PageCollectionInterface */ public function nonVisible(); @@ -188,6 +204,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * Creates new collection with only pages * * @return PageCollectionInterface The collection with only pages + * @phpstan-return PageCollectionInterface */ public function pages(); @@ -195,6 +212,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * Creates new collection with only modules * * @return PageCollectionInterface The collection with only modules + * @phpstan-return PageCollectionInterface */ public function modules(); @@ -202,6 +220,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * Creates new collection with only modules * * @return PageCollectionInterface The collection with only modules + * @phpstan-return PageCollectionInterface * @deprecated 1.7 Use $this->modules() instead */ public function modular(); @@ -210,6 +229,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * Creates new collection with only non-module pages * * @return PageCollectionInterface The collection with only non-module pages + * @phpstan-return PageCollectionInterface * @deprecated 1.7 Use $this->pages() instead */ public function nonModular(); @@ -218,6 +238,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * Creates new collection with only published pages * * @return PageCollectionInterface The collection with only published pages + * @phpstan-return PageCollectionInterface */ public function published(); @@ -225,6 +246,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * Creates new collection with only non-published pages * * @return PageCollectionInterface The collection with only non-published pages + * @phpstan-return PageCollectionInterface */ public function nonPublished(); @@ -232,6 +254,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * Creates new collection with only routable pages * * @return PageCollectionInterface The collection with only routable pages + * @phpstan-return PageCollectionInterface */ public function routable(); @@ -239,6 +262,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * Creates new collection with only non-routable pages * * @return PageCollectionInterface The collection with only non-routable pages + * @phpstan-return PageCollectionInterface */ public function nonRoutable(); @@ -247,6 +271,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * * @param string $type * @return PageCollectionInterface The collection + * @phpstan-return PageCollectionInterface */ public function ofType($type); @@ -255,6 +280,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * * @param string[] $types * @return PageCollectionInterface The collection + * @phpstan-return PageCollectionInterface */ public function ofOneOfTheseTypes($types); @@ -263,6 +289,7 @@ interface PageCollectionInterface extends Traversable, ArrayAccess, Countable, S * * @param array $accessLevels * @return PageCollectionInterface The collection + * @phpstan-return PageCollectionInterface */ public function ofOneOfTheseAccessLevels($accessLevels); diff --git a/system/src/Grav/Common/Page/Interfaces/PageContentInterface.php b/system/src/Grav/Common/Page/Interfaces/PageContentInterface.php index d9d3105..a80972b 100644 --- a/system/src/Grav/Common/Page/Interfaces/PageContentInterface.php +++ b/system/src/Grav/Common/Page/Interfaces/PageContentInterface.php @@ -3,13 +3,15 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Common\Page\Interfaces; +use Grav\Common\Data\Blueprint; use Grav\Common\Media\Interfaces\MediaCollectionInterface; +use Grav\Common\Page\Header; /** * Methods currently implemented in Flex Page emulation layer. @@ -20,7 +22,7 @@ interface PageContentInterface * Gets and Sets the header based on the YAML configuration at the top of the .md file * * @param object|array|null $var a YAML object representing the configuration for the file - * @return object the current YAML configuration + * @return \stdClass|Header The current YAML configuration */ public function header($var = null); @@ -254,4 +256,12 @@ interface PageContentInterface * @return bool */ public function exists(); + + /** + * Returns the blueprint from the page. + * + * @param string $name Name of the Blueprint form. Used by flex only. + * @return Blueprint Returns a Blueprint. + */ + public function getBlueprint(string $name = ''); } diff --git a/system/src/Grav/Common/Page/Interfaces/PageInterface.php b/system/src/Grav/Common/Page/Interfaces/PageInterface.php index e5ea20c..56fc891 100644 --- a/system/src/Grav/Common/Page/Interfaces/PageInterface.php +++ b/system/src/Grav/Common/Page/Interfaces/PageInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Page/Interfaces/PageTranslateInterface.php b/system/src/Grav/Common/Page/Interfaces/PageTranslateInterface.php index be7ba15..5fba751 100644 --- a/system/src/Grav/Common/Page/Interfaces/PageTranslateInterface.php +++ b/system/src/Grav/Common/Page/Interfaces/PageTranslateInterface.php @@ -7,6 +7,11 @@ namespace Grav\Common\Page\Interfaces; */ interface PageTranslateInterface { + /** + * @return bool + */ + public function translated(): bool; + /** * Return an array with the routes of other translated languages * diff --git a/system/src/Grav/Common/Page/Interfaces/PagesSourceInterface.php b/system/src/Grav/Common/Page/Interfaces/PagesSourceInterface.php index ef5cfba..ff4ebda 100644 --- a/system/src/Grav/Common/Page/Interfaces/PagesSourceInterface.php +++ b/system/src/Grav/Common/Page/Interfaces/PagesSourceInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Page/Markdown/Excerpts.php b/system/src/Grav/Common/Page/Markdown/Excerpts.php index 9b0b996..17f9cbf 100644 --- a/system/src/Grav/Common/Page/Markdown/Excerpts.php +++ b/system/src/Grav/Common/Page/Markdown/Excerpts.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -206,7 +206,7 @@ class Excerpts && (empty($url_parts['host']) || $url_parts['host'] === $grav['uri']->host()); if ($local_file) { - $filename = basename($url_parts['path']); + $filename = Utils::basename($url_parts['path']); $folder = dirname($url_parts['path']); // Get the local path to page media if possible. diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index e182014..6c0a6c3 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -3,13 +3,14 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Common\Page; use FilesystemIterator; +use Grav\Common\Config\Config; use Grav\Common\Grav; use Grav\Common\Media\Interfaces\MediaObjectInterface; use Grav\Common\Yaml; @@ -59,6 +60,46 @@ class Media extends AbstractMedia } } + /** + * Return raw route to the page. + * + * @return string|null Route to the page or null if media isn't for a page. + */ + public function getRawRoute(): ?string + { + $path = $this->getPath(); + if ($path) { + /** @var Pages $pages */ + $pages = $this->getGrav()['pages']; + $page = $pages->get($path); + if ($page) { + return $page->rawRoute(); + } + } + + return null; + } + + /** + * Return page route. + * + * @return string|null Route to the page or null if media isn't for a page. + */ + public function getRoute(): ?string + { + $path = $this->getPath(); + if ($path) { + /** @var Pages $pages */ + $pages = $this->getGrav()['pages']; + $page = $pages->get($path); + if ($page) { + return $page->route(); + } + } + + return null; + } + /** * @param string $offset * @return bool @@ -86,11 +127,6 @@ class Media extends AbstractMedia */ protected function init() { - /** @var UniformResourceLocator $locator */ - $locator = Grav::instance()['locator']; - $config = Grav::instance()['config']; - $exif_reader = isset(Grav::instance()['exif']) ? Grav::instance()['exif']->getReader() : false; - $media_types = array_keys(Grav::instance()['config']->get('media.types')); $path = $this->getPath(); // Handle special cases where page doesn't exist in filesystem. @@ -98,6 +134,17 @@ class Media extends AbstractMedia return; } + $grav = Grav::instance(); + + /** @var UniformResourceLocator $locator */ + $locator = $grav['locator']; + + /** @var Config $config */ + $config = $grav['config']; + + $exif_reader = isset($grav['exif']) ? $grav['exif']->getReader() : null; + $media_types = array_keys($config->get('media.types', [])); + $iterator = new FilesystemIterator($path, FilesystemIterator::UNIX_PATHS | FilesystemIterator::SKIP_DOTS); $media = []; diff --git a/system/src/Grav/Common/Page/Medium/AbstractMedia.php b/system/src/Grav/Common/Page/Medium/AbstractMedia.php index db81ddd..9b3650b 100644 --- a/system/src/Grav/Common/Page/Medium/AbstractMedia.php +++ b/system/src/Grav/Common/Page/Medium/AbstractMedia.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -90,6 +90,7 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac * @param string $filename * @return mixed */ + #[\ReturnTypeWillChange] public function __invoke($filename) { return $this->offsetGet($filename); diff --git a/system/src/Grav/Common/Page/Medium/AudioMedium.php b/system/src/Grav/Common/Page/Medium/AudioMedium.php index f34f0a9..cc53f81 100644 --- a/system/src/Grav/Common/Page/Medium/AudioMedium.php +++ b/system/src/Grav/Common/Page/Medium/AudioMedium.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Page/Medium/GlobalMedia.php b/system/src/Grav/Common/Page/Medium/GlobalMedia.php index 50d69c7..20f63ad 100644 --- a/system/src/Grav/Common/Page/Medium/GlobalMedia.php +++ b/system/src/Grav/Common/Page/Medium/GlobalMedia.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -11,6 +11,7 @@ namespace Grav\Common\Page\Medium; use Grav\Common\Grav; use Grav\Common\Media\Interfaces\MediaObjectInterface; +use Grav\Common\Utils; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use function dirname; @@ -89,7 +90,7 @@ class GlobalMedia extends AbstractMedia } $path = dirname($filename); - [$basename, $ext,, $extra] = $this->getFileParts(basename($filename)); + [$basename, $ext,, $extra] = $this->getFileParts(Utils::basename($filename)); $medium = MediumFactory::fromFile($filename); if (null === $medium) { diff --git a/system/src/Grav/Common/Page/Medium/ImageFile.php b/system/src/Grav/Common/Page/Medium/ImageFile.php index bd853bf..1aae7ee 100644 --- a/system/src/Grav/Common/Page/Medium/ImageFile.php +++ b/system/src/Grav/Common/Page/Medium/ImageFile.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -34,6 +34,7 @@ class ImageFile extends Image /** * Destruct also image object. */ + #[\ReturnTypeWillChange] public function __destruct() { $adapter = $this->adapter; diff --git a/system/src/Grav/Common/Page/Medium/ImageMedium.php b/system/src/Grav/Common/Page/Medium/ImageMedium.php index 46c832e..42d8f0e 100644 --- a/system/src/Grav/Common/Page/Medium/ImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/ImageMedium.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -89,6 +89,7 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate /** * Also unset the image on destruct. */ + #[\ReturnTypeWillChange] public function __destruct() { unset($this->image); @@ -97,6 +98,7 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate /** * Also clone image. */ + #[\ReturnTypeWillChange] public function __clone() { if ($this->image) { @@ -247,12 +249,12 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate if ($this->saved_image_path && $this->auto_sizes) { if (!array_key_exists('height', $this->attributes) && !array_key_exists('width', $this->attributes)) { $info = getimagesize($this->saved_image_path); - $width = intval($info[0]); - $height = intval($info[1]); + $width = (int)$info[0]; + $height = (int)$info[1]; $scaling_factor = $this->retina_scale > 0 ? $this->retina_scale : 1; - $attributes['width'] = intval($width / $scaling_factor); - $attributes['height'] = intval($height / $scaling_factor); + $attributes['width'] = (int)($width / $scaling_factor); + $attributes['height'] = (int)($height / $scaling_factor); if ($this->aspect_ratio) { $style = ($attributes['style'] ?? ' ') . "--aspect-ratio: $width/$height;"; @@ -303,29 +305,45 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate return parent::lightbox($width, $height, $reset); } + /** + * @param string $enabled + * @return $this + */ public function autoSizes($enabled = 'true') { - $enabled = $enabled === 'true' ?: false; - $this->auto_sizes = $enabled; + $this->auto_sizes = $enabled === 'true' ?: false; return $this; } + /** + * @param string $enabled + * @return $this + */ public function aspectRatio($enabled = 'true') { - $enabled = $enabled === 'true' ?: false; - $this->aspect_ratio = $enabled; + $this->aspect_ratio = $enabled === 'true' ?: false; return $this; } + /** + * @param int $scale + * @return $this + */ public function retinaScale($scale = 1) { - $this->retina_scale = intval($scale); + $this->retina_scale = (int)$scale; return $this; } + /** + * @param string|null $image + * @param string|null $position + * @param int|float|null $scale + * @return $this + */ public function watermark($image = null, $position = null, $scale = null) { $grav = $this->getGrav(); @@ -406,7 +424,7 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate */ public function addFrame(int $border = 10, string $color = '0x000000') { - if(is_int(intval($border)) && $border>0 && preg_match('/^0x[a-f0-9]{6}$/i', $color)) { // $border must be an integer and bigger than 0; $color must be formatted as an HEX value (0x??????). + if($border > 0 && preg_match('/^0x[a-f0-9]{6}$/i', $color)) { // $border must be an integer and bigger than 0; $color must be formatted as an HEX value (0x??????). $image = ImageFile::open($this->path()); } else { @@ -437,7 +455,7 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate * @param mixed $args * @return $this|mixed */ - + #[\ReturnTypeWillChange] public function __call($method, $args) { if (!in_array($method, static::$magic_actions, true)) { diff --git a/system/src/Grav/Common/Page/Medium/Link.php b/system/src/Grav/Common/Page/Medium/Link.php index d576875..c76d8c1 100644 --- a/system/src/Grav/Common/Page/Medium/Link.php +++ b/system/src/Grav/Common/Page/Medium/Link.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -28,7 +28,7 @@ class Link implements RenderableInterface, MediaLinkInterface /** @var array */ protected $attributes = []; - /** @var MediaObjectInterface */ + /** @var MediaObjectInterface|MediaLinkInterface */ protected $source; /** @@ -79,6 +79,7 @@ class Link implements RenderableInterface, MediaLinkInterface * @param mixed $args * @return mixed */ + #[\ReturnTypeWillChange] public function __call($method, $args) { $object = $this->source; diff --git a/system/src/Grav/Common/Page/Medium/Medium.php b/system/src/Grav/Common/Page/Medium/Medium.php index 87009ac..0891c0c 100644 --- a/system/src/Grav/Common/Page/Medium/Medium.php +++ b/system/src/Grav/Common/Page/Medium/Medium.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -22,7 +22,14 @@ use Grav\Common\Media\Traits\MediaObjectTrait; * Class Medium * @package Grav\Common\Page\Medium * + * @property string $filepath + * @property string $filename + * @property string $basename * @property string $mime + * @property int $size + * @property int $modified + * @property array $metadata + * @property int|string $timestamp */ class Medium extends Data implements RenderableInterface, MediaFileInterface { @@ -57,6 +64,7 @@ class Medium extends Data implements RenderableInterface, MediaFileInterface /** * Clone medium. */ + #[\ReturnTypeWillChange] public function __clone() { // Allows future compatibility as parent::__clone() works. @@ -90,6 +98,7 @@ class Medium extends Data implements RenderableInterface, MediaFileInterface * * @return string */ + #[\ReturnTypeWillChange] public function __toString() { return $this->html(); @@ -97,6 +106,7 @@ class Medium extends Data implements RenderableInterface, MediaFileInterface /** * @param string $thumb + * @return Medium|null */ protected function createThumbnail($thumb) { diff --git a/system/src/Grav/Common/Page/Medium/MediumFactory.php b/system/src/Grav/Common/Page/Medium/MediumFactory.php index 7dee4ea..913f198 100644 --- a/system/src/Grav/Common/Page/Medium/MediumFactory.php +++ b/system/src/Grav/Common/Page/Medium/MediumFactory.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -13,6 +13,7 @@ use Grav\Common\Grav; use Grav\Common\Data\Blueprint; use Grav\Common\Media\Interfaces\ImageMediaInterface; use Grav\Common\Media\Interfaces\MediaObjectInterface; +use Grav\Common\Utils; use Grav\Framework\Form\FormFlashFile; use Psr\Http\Message\UploadedFileInterface; use function dirname; @@ -37,7 +38,7 @@ class MediumFactory return null; } - $parts = pathinfo($file); + $parts = Utils::pathinfo($file); $path = $parts['dirname']; $filename = $parts['basename']; $ext = $parts['extension'] ?? ''; @@ -101,7 +102,7 @@ class MediumFactory return null; } - $parts = pathinfo($clientName); + $parts = Utils::pathinfo($clientName); $filename = $parts['basename']; $ext = $parts['extension'] ?? ''; $basename = $parts['filename']; @@ -158,8 +159,9 @@ class MediumFactory return new ImageMedium($items, $blueprint); case 'thumbnail': return new ThumbnailImageMedium($items, $blueprint); - case 'animated': case 'vector': + return new VectorImageMedium($items, $blueprint); + case 'animated': return new StaticImageMedium($items, $blueprint); case 'video': return new VideoMedium($items, $blueprint); @@ -193,7 +195,7 @@ class MediumFactory $height = $medium->get('height') * $ratio; $prev_basename = $medium->get('basename'); - $basename = str_replace('@'.$from.'x', '@'.$to.'x', $prev_basename); + $basename = str_replace('@' . $from . 'x', $to !== 1 ? '@' . $to . 'x' : '', $prev_basename); $debug = $medium->get('debug'); $medium->set('debug', false); @@ -208,6 +210,8 @@ class MediumFactory $medium = self::fromFile($file); if ($medium) { + $medium->set('basename', $basename); + $medium->set('filename', $basename . '.' . $medium->extension); $medium->set('size', $size); } diff --git a/system/src/Grav/Common/Page/Medium/ParsedownHtmlTrait.php b/system/src/Grav/Common/Page/Medium/ParsedownHtmlTrait.php index 44ab952..4ab2fb5 100644 --- a/system/src/Grav/Common/Page/Medium/ParsedownHtmlTrait.php +++ b/system/src/Grav/Common/Page/Medium/ParsedownHtmlTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Page/Medium/RenderableInterface.php b/system/src/Grav/Common/Page/Medium/RenderableInterface.php index ac72447..1ee6a96 100644 --- a/system/src/Grav/Common/Page/Medium/RenderableInterface.php +++ b/system/src/Grav/Common/Page/Medium/RenderableInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Page/Medium/StaticImageMedium.php b/system/src/Grav/Common/Page/Medium/StaticImageMedium.php index ba92fa1..9780100 100644 --- a/system/src/Grav/Common/Page/Medium/StaticImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/StaticImageMedium.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -37,4 +37,12 @@ class StaticImageMedium extends Medium implements ImageMediaInterface return ['name' => 'img', 'attributes' => $attributes]; } + + /** + * @return $this + */ + public function higherQualityAlternative() + { + return $this; + } } diff --git a/system/src/Grav/Common/Page/Medium/StaticResizeTrait.php b/system/src/Grav/Common/Page/Medium/StaticResizeTrait.php index d95b2d6..caaa7e2 100644 --- a/system/src/Grav/Common/Page/Medium/StaticResizeTrait.php +++ b/system/src/Grav/Common/Page/Medium/StaticResizeTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Page/Medium/ThumbnailImageMedium.php b/system/src/Grav/Common/Page/Medium/ThumbnailImageMedium.php index a56a20d..1e4d862 100644 --- a/system/src/Grav/Common/Page/Medium/ThumbnailImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/ThumbnailImageMedium.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Page/Medium/VectorImageMedium.php b/system/src/Grav/Common/Page/Medium/VectorImageMedium.php new file mode 100644 index 0000000..c44f35a --- /dev/null +++ b/system/src/Grav/Common/Page/Medium/VectorImageMedium.php @@ -0,0 +1,68 @@ +get('width'); + $height = $this->get('height'); + if ($width && $height) { + return; + } + + // Make sure that getting image size is supported. + if ($this->mime !== 'image/svg+xml' || !\extension_loaded('simplexml')) { + return; + } + + // Make sure that the image exists. + $path = $this->get('filepath'); + if (!$path || !file_exists($path) || !filesize($path)) { + return; + } + + $xml = simplexml_load_string(file_get_contents($path)); + $attr = $xml ? $xml->attributes() : null; + if (!$attr instanceof \SimpleXMLElement) { + return; + } + + // Get the size from svg image. + if ($attr->width && $attr->height) { + $width = (string)$attr->width; + $height = (string)$attr->height; + } elseif ($attr->viewBox && \count($size = explode(' ', (string)$attr->viewBox)) === 4) { + [,$width,$height,] = $size; + } + + if ($width && $height) { + $this->def('width', (int)$width); + $this->def('height', (int)$height); + } + } +} diff --git a/system/src/Grav/Common/Page/Medium/VideoMedium.php b/system/src/Grav/Common/Page/Medium/VideoMedium.php index bfcf550..0e629dc 100644 --- a/system/src/Grav/Common/Page/Medium/VideoMedium.php +++ b/system/src/Grav/Common/Page/Medium/VideoMedium.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 9e68a44..25f8ff6 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -84,7 +84,7 @@ class Page implements PageInterface protected $unpublish_date; /** @var string */ protected $slug; - /** @var string */ + /** @var string|null */ protected $route; /** @var string|null */ protected $raw_route; @@ -196,7 +196,7 @@ class Page implements PageInterface } // extract page language from page extension - $language = trim(basename($this->extension(), 'md'), '.') ?: null; + $language = trim(Utils::basename($this->extension(), 'md'), '.') ?: null; $this->language($language); $this->hide_home_route = $config->get('system.home.hide_in_urls', false); @@ -218,6 +218,7 @@ class Page implements PageInterface return $this; } + #[\ReturnTypeWillChange] public function __clone() { $this->initialized = false; @@ -387,7 +388,7 @@ class Page implements PageInterface * Gets and Sets the header based on the YAML configuration at the top of the .md file * * @param object|array|null $var a YAML object representing the configuration for the file - * @return object the current YAML configuration + * @return \stdClass the current YAML configuration */ public function header($var = null) { @@ -1246,6 +1247,17 @@ class Page implements PageInterface return $blueprint; } + /** + * Returns the blueprint from the page. + * + * @param string $name Not used. + * @return Blueprint Returns a Blueprint. + */ + public function getBlueprint(string $name = '') + { + return $this->blueprints(); + } + /** * Get the blueprint name for this page. Use the blueprint form field if set * @@ -1453,7 +1465,7 @@ class Page implements PageInterface $this->extension = $var; } if (empty($this->extension)) { - $this->extension = '.' . pathinfo($this->name(), PATHINFO_EXTENSION); + $this->extension = '.' . Utils::pathinfo($this->name(), PATHINFO_EXTENSION); } return $this->extension; @@ -2097,9 +2109,9 @@ class Page implements PageInterface { if ($var !== null) { // Filename of the page. - $this->name = basename($var); + $this->name = Utils::basename($var); // Folder of the page. - $this->folder = basename(dirname($var)); + $this->folder = Utils::basename(dirname($var)); // Path to the page. $this->path = dirname($var, 2); } @@ -2138,7 +2150,7 @@ class Page implements PageInterface { if ($var !== null) { // Folder of the page. - $this->folder = basename($var); + $this->folder = Utils::basename($var); // Path to the page. $this->path = dirname($var); } diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 9e5d47d..ec48b51 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -736,7 +736,13 @@ class Pages break; case 'siblings': $parent = $page->parent(); - $collection = $parent ? $parent->children()->remove($page->path()) : new Collection(); + if ($parent) { + /** @var Collection $collection */ + $collection = $parent->children(); + $collection = $collection->remove($page->path()); + } else { + $collection = new Collection(); + } break; case 'descendants': $collection = $this->all($page)->remove($page->path())->pages(); @@ -1041,9 +1047,14 @@ class Pages $this->grav->redirectLangSafe($page->redirect()); } - if (!$routable && ($child = $page->children()->visible()->routable()->published()->first()) !== null) { - // Redirect to the first visible child as current page isn't routable. - $this->grav->redirectLangSafe($child->route()); + if (!$routable) { + /** @var Collection $children */ + $children = $page->children()->visible()->routable()->published(); + $child = $children->first(); + if ($child !== null) { + // Redirect to the first visible child as current page isn't routable. + $this->grav->redirectLangSafe($child->route()); + } } } @@ -2065,7 +2076,7 @@ class Pages $list[$key] = $child->slug(); break; case 'basename': - $list[$key] = basename($key); + $list[$key] = Utils::basename($key); break; case 'folder': $list[$key] = $child->folder(); diff --git a/system/src/Grav/Common/Page/Types.php b/system/src/Grav/Common/Page/Types.php index c718368..420c588 100644 --- a/system/src/Grav/Common/Page/Types.php +++ b/system/src/Grav/Common/Page/Types.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Page * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -12,6 +12,7 @@ namespace Grav\Common\Page; use Grav\Common\Data\Blueprint; use Grav\Common\Filesystem\Folder; use Grav\Common\Grav; +use Grav\Common\Utils; use InvalidArgumentException; use RocketTheme\Toolbox\ArrayTraits\ArrayAccess; use RocketTheme\Toolbox\ArrayTraits\Constructor; @@ -144,7 +145,7 @@ class Types implements \ArrayAccess, \Iterator, \Countable if (strpos($name, 'modular/') !== 0) { continue; } - $list[$name] = ucfirst(trim(str_replace('_', ' ', basename($name)))); + $list[$name] = ucfirst(trim(str_replace('_', ' ', Utils::basename($name)))); } ksort($list); diff --git a/system/src/Grav/Common/Plugin.php b/system/src/Grav/Common/Plugin.php index 3b0d3fb..30e5344 100644 --- a/system/src/Grav/Common/Plugin.php +++ b/system/src/Grav/Common/Plugin.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -118,7 +118,7 @@ class Plugin implements EventSubscriberInterface, ArrayAccess */ public function config() { - return null !== $this->config ? $this->config["plugins.{$this->name}"] : []; + return $this->config["plugins.{$this->name}"] ?? []; } /** @@ -414,6 +414,30 @@ class Plugin implements EventSubscriberInterface, ArrayAccess return true; } + public static function inheritedConfigOption(string $plugin, string $var, PageInterface $page = null, $default = null) + { + if (Utils::isAdminPlugin()) { + $page = Grav::instance()['admin']->page() ?? null; + } else { + $page = $page ?? Grav::instance()['page'] ?? null; + } + + // Try to find var in the page headers + if ($page instanceof PageInterface && $page->exists()) { + // Loop over pages and look for header vars + while ($page && !$page->root()) { + $header = new Data((array)$page->header()); + $value = $header->get("$plugin.$var"); + if (isset($value)) { + return $value; + } + $page = $page->parent(); + } + } + + return Grav::instance()['config']->get("plugins.$plugin.$var", $default); + } + /** * Simpler getter for the plugin blueprint * diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index 88b5e52..42b1593 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/AssetsProcessor.php b/system/src/Grav/Common/Processors/AssetsProcessor.php index 66bb5e3..e460fb0 100644 --- a/system/src/Grav/Common/Processors/AssetsProcessor.php +++ b/system/src/Grav/Common/Processors/AssetsProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/BackupsProcessor.php b/system/src/Grav/Common/Processors/BackupsProcessor.php index 6e960b4..83e8a0c 100644 --- a/system/src/Grav/Common/Processors/BackupsProcessor.php +++ b/system/src/Grav/Common/Processors/BackupsProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/DebuggerAssetsProcessor.php b/system/src/Grav/Common/Processors/DebuggerAssetsProcessor.php index de7cafc..a3d5a51 100644 --- a/system/src/Grav/Common/Processors/DebuggerAssetsProcessor.php +++ b/system/src/Grav/Common/Processors/DebuggerAssetsProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/Events/RequestHandlerEvent.php b/system/src/Grav/Common/Processors/Events/RequestHandlerEvent.php index 32908ba..30f6195 100644 --- a/system/src/Grav/Common/Processors/Events/RequestHandlerEvent.php +++ b/system/src/Grav/Common/Processors/Events/RequestHandlerEvent.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/InitializeProcessor.php b/system/src/Grav/Common/Processors/InitializeProcessor.php index b31530e..04e06ed 100644 --- a/system/src/Grav/Common/Processors/InitializeProcessor.php +++ b/system/src/Grav/Common/Processors/InitializeProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/PagesProcessor.php b/system/src/Grav/Common/Processors/PagesProcessor.php index 36f6718..3338e0c 100644 --- a/system/src/Grav/Common/Processors/PagesProcessor.php +++ b/system/src/Grav/Common/Processors/PagesProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/PluginsProcessor.php b/system/src/Grav/Common/Processors/PluginsProcessor.php index 485578e..ae87901 100644 --- a/system/src/Grav/Common/Processors/PluginsProcessor.php +++ b/system/src/Grav/Common/Processors/PluginsProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/ProcessorBase.php b/system/src/Grav/Common/Processors/ProcessorBase.php index a3506f5..9353391 100644 --- a/system/src/Grav/Common/Processors/ProcessorBase.php +++ b/system/src/Grav/Common/Processors/ProcessorBase.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/ProcessorInterface.php b/system/src/Grav/Common/Processors/ProcessorInterface.php index 8a6edbe..0aed195 100644 --- a/system/src/Grav/Common/Processors/ProcessorInterface.php +++ b/system/src/Grav/Common/Processors/ProcessorInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/RenderProcessor.php b/system/src/Grav/Common/Processors/RenderProcessor.php index 329da22..e12cc45 100644 --- a/system/src/Grav/Common/Processors/RenderProcessor.php +++ b/system/src/Grav/Common/Processors/RenderProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/RequestProcessor.php b/system/src/Grav/Common/Processors/RequestProcessor.php index 971fb67..bad410c 100644 --- a/system/src/Grav/Common/Processors/RequestProcessor.php +++ b/system/src/Grav/Common/Processors/RequestProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -11,6 +11,7 @@ namespace Grav\Common\Processors; use Grav\Common\Processors\Events\RequestHandlerEvent; use Grav\Common\Uri; +use Grav\Common\Utils; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; @@ -42,7 +43,7 @@ class RequestProcessor extends ProcessorBase } $uri = $request->getUri(); - $ext = mb_strtolower(pathinfo($uri->getPath(), PATHINFO_EXTENSION)); + $ext = mb_strtolower(Utils::pathinfo($uri->getPath(), PATHINFO_EXTENSION)); $request = $request ->withAttribute('grav', $this->container) diff --git a/system/src/Grav/Common/Processors/SchedulerProcessor.php b/system/src/Grav/Common/Processors/SchedulerProcessor.php index 69cc163..722bfcc 100644 --- a/system/src/Grav/Common/Processors/SchedulerProcessor.php +++ b/system/src/Grav/Common/Processors/SchedulerProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/TasksProcessor.php b/system/src/Grav/Common/Processors/TasksProcessor.php index 07e0934..29f3458 100644 --- a/system/src/Grav/Common/Processors/TasksProcessor.php +++ b/system/src/Grav/Common/Processors/TasksProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/ThemesProcessor.php b/system/src/Grav/Common/Processors/ThemesProcessor.php index 951dc79..60d089e 100644 --- a/system/src/Grav/Common/Processors/ThemesProcessor.php +++ b/system/src/Grav/Common/Processors/ThemesProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Processors/TwigProcessor.php b/system/src/Grav/Common/Processors/TwigProcessor.php index 6604b5c..ffc1032 100644 --- a/system/src/Grav/Common/Processors/TwigProcessor.php +++ b/system/src/Grav/Common/Processors/TwigProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Processors * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Scheduler/Cron.php b/system/src/Grav/Common/Scheduler/Cron.php index 5127a99..0103839 100644 --- a/system/src/Grav/Common/Scheduler/Cron.php +++ b/system/src/Grav/Common/Scheduler/Cron.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Scheduler * @author Originally based on jqCron by Arnaud Buathier modified for Grav integration - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Scheduler/IntervalTrait.php b/system/src/Grav/Common/Scheduler/IntervalTrait.php index cc5c165..5f7406b 100644 --- a/system/src/Grav/Common/Scheduler/IntervalTrait.php +++ b/system/src/Grav/Common/Scheduler/IntervalTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Scheduler * @author Originally based on peppeocchi/php-cron-scheduler modified for Grav integration - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Scheduler/Job.php b/system/src/Grav/Common/Scheduler/Job.php index 13059a5..4156119 100644 --- a/system/src/Grav/Common/Scheduler/Job.php +++ b/system/src/Grav/Common/Scheduler/Job.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Scheduler * @author Originally based on peppeocchi/php-cron-scheduler modified for Grav integration - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Scheduler/Scheduler.php b/system/src/Grav/Common/Scheduler/Scheduler.php index 73a0712..19eb9ea 100644 --- a/system/src/Grav/Common/Scheduler/Scheduler.php +++ b/system/src/Grav/Common/Scheduler/Scheduler.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Scheduler * @author Originally based on peppeocchi/php-cron-scheduler modified for Grav integration - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Security.php b/system/src/Grav/Common/Security.php index fe259d8..779e619 100644 --- a/system/src/Grav/Common/Security.php +++ b/system/src/Grav/Common/Security.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -25,6 +25,22 @@ use function is_string; */ class Security { + /** + * @param string $filepath + * @param array|null $options + * @return string|null + */ + public static function detectXssFromSvgFile(string $filepath, array $options = null): ?string + { + if (file_exists($filepath) && Grav::instance()['config']->get('security.sanitize_svg')) { + $content = file_get_contents($filepath); + + return static::detectXss($content, $options); + } + + return null; + } + /** * Sanitize SVG string for XSS code * @@ -61,7 +77,7 @@ class Security if ($clean_svg !== false ) { file_put_contents($file, $clean_svg); } else { - $quarantine_file = basename($file); + $quarantine_file = Utils::basename($file); $quarantine_dir = 'log://quarantine'; Folder::mkdir($quarantine_dir); file_put_contents("$quarantine_dir/$quarantine_file", $original_svg); @@ -200,7 +216,7 @@ class Security }, $string); // Clean up entities - $string = preg_replace('!(�+[0-9]+)!u', '$1;', $string); + $string = preg_replace('!(&#[0-9]+);?!u', '$1;', $string); // Decode entities $string = html_entity_decode($string, ENT_NOQUOTES | ENT_HTML5, 'UTF-8'); @@ -214,7 +230,7 @@ class Security 'on_events' => '#(<[^>]+[[a-z\x00-\x20\"\'\/])([\s\/]on|\sxmlns)[a-z].*=>?#iUu', // Match javascript:, livescript:, vbscript:, mocha:, feed: and data: protocols - 'invalid_protocols' => '#(' . implode('|', array_map('preg_quote', $invalid_protocols, ['#'])) . '):\S.*?#iUu', + 'invalid_protocols' => '#(' . implode('|', array_map('preg_quote', $invalid_protocols, ['#'])) . ')(:|\&\#58)\S.*?#iUu', // Match -moz-bindings 'moz_binding' => '#-moz-binding[a-z\x00-\x20]*:#u', diff --git a/system/src/Grav/Common/Service/AccountsServiceProvider.php b/system/src/Grav/Common/Service/AccountsServiceProvider.php index 8b158c9..60f26e5 100644 --- a/system/src/Grav/Common/Service/AccountsServiceProvider.php +++ b/system/src/Grav/Common/Service/AccountsServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/AssetsServiceProvider.php b/system/src/Grav/Common/Service/AssetsServiceProvider.php index 1e4e647..54a44a1 100644 --- a/system/src/Grav/Common/Service/AssetsServiceProvider.php +++ b/system/src/Grav/Common/Service/AssetsServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/BackupsServiceProvider.php b/system/src/Grav/Common/Service/BackupsServiceProvider.php index 00fa963..58f5021 100644 --- a/system/src/Grav/Common/Service/BackupsServiceProvider.php +++ b/system/src/Grav/Common/Service/BackupsServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/ConfigServiceProvider.php b/system/src/Grav/Common/Service/ConfigServiceProvider.php index 3a5c2e2..e65e228 100644 --- a/system/src/Grav/Common/Service/ConfigServiceProvider.php +++ b/system/src/Grav/Common/Service/ConfigServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/ErrorServiceProvider.php b/system/src/Grav/Common/Service/ErrorServiceProvider.php index 3227365..02d38c9 100644 --- a/system/src/Grav/Common/Service/ErrorServiceProvider.php +++ b/system/src/Grav/Common/Service/ErrorServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/FilesystemServiceProvider.php b/system/src/Grav/Common/Service/FilesystemServiceProvider.php index 62dad5d..1dde5b3 100644 --- a/system/src/Grav/Common/Service/FilesystemServiceProvider.php +++ b/system/src/Grav/Common/Service/FilesystemServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/FlexServiceProvider.php b/system/src/Grav/Common/Service/FlexServiceProvider.php index 9c8cd49..e7b283a 100644 --- a/system/src/Grav/Common/Service/FlexServiceProvider.php +++ b/system/src/Grav/Common/Service/FlexServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/InflectorServiceProvider.php b/system/src/Grav/Common/Service/InflectorServiceProvider.php index 861a69e..f43a446 100644 --- a/system/src/Grav/Common/Service/InflectorServiceProvider.php +++ b/system/src/Grav/Common/Service/InflectorServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/LoggerServiceProvider.php b/system/src/Grav/Common/Service/LoggerServiceProvider.php index 5043cfb..43a67ca 100644 --- a/system/src/Grav/Common/Service/LoggerServiceProvider.php +++ b/system/src/Grav/Common/Service/LoggerServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/OutputServiceProvider.php b/system/src/Grav/Common/Service/OutputServiceProvider.php index 9a49185..2dbd343 100644 --- a/system/src/Grav/Common/Service/OutputServiceProvider.php +++ b/system/src/Grav/Common/Service/OutputServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/PagesServiceProvider.php b/system/src/Grav/Common/Service/PagesServiceProvider.php index 55f6a45..fa6631e 100644 --- a/system/src/Grav/Common/Service/PagesServiceProvider.php +++ b/system/src/Grav/Common/Service/PagesServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -99,7 +99,8 @@ class PagesServiceProvider implements ServiceProviderInterface /** @var Language $language */ $language = $grav['language']; - $redirectCode = (int)$config->get('system.pages.redirect_default_route', 0); + $redirect_default_route = $page->header()->redirect_default_route ?? $config->get('system.pages.redirect_default_route', 0); + $redirectCode = (int) $redirect_default_route; // Language-specific redirection scenarios if ($language->enabled() && ($language->isLanguageInUrl() xor $language->isIncludeDefaultLanguage())) { diff --git a/system/src/Grav/Common/Service/RequestServiceProvider.php b/system/src/Grav/Common/Service/RequestServiceProvider.php index 17b3149..a44c735 100644 --- a/system/src/Grav/Common/Service/RequestServiceProvider.php +++ b/system/src/Grav/Common/Service/RequestServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/SchedulerServiceProvider.php b/system/src/Grav/Common/Service/SchedulerServiceProvider.php index a952725..13918fb 100644 --- a/system/src/Grav/Common/Service/SchedulerServiceProvider.php +++ b/system/src/Grav/Common/Service/SchedulerServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/SessionServiceProvider.php b/system/src/Grav/Common/Service/SessionServiceProvider.php index 88c833f..80e24b4 100644 --- a/system/src/Grav/Common/Service/SessionServiceProvider.php +++ b/system/src/Grav/Common/Service/SessionServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -40,7 +40,8 @@ class SessionServiceProvider implements ServiceProviderInterface // Get session options. $enabled = (bool)$config->get('system.session.enabled', false); - $cookie_secure = (bool)$config->get('system.session.secure', false); + $cookie_secure = $config->get('system.session.secure', false) + || ($config->get('system.session.secure_https', true) && $uri->scheme(true) === 'https'); $cookie_httponly = (bool)$config->get('system.session.httponly', true); $cookie_lifetime = (int)$config->get('system.session.timeout', 1800); $cookie_domain = $config->get('system.session.domain'); diff --git a/system/src/Grav/Common/Service/StreamsServiceProvider.php b/system/src/Grav/Common/Service/StreamsServiceProvider.php index edde09a..f501b49 100644 --- a/system/src/Grav/Common/Service/StreamsServiceProvider.php +++ b/system/src/Grav/Common/Service/StreamsServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Service/TaskServiceProvider.php b/system/src/Grav/Common/Service/TaskServiceProvider.php index 49ce147..2989e9d 100644 --- a/system/src/Grav/Common/Service/TaskServiceProvider.php +++ b/system/src/Grav/Common/Service/TaskServiceProvider.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Service * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Session.php b/system/src/Grav/Common/Session.php index 3221627..513143e 100644 --- a/system/src/Grav/Common/Session.php +++ b/system/src/Grav/Common/Session.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Taxonomy.php b/system/src/Grav/Common/Taxonomy.php index 0d0a450..5079a25 100644 --- a/system/src/Grav/Common/Taxonomy.php +++ b/system/src/Grav/Common/Taxonomy.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Theme.php b/system/src/Grav/Common/Theme.php index a5006a2..6013129 100644 --- a/system/src/Grav/Common/Theme.php +++ b/system/src/Grav/Common/Theme.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index 6126841..3567cca 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/Exception/TwigException.php b/system/src/Grav/Common/Twig/Exception/TwigException.php index 8f543dc..7605de4 100644 --- a/system/src/Grav/Common/Twig/Exception/TwigException.php +++ b/system/src/Grav/Common/Twig/Exception/TwigException.php @@ -3,17 +3,19 @@ /** * @package Grav\Common\Twig\Exception * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Common\Twig\Exception; +use RuntimeException; + /** * TwigException gets thrown when you use {% throw code message %} in twig. * * This allows Grav to catch 401, 403 and 404 exceptions and display proper error page. */ -class TwigException extends \RuntimeException +class TwigException extends RuntimeException { } diff --git a/system/src/Grav/Common/Twig/Extension/FilesystemExtension.php b/system/src/Grav/Common/Twig/Extension/FilesystemExtension.php index dfd5fdd..0ae793e 100644 --- a/system/src/Grav/Common/Twig/Extension/FilesystemExtension.php +++ b/system/src/Grav/Common/Twig/Extension/FilesystemExtension.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -266,24 +266,24 @@ class FilesystemExtension extends AbstractExtension } /** - * @param string $file + * @param string $filename * @param string|null $required_sections * @param bool $as_arrays * @param bool $read_thumbnail * @return array|false */ - public function exif_read_data($file, ?string $required_sections, bool $as_arrays = false, bool $read_thumbnail = false) + public function exif_read_data($filename, ?string $required_sections, bool $as_arrays = false, bool $read_thumbnail = false) { - if (!Utils::functionExists('exif_read_data') || !$this->checkFilename($file)) { + if (!Utils::functionExists('exif_read_data') || !$this->checkFilename($filename)) { return false; } - return exif_read_data($file, $required_sections, $as_arrays, $read_thumbnail); + return exif_read_data($filename, $required_sections, $as_arrays, $read_thumbnail); } /** * @param string $filename - * @return string|false + * @return int|false */ public function exif_imagetype($filename) { @@ -311,18 +311,18 @@ class FilesystemExtension extends AbstractExtension /** * @param string $algo - * @param string $data + * @param string $filename * @param string $key * @param bool $binary * @return string|false */ - public function hash_hmac_file(string $algo, string $data, string $key, bool $binary = false) + public function hash_hmac_file(string $algo, string $filename, string $key, bool $binary = false) { - if (!$this->checkFilename($data)) { + if (!$this->checkFilename($filename)) { return false; } - return hash_hmac_file($algo, $data, $key, $binary); + return hash_hmac_file($algo, $filename, $key, $binary); } /** @@ -373,11 +373,7 @@ class FilesystemExtension extends AbstractExtension */ public function pathinfo($path, $flags = null) { - if (null !== $flags) { - return pathinfo($path, (int)$flags); - } - - return pathinfo($path); + return Utils::pathinfo($path, $flags); } /** diff --git a/system/src/Grav/Common/Twig/Extension/GravExtension.php b/system/src/Grav/Common/Twig/Extension/GravExtension.php index 4c0d9fe..52e2a18 100644 --- a/system/src/Grav/Common/Twig/Extension/GravExtension.php +++ b/system/src/Grav/Common/Twig/Extension/GravExtension.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -22,6 +22,7 @@ use Grav\Common\Page\Media; use Grav\Common\Scheduler\Cron; use Grav\Common\Security; use Grav\Common\Twig\TokenParser\TwigTokenParserCache; +use Grav\Common\Twig\TokenParser\TwigTokenParserLink; use Grav\Common\Twig\TokenParser\TwigTokenParserRender; use Grav\Common\Twig\TokenParser\TwigTokenParserScript; use Grav\Common\Twig\TokenParser\TwigTokenParserStyle; @@ -115,6 +116,7 @@ class GravExtension extends AbstractExtension implements GlobalsInterface new TwigFilter('defined', [$this, 'definedDefaultFilter']), new TwigFilter('ends_with', [$this, 'endsWithFilter']), new TwigFilter('fieldName', [$this, 'fieldNameFilter']), + new TwigFilter('parent_field', [$this, 'fieldParentFilter']), new TwigFilter('ksort', [$this, 'ksortFilter']), new TwigFilter('ltrim', [$this, 'ltrimFilter']), new TwigFilter('markdown', [$this, 'markdownFunction'], ['needs_context' => true, 'is_safe' => ['html']]), @@ -252,12 +254,17 @@ class GravExtension extends AbstractExtension implements GlobalsInterface new TwigTokenParserTryCatch(), new TwigTokenParserScript(), new TwigTokenParserStyle(), + new TwigTokenParserLink(), new TwigTokenParserMarkdown(), new TwigTokenParserSwitch(), new TwigTokenParserCache(), ]; } + /** + * @param mixed $var + * @return string + */ public function print_r($var) { return print_r($var, true); @@ -276,6 +283,20 @@ class GravExtension extends AbstractExtension implements GlobalsInterface return array_shift($path) . ($path ? '[' . implode('][', $path) . ']' : ''); } + /** + * Filters field name by changing dot notation into array notation. + * + * @param string $str + * @return string + */ + public function fieldParentFilter($str) + { + $path = explode('.', rtrim($str, '.')); + array_pop($path); + + return implode('.', $path); + } + /** * Protects email address. * diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeCache.php b/system/src/Grav/Common/Twig/Node/TwigNodeCache.php index 0ed1fff..e05e372 100644 --- a/system/src/Grav/Common/Twig/Node/TwigNodeCache.php +++ b/system/src/Grav/Common/Twig/Node/TwigNodeCache.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeLink.php b/system/src/Grav/Common/Twig/Node/TwigNodeLink.php new file mode 100644 index 0000000..a468633 --- /dev/null +++ b/system/src/Grav/Common/Twig/Node/TwigNodeLink.php @@ -0,0 +1,114 @@ + $file, 'group' => $group, 'priority' => $priority, 'attributes' => $attributes]; + $nodes = array_filter($nodes); + + parent::__construct($nodes, ['rel' => $rel], $lineno, $tag); + } + + /** + * Compiles the node to PHP. + * + * @param Compiler $compiler A Twig Compiler instance + * @return void + * @throws LogicException + */ + public function compile(Compiler $compiler): void + { + $compiler->addDebugInfo($this); + if (!$this->hasNode('file')) { + return; + } + + $compiler->write('$attributes = [\'rel\' => \'' . $this->getAttribute('rel') . '\'];' . "\n"); + if ($this->hasNode('attributes')) { + $compiler + ->write('$attributes += ') + ->subcompile($this->getNode('attributes')) + ->raw(';' . PHP_EOL) + ->write('if (!is_array($attributes)) {' . PHP_EOL) + ->indent() + ->write("throw new UnexpectedValueException('{% {$this->tagName} with x %}: x is not an array');" . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } + + if ($this->hasNode('group')) { + $compiler + ->write('$group = ') + ->subcompile($this->getNode('group')) + ->raw(';' . PHP_EOL) + ->write('if (!is_string($group)) {' . PHP_EOL) + ->indent() + ->write("throw new UnexpectedValueException('{% {$this->tagName} in x %}: x is not a string');" . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } else { + $compiler->write('$group = \'head\';' . PHP_EOL); + } + + if ($this->hasNode('priority')) { + $compiler + ->write('$priority = (int)(') + ->subcompile($this->getNode('priority')) + ->raw(');' . PHP_EOL); + } else { + $compiler->write('$priority = 10;' . PHP_EOL); + } + + $compiler->write("\$assets = \\Grav\\Common\\Grav::instance()['assets'];" . PHP_EOL); + $compiler->write("\$block = \$context['block'] ?? null;" . PHP_EOL); + + $compiler + ->write('$file = (string)(') + ->subcompile($this->getNode('file')) + ->raw(');' . PHP_EOL); + + // Assets support. + $compiler->write('$assets->addLink($file, [\'group\' => $group, \'priority\' => $priority] + $attributes);' . PHP_EOL); + + // HtmlBlock support. + $compiler + ->write('if ($block instanceof \Grav\Framework\ContentBlock\HtmlBlock) {' . PHP_EOL) + ->indent() + ->write('$block->addLink([\'href\'=> $file] + $attributes, $priority, $group);' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + } +} diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeMarkdown.php b/system/src/Grav/Common/Twig/Node/TwigNodeMarkdown.php index 81cecae..4637db7 100644 --- a/system/src/Grav/Common/Twig/Node/TwigNodeMarkdown.php +++ b/system/src/Grav/Common/Twig/Node/TwigNodeMarkdown.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeRender.php b/system/src/Grav/Common/Twig/Node/TwigNodeRender.php index 798c6ba..dbce3c6 100644 --- a/system/src/Grav/Common/Twig/Node/TwigNodeRender.php +++ b/system/src/Grav/Common/Twig/Node/TwigNodeRender.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -75,6 +75,7 @@ class TwigNodeRender extends Node implements NodeCaptureInterface ->outdent() ->write('} else {' . PHP_EOL) ->indent() + ->write('\Grav\Common\Assets\BlockAssets::registerAssets($html);' . PHP_EOL) ->write('echo (string)$html;' . PHP_EOL) ->outdent() ->write('}' . PHP_EOL) diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeScript.php b/system/src/Grav/Common/Twig/Node/TwigNodeScript.php index 46a0870..03554bd 100644 --- a/system/src/Grav/Common/Twig/Node/TwigNodeScript.php +++ b/system/src/Grav/Common/Twig/Node/TwigNodeScript.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -27,6 +27,7 @@ class TwigNodeScript extends Node implements NodeCaptureInterface /** * TwigNodeScript constructor. * @param Node|null $body + * @param string|null $type * @param AbstractExpression|null $file * @param AbstractExpression|null $group * @param AbstractExpression|null $priority @@ -34,12 +35,12 @@ class TwigNodeScript extends Node implements NodeCaptureInterface * @param int $lineno * @param string|null $tag */ - public function __construct(?Node $body, ?AbstractExpression $file, ?AbstractExpression $group, ?AbstractExpression $priority, ?AbstractExpression $attributes, $lineno = 0, $tag = null) + public function __construct(?Node $body, ?string $type, ?AbstractExpression $file, ?AbstractExpression $group, ?AbstractExpression $priority, ?AbstractExpression $attributes, $lineno = 0, $tag = null) { $nodes = ['body' => $body, 'file' => $file, 'group' => $group, 'priority' => $priority, 'attributes' => $attributes]; $nodes = array_filter($nodes); - parent::__construct($nodes, [], $lineno, $tag); + parent::__construct($nodes, ['type' => $type], $lineno, $tag); } /** @@ -53,52 +54,89 @@ class TwigNodeScript extends Node implements NodeCaptureInterface { $compiler->addDebugInfo($this); - $compiler->write("\$assets = \\Grav\\Common\\Grav::instance()['assets'];\n"); - if ($this->hasNode('attributes')) { $compiler ->write('$attributes = ') ->subcompile($this->getNode('attributes')) - ->raw(";\n") - ->write("if (!is_array(\$attributes)) {\n") + ->raw(';' . PHP_EOL) + ->write('if (!is_array($attributes)) {' . PHP_EOL) ->indent() - ->write("throw new UnexpectedValueException('{% {$this->tagName} with x %}: x is not an array');\n") + ->write("throw new UnexpectedValueException('{% {$this->tagName} with x %}: x is not an array');" . PHP_EOL) ->outdent() - ->write("}\n"); + ->write('}' . PHP_EOL); } else { - $compiler->write('$attributes = [];' . "\n"); + $compiler->write('$attributes = [];' . PHP_EOL); } if ($this->hasNode('group')) { $compiler - ->write("\$attributes['group'] = ") + ->write('$group = ') ->subcompile($this->getNode('group')) - ->raw(";\n") - ->write("if (!is_string(\$attributes['group'])) {\n") + ->raw(';' . PHP_EOL) + ->write('if (!is_string($group)) {' . PHP_EOL) ->indent() - ->write("throw new UnexpectedValueException('{% {$this->tagName} in x %}: x is not a string');\n") + ->write("throw new UnexpectedValueException('{% {$this->tagName} in x %}: x is not a string');" . PHP_EOL) ->outdent() - ->write("}\n"); + ->write('}' . PHP_EOL); + } else { + $compiler->write('$group = \'head\';' . PHP_EOL); } if ($this->hasNode('priority')) { $compiler - ->write("\$attributes['priority'] = (int)(") + ->write('$priority = (int)(') ->subcompile($this->getNode('priority')) - ->raw(");\n"); + ->raw(');' . PHP_EOL); + } else { + $compiler->write('$priority = 10;' . PHP_EOL); } + $compiler->write("\$assets = \\Grav\\Common\\Grav::instance()['assets'];" . PHP_EOL); + $compiler->write("\$block = \$context['block'] ?? null;" . PHP_EOL); + if ($this->hasNode('file')) { + // JS file. $compiler - ->write('$assets->addJs(') + ->write('$file = (string)(') ->subcompile($this->getNode('file')) - ->raw(", \$attributes);\n"); - } else { + ->raw(');' . PHP_EOL); + + $method = $this->getAttribute('type') === 'module' ? 'addJsModule' : 'addJs'; + + // Assets support. + $compiler->write('$assets->' . $method . '($file, [\'group\' => $group, \'priority\' => $priority] + $attributes);' . PHP_EOL); + + $method = $this->getAttribute('type') === 'module' ? 'addModule' : 'addScript'; + + // HtmlBlock support. $compiler - ->write("ob_start();\n") + ->write('if ($block instanceof \Grav\Framework\ContentBlock\HtmlBlock) {' . PHP_EOL) + ->indent() + ->write('$block->' . $method . '([\'src\'=> $file] + $attributes, $priority, $group);' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + + } else { + // Inline script. + $compiler + ->write('ob_start();' . PHP_EOL) ->subcompile($this->getNode('body')) - ->write('$content = ob_get_clean();' . "\n") - ->write("\$assets->addInlineJs(\$content, \$attributes);\n"); + ->write('$content = ob_get_clean();' . PHP_EOL); + + $method = $this->getAttribute('type') === 'module' ? 'addInlineJsModule' : 'addInlineJs'; + + // Assets support. + $compiler->write('$assets->' . $method . '($content, [\'group\' => $group, \'priority\' => $priority] + $attributes);' . PHP_EOL); + + $method = $this->getAttribute('type') === 'module' ? 'addInlineModule' : 'addInlineScript'; + + // HtmlBlock support. + $compiler + ->write('if ($block instanceof \Grav\Framework\ContentBlock\HtmlBlock) {' . PHP_EOL) + ->indent() + ->write('$block->' . $method . '([\'content\'=> $content] + $attributes, $priority, $group);' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); } } } diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeStyle.php b/system/src/Grav/Common/Twig/Node/TwigNodeStyle.php index 05355f9..1c3568c 100644 --- a/system/src/Grav/Common/Twig/Node/TwigNodeStyle.php +++ b/system/src/Grav/Common/Twig/Node/TwigNodeStyle.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -41,6 +41,7 @@ class TwigNodeStyle extends Node implements NodeCaptureInterface parent::__construct($nodes, [], $lineno, $tag); } + /** * Compiles the node to PHP. * @@ -52,52 +53,81 @@ class TwigNodeStyle extends Node implements NodeCaptureInterface { $compiler->addDebugInfo($this); - $compiler->write("\$assets = \\Grav\\Common\\Grav::instance()['assets'];\n"); - if ($this->hasNode('attributes')) { $compiler ->write('$attributes = ') ->subcompile($this->getNode('attributes')) - ->raw(";\n") - ->write("if (!is_array(\$attributes)) {\n") + ->raw(';' . PHP_EOL) + ->write('if (!is_array($attributes)) {' . PHP_EOL) ->indent() - ->write("throw new UnexpectedValueException('{% {$this->tagName} with x %}: x is not an array');\n") + ->write("throw new UnexpectedValueException('{% {$this->tagName} with x %}: x is not an array');" . PHP_EOL) ->outdent() - ->write("}\n"); + ->write('}' . PHP_EOL); } else { - $compiler->write('$attributes = [];' . "\n"); + $compiler->write('$attributes = [];' . PHP_EOL); } if ($this->hasNode('group')) { $compiler - ->write("\$attributes['group'] = ") + ->write('$group = ') ->subcompile($this->getNode('group')) - ->raw(";\n") - ->write("if (!is_string(\$attributes['group'])) {\n") + ->raw(';' . PHP_EOL) + ->write('if (!is_string($group)) {' . PHP_EOL) ->indent() - ->write("throw new UnexpectedValueException('{% {$this->tagName} in x %}: x is not a string');\n") + ->write("throw new UnexpectedValueException('{% {$this->tagName} in x %}: x is not a string');" . PHP_EOL) ->outdent() - ->write("}\n"); + ->write('}' . PHP_EOL); + } else { + $compiler->write('$group = \'head\';' . PHP_EOL); } if ($this->hasNode('priority')) { $compiler - ->write("\$attributes['priority'] = (int)(") + ->write('$priority = (int)(') ->subcompile($this->getNode('priority')) - ->raw(");\n"); + ->raw(');' . PHP_EOL); + } else { + $compiler->write('$priority = 10;' . PHP_EOL); } + $compiler->write("\$assets = \\Grav\\Common\\Grav::instance()['assets'];" . PHP_EOL); + $compiler->write("\$block = \$context['block'] ?? null;" . PHP_EOL); + if ($this->hasNode('file')) { + // CSS file. $compiler - ->write('$assets->addCss(') + ->write('$file = (string)(') ->subcompile($this->getNode('file')) - ->raw(", \$attributes);\n"); - } else { + ->raw(');' . PHP_EOL); + + // Assets support. + $compiler->write('$assets->addCss($file, [\'group\' => $group, \'priority\' => $priority] + $attributes);' . PHP_EOL); + + // HtmlBlock support. $compiler - ->write("ob_start();\n") + ->write('if ($block instanceof \Grav\Framework\ContentBlock\HtmlBlock) {' . PHP_EOL) + ->indent() + ->write('$block->addStyle([\'href\'=> $file] + $attributes, $priority, $group);' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); + + } else { + // Inline style. + $compiler + ->write('ob_start();' . PHP_EOL) ->subcompile($this->getNode('body')) - ->write('$content = ob_get_clean();' . "\n") - ->write("\$assets->addInlineCss(\$content, \$attributes);\n"); + ->write('$content = ob_get_clean();' . PHP_EOL); + + // Assets support. + $compiler->write('$assets->addInlineCss($content, [\'group\' => $group, \'priority\' => $priority] + $attributes);' . PHP_EOL); + + // HtmlBlock support. + $compiler + ->write('if ($block instanceof \Grav\Framework\ContentBlock\HtmlBlock) {' . PHP_EOL) + ->indent() + ->write('$block->addInlineStyle([\'content\'=> $content] + $attributes, $priority, $group);' . PHP_EOL) + ->outdent() + ->write('}' . PHP_EOL); } } } diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeSwitch.php b/system/src/Grav/Common/Twig/Node/TwigNodeSwitch.php index 43ae56f..7bd368e 100644 --- a/system/src/Grav/Common/Twig/Node/TwigNodeSwitch.php +++ b/system/src/Grav/Common/Twig/Node/TwigNodeSwitch.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeThrow.php b/system/src/Grav/Common/Twig/Node/TwigNodeThrow.php index 3bfe612..41ca15d 100644 --- a/system/src/Grav/Common/Twig/Node/TwigNodeThrow.php +++ b/system/src/Grav/Common/Twig/Node/TwigNodeThrow.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/Node/TwigNodeTryCatch.php b/system/src/Grav/Common/Twig/Node/TwigNodeTryCatch.php index 40e9240..1213b7c 100644 --- a/system/src/Grav/Common/Twig/Node/TwigNodeTryCatch.php +++ b/system/src/Grav/Common/Twig/Node/TwigNodeTryCatch.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php index 371e89a..1cf2191 100644 --- a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserCache.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserLink.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserLink.php new file mode 100644 index 0000000..2cb0208 --- /dev/null +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserLink.php @@ -0,0 +1,109 @@ +getLine(); + + [$rel, $file, $group, $priority, $attributes] = $this->parseArguments($token); + + return new TwigNodeLink($rel, $file, $group, $priority, $attributes, $lineno, $this->getTag()); + } + + /** + * @param Token $token + * @return array + */ + protected function parseArguments(Token $token): array + { + $stream = $this->parser->getStream(); + + + $rel = null; + if ($stream->test(Token::NAME_TYPE, $this->rel)) { + $rel = $stream->getCurrent()->getValue(); + $stream->next(); + } + + $file = null; + if (!$stream->test(Token::NAME_TYPE) && !$stream->test(Token::BLOCK_END_TYPE)) { + $file = $this->parser->getExpressionParser()->parseExpression(); + } + + $group = null; + if ($stream->nextIf(Token::NAME_TYPE, 'at')) { + $group = $this->parser->getExpressionParser()->parseExpression(); + } + + $priority = null; + if ($stream->nextIf(Token::NAME_TYPE, 'priority')) { + $stream->expect(Token::PUNCTUATION_TYPE, ':'); + $priority = $this->parser->getExpressionParser()->parseExpression(); + } + + $attributes = null; + if ($stream->nextIf(Token::NAME_TYPE, 'with')) { + $attributes = $this->parser->getExpressionParser()->parseExpression(); + } + + $stream->expect(Token::BLOCK_END_TYPE); + + return [$rel, $file, $group, $priority, $attributes]; + } + + /** + * Gets the tag name associated with this token parser. + * + * @return string The tag name + */ + public function getTag(): string + { + return 'link'; + } +} diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserMarkdown.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserMarkdown.php index 9dab4ae..49e34e6 100644 --- a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserMarkdown.php +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserMarkdown.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserRender.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserRender.php index ab2bdde..de16266 100644 --- a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserRender.php +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserRender.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserScript.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserScript.php index b860631..b943a25 100644 --- a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserScript.php +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserScript.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -15,14 +15,20 @@ use Twig\Token; use Twig\TokenParser\AbstractTokenParser; /** - * Adds a script to head/bottom/custom location in the document. + * Adds a script to head/bottom/custom group location in the document. * - * {% script 'theme://js/something.js' at 'bottom' priority: 20 with { defer: true, async: true } %} + * {% script 'theme://js/something.js' at 'bottom' priority: 20 with { position: 'pipeline', loading: 'async defer' } %} + * {% script module 'theme://js/module.mjs' at 'head' %} * + * {% script 'theme://js/something.js' at 'bottom' priority: 20 with { loading: 'inline' } %} * {% script at 'bottom' priority: 20 %} - * alert('Warning!'); + * alert('Warning!'); + * {% endscript %} + * + * {% script module 'theme://js/module.mjs' at 'bottom' with { loading: 'inline' } %} + * {% script module at 'bottom' %} + * ... * {% endscript %} - */ class TwigTokenParserScript extends AbstractTokenParser { @@ -38,7 +44,7 @@ class TwigTokenParserScript extends AbstractTokenParser $lineno = $token->getLine(); $stream = $this->parser->getStream(); - [$file, $group, $priority, $attributes] = $this->parseArguments($token); + [$type, $file, $group, $priority, $attributes] = $this->parseArguments($token); $content = null; if ($file === null) { @@ -46,7 +52,7 @@ class TwigTokenParserScript extends AbstractTokenParser $stream->expect(Token::BLOCK_END_TYPE); } - return new TwigNodeScript($content, $file, $group, $priority, $attributes, $lineno, $this->getTag()); + return new TwigNodeScript($content, $type, $file, $group, $priority, $attributes, $lineno, $this->getTag()); } /** @@ -73,6 +79,12 @@ class TwigTokenParserScript extends AbstractTokenParser } while (true); } + $type = null; + if ($stream->test(Token::NAME_TYPE, 'module')) { + $type = $stream->getCurrent()->getValue(); + $stream->next(); + } + $file = null; if (!$stream->test(Token::NAME_TYPE) && !$stream->test(Token::OPERATOR_TYPE, 'in') && !$stream->test(Token::BLOCK_END_TYPE)) { $file = $this->parser->getExpressionParser()->parseExpression(); @@ -96,7 +108,7 @@ class TwigTokenParserScript extends AbstractTokenParser $stream->expect(Token::BLOCK_END_TYPE); - return [$file, $group, $priority, $attributes]; + return [$type, $file, $group, $priority, $attributes]; } /** diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserStyle.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserStyle.php index c8d9544..0687395 100644 --- a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserStyle.php +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserStyle.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserSwitch.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserSwitch.php index 4540bbf..c63fe95 100644 --- a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserSwitch.php +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserSwitch.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. * @origin https://gist.github.com/maxgalbu/9409182 */ diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserThrow.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserThrow.php index bd4adab..41f415d 100644 --- a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserThrow.php +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserThrow.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserTryCatch.php b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserTryCatch.php index 46af176..9930632 100644 --- a/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserTryCatch.php +++ b/system/src/Grav/Common/Twig/TokenParser/TwigTokenParserTryCatch.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/Twig.php b/system/src/Grav/Common/Twig/Twig.php index 19bad01..39ae3c6 100644 --- a/system/src/Grav/Common/Twig/Twig.php +++ b/system/src/Grav/Common/Twig/Twig.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -33,6 +33,7 @@ use Twig\Extension\DebugExtension; use Twig\Extension\StringLoaderExtension; use Twig\Loader\ArrayLoader; use Twig\Loader\ChainLoader; +use Twig\Loader\ExistsLoaderInterface; use Twig\Loader\FilesystemLoader; use Twig\Profiler\Profile; use Twig\TwigFilter; @@ -160,7 +161,7 @@ class Twig $this->twig = new TwigEnvironment($loader_chain, $params); - $this->twig->registerUndefinedFunctionCallback(function ($name) use ($config) { + $this->twig->registerUndefinedFunctionCallback(function (string $name) use ($config) { $allowed = $config->get('system.twig.safe_functions'); if (is_array($allowed) && in_array($name, $allowed, true) && function_exists($name)) { return new TwigFunction($name, $name); @@ -184,7 +185,7 @@ class Twig return false; }); - $this->twig->registerUndefinedFilterCallback(function ($name) use ($config) { + $this->twig->registerUndefinedFilterCallback(function (string $name) use ($config) { $allowed = $config->get('system.twig.safe_filters'); if (is_array($allowed) && in_array($name, $allowed, true) && function_exists($name)) { return new TwigFilter($name, $name); @@ -514,6 +515,8 @@ class Twig $twig_extension = $extension ? '.'. $extension .TWIG_EXT : TEMPLATE_EXT; $template_file = $this->template($page->template() . $twig_extension); + // TODO: no longer needed in Twig 3. + /** @var ExistsLoaderInterface $loader */ $loader = $this->twig->getLoader(); if ($loader->exists($template_file)) { // template.xxx.twig diff --git a/system/src/Grav/Common/Twig/TwigClockworkDataSource.php b/system/src/Grav/Common/Twig/TwigClockworkDataSource.php index 11127b8..407a05e 100644 --- a/system/src/Grav/Common/Twig/TwigClockworkDataSource.php +++ b/system/src/Grav/Common/Twig/TwigClockworkDataSource.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/TwigClockworkDumper.php b/system/src/Grav/Common/Twig/TwigClockworkDumper.php index 2c1f4be..c960cf2 100644 --- a/system/src/Grav/Common/Twig/TwigClockworkDumper.php +++ b/system/src/Grav/Common/Twig/TwigClockworkDumper.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/TwigEnvironment.php b/system/src/Grav/Common/Twig/TwigEnvironment.php index bebbdf1..dba8846 100644 --- a/system/src/Grav/Common/Twig/TwigEnvironment.php +++ b/system/src/Grav/Common/Twig/TwigEnvironment.php @@ -3,13 +3,18 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Common\Twig; use Twig\Environment; +use Twig\Error\LoaderError; +use Twig\Loader\ExistsLoaderInterface; +use Twig\Loader\LoaderInterface; +use Twig\Template; +use Twig\TemplateWrapper; /** * Class TwigEnvironment @@ -18,4 +23,38 @@ use Twig\Environment; class TwigEnvironment extends Environment { use WriteCacheFileTrait; + + /** + * @inheritDoc + */ + public function resolveTemplate($names) + { + if (!\is_array($names)) { + $names = [$names]; + } + + $count = \count($names); + foreach ($names as $name) { + if ($name instanceof Template) { + return $name; + } + if ($name instanceof TemplateWrapper) { + return $name; + } + + // Optimization: Avoid throwing an exception when it would be ignored anyway. + if (1 !== $count) { + /** @var LoaderInterface|ExistsLoaderInterface $loader */ + $loader = $this->getLoader(); + if (!$loader->exists($name)) { + continue; + } + } + + // Throws LoaderError: Unable to find template "%s". + return $this->loadTemplate($name); + } + + throw new LoaderError(sprintf('Unable to find one of the following templates: "%s".', implode('", "', $names))); + } } diff --git a/system/src/Grav/Common/Twig/TwigExtension.php b/system/src/Grav/Common/Twig/TwigExtension.php index 698858b..07c442e 100644 --- a/system/src/Grav/Common/Twig/TwigExtension.php +++ b/system/src/Grav/Common/Twig/TwigExtension.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Twig/WriteCacheFileTrait.php b/system/src/Grav/Common/Twig/WriteCacheFileTrait.php index edab8e5..575a281 100644 --- a/system/src/Grav/Common/Twig/WriteCacheFileTrait.php +++ b/system/src/Grav/Common/Twig/WriteCacheFileTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Twig * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index 7bef097..76d9a99 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -165,7 +165,7 @@ class Uri } // Handle custom base - $custom_base = rtrim($grav['config']->get('system.custom_base_url'), '/'); + $custom_base = rtrim($grav['config']->get('system.custom_base_url', ''), '/'); if ($custom_base) { $custom_parts = parse_url($custom_base); if ($custom_parts === false) { @@ -217,7 +217,7 @@ class Uri $path = $bits['path'] ?? '/'; // remove the extension if there is one set - $parts = pathinfo($path); + $parts = Utils::pathinfo($path); // set the original basename $this->basename = $parts['basename']; @@ -337,9 +337,9 @@ class Uri /** * Get URI parameter. * - * @param string|null $id - * @param string|bool|null $default - * @return bool|string + * @param string $id + * @param string|false|null $default + * @return string|false|null */ public function param($id, $default = false) { @@ -623,6 +623,7 @@ class Uri /** * @return string */ + #[\ReturnTypeWillChange] public function __toString() { return static::buildUrl($this->toArray()); @@ -853,7 +854,7 @@ class Uri } if ($full_path) { - $path_info = pathinfo($full_path); + $path_info = Utils::pathinfo($full_path); $page_path = $path_info['dirname']; $filename = ''; @@ -898,7 +899,7 @@ class Uri $routes = $pages->routes(); // if this is an image, get the proper path - $url_bits = pathinfo($url_path); + $url_bits = Utils::pathinfo($url_path); if (isset($url_bits['extension'])) { $target_path = $url_bits['dirname']; } else { @@ -1045,7 +1046,7 @@ class Uri $base_url = rtrim($base . $grav['pages']->base(), '/') . $language_append; // if absolute and starts with a base_url move on - if (pathinfo($markdown_url, PATHINFO_DIRNAME) === '.' && $page->url() === '/') { + if (Utils::pathinfo($markdown_url, PATHINFO_DIRNAME) === '.' && $page->url() === '/') { return '/' . $markdown_url; } // no path to convert @@ -1084,7 +1085,7 @@ class Uri return $normalized_url; } - $path_info = pathinfo($full_path); + $path_info = Utils::pathinfo($full_path); $page_path = $path_info['dirname']; $filename = ''; @@ -1272,9 +1273,9 @@ class Uri $this->path = rawurldecode(parse_url('http://example.com' . $request_uri, PHP_URL_PATH)); // Build query string. - $this->query = $env['QUERY_STRING'] ?? ''; + $this->query = $env['QUERY_STRING'] ?? ''; if ($this->query === '') { - $this->query = parse_url('http://example.com' . $request_uri, PHP_URL_QUERY); + $this->query = parse_url('http://example.com' . $request_uri, PHP_URL_QUERY) ?? ''; } // Support ngnix routes. diff --git a/system/src/Grav/Common/User/Access.php b/system/src/Grav/Common/User/Access.php index 6503c89..96f4d96 100644 --- a/system/src/Grav/Common/User/Access.php +++ b/system/src/Grav/Common/User/Access.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/User/Authentication.php b/system/src/Grav/Common/User/Authentication.php index 6ff95e7..c32fd62 100644 --- a/system/src/Grav/Common/User/Authentication.php +++ b/system/src/Grav/Common/User/Authentication.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/User/DataUser/User.php b/system/src/Grav/Common/User/DataUser/User.php index 8fcdbbb..9cd3904 100644 --- a/system/src/Grav/Common/User/DataUser/User.php +++ b/system/src/Grav/Common/User/DataUser/User.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -21,6 +21,7 @@ use Grav\Common\Page\Medium\MediumFactory; use Grav\Common\User\Authentication; use Grav\Common\User\Interfaces\UserInterface; use Grav\Common\User\Traits\UserTrait; +use Grav\Common\Utils; use Grav\Framework\Flex\Flex; use function is_array; @@ -177,7 +178,7 @@ class User extends Data implements UserInterface if ($path && is_file($path)) { $medium = MediumFactory::fromFile($path); if ($medium) { - $media->add(basename($path), $medium); + $media->add(Utils::basename($path), $medium); } } @@ -192,7 +193,7 @@ class User extends Data implements UserInterface */ public function getMediaFolder() { - return $this->blueprints()->fields()['avatar']['destination'] ?? 'user://accounts/avatars'; + return $this->blueprints()->fields()['avatar']['destination'] ?? 'account://avatars'; } /** @@ -295,6 +296,7 @@ class User extends Data implements UserInterface * @return int * @deprecated 1.6 Method makes no sense for user account. */ + #[\ReturnTypeWillChange] public function count() { user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED); diff --git a/system/src/Grav/Common/User/DataUser/UserCollection.php b/system/src/Grav/Common/User/DataUser/UserCollection.php index 3da7e2d..d0ada09 100644 --- a/system/src/Grav/Common/User/DataUser/UserCollection.php +++ b/system/src/Grav/Common/User/DataUser/UserCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -114,7 +114,7 @@ class UserCollection implements UserCollectionInterface if (!$user->exists()) { foreach ($files as $file) { if (Utils::endsWith($file, YAML_EXT)) { - $find_user = $this->load(trim(pathinfo($file, PATHINFO_FILENAME))); + $find_user = $this->load(trim(Utils::pathinfo($file, PATHINFO_FILENAME))); foreach ($fields as $field) { if (isset($find_user[$field]) && $find_user[$field] === $query) { return $find_user; diff --git a/system/src/Grav/Common/User/Group.php b/system/src/Grav/Common/User/Group.php index 7dd6d65..9be619a 100644 --- a/system/src/Grav/Common/User/Group.php +++ b/system/src/Grav/Common/User/Group.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/User/Interfaces/AuthorizeInterface.php b/system/src/Grav/Common/User/Interfaces/AuthorizeInterface.php index 3ad8d2c..1aeb004 100644 --- a/system/src/Grav/Common/User/Interfaces/AuthorizeInterface.php +++ b/system/src/Grav/Common/User/Interfaces/AuthorizeInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/User/Interfaces/UserCollectionInterface.php b/system/src/Grav/Common/User/Interfaces/UserCollectionInterface.php index d892e82..5bcfbc0 100644 --- a/system/src/Grav/Common/User/Interfaces/UserCollectionInterface.php +++ b/system/src/Grav/Common/User/Interfaces/UserCollectionInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/User/Interfaces/UserGroupInterface.php b/system/src/Grav/Common/User/Interfaces/UserGroupInterface.php index c345c4b..c18388c 100644 --- a/system/src/Grav/Common/User/Interfaces/UserGroupInterface.php +++ b/system/src/Grav/Common/User/Interfaces/UserGroupInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/User/Interfaces/UserInterface.php b/system/src/Grav/Common/User/Interfaces/UserInterface.php index 02827e3..dcd014c 100644 --- a/system/src/Grav/Common/User/Interfaces/UserInterface.php +++ b/system/src/Grav/Common/User/Interfaces/UserInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/User/Traits/UserTrait.php b/system/src/Grav/Common/User/Traits/UserTrait.php index 5a6b749..91c41aa 100644 --- a/system/src/Grav/Common/User/Traits/UserTrait.php +++ b/system/src/Grav/Common/User/Traits/UserTrait.php @@ -3,18 +3,21 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Common\User\Traits; +use Grav\Common\Filesystem\Folder; use Grav\Common\Grav; use Grav\Common\Page\Medium\ImageMedium; use Grav\Common\Page\Medium\Medium; use Grav\Common\Page\Medium\StaticImageMedium; use Grav\Common\User\Authentication; use Grav\Common\Utils; +use Multiavatar; +use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use function is_array; use function is_string; @@ -175,9 +178,52 @@ trait UserTrait } $email = $this->get('email'); + $avatar_generator = Grav::instance()['config']->get('system.accounts.avatar', 'multiavatar'); + if ($avatar_generator === 'gravatar') { + if (!$email) { + return ''; + } + + $hash = md5(strtolower(trim($email))); + + return 'https://www.gravatar.com/avatar/' . $hash; + } + + $hash = $this->get('avatar_hash'); + if (!$hash) { + $username = $this->get('username'); + $hash = md5(strtolower(trim($email ?? $username))); + } + + return $this->generateMultiavatar($hash); + } + + /** + * @param string $hash + * @return string + */ + protected function generateMultiavatar(string $hash): string + { + /** @var UniformResourceLocator $locator */ + $locator = Grav::instance()['locator']; + + $storage = $locator->findResource('image://multiavatar', true, true); + $avatar_file = "{$storage}/{$hash}.svg"; + + if (!file_exists($storage)) { + Folder::create($storage); + } + + if (!file_exists($avatar_file)) { + $mavatar = new Multiavatar(); + + file_put_contents($avatar_file, $mavatar->generate($hash, null, null)); + } + + $avatar_url = $locator->findResource("image://multiavatar/{$hash}.svg", false, true); + + return Utils::url($avatar_url); - // By default fall back to gravatar image. - return $email ? 'https://www.gravatar.com/avatar/' . md5(strtolower(trim($email))) : ''; } abstract public function get($name, $default = null, $separator = null); diff --git a/system/src/Grav/Common/User/User.php b/system/src/Grav/Common/User/User.php index 4b2319f..b38c72e 100644 --- a/system/src/Grav/Common/User/User.php +++ b/system/src/Grav/Common/User/User.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\User * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 5295a64..145a893 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -134,14 +134,13 @@ abstract class Utils $resource = $locator->findResource($input, false); } } else { - $root = $uri->rootUrl(); - - if (static::startsWith($input, $root)) { - $input = static::replaceFirstOccurrence($root, '', $input); + $root = preg_quote($uri->rootUrl(), '#'); + $pattern = '#(' . $root . '$|' . $root . '/)#'; + if (!empty($root) && preg_match($pattern, $input, $matches)) { + $input = static::replaceFirstOccurrence($matches[0], '', $input); } $input = ltrim($input, '/'); - $resource = $input; } @@ -653,16 +652,17 @@ abstract class Utils * @param bool $force_download as opposed to letting browser choose if to download or render * @param int $sec Throttling, try 0.1 for some speed throttling of downloads * @param int $bytes Size of chunks to send in bytes. Default is 1024 + * @param array $options Extra options: [mime, download_name, expires] * @throws Exception */ - public static function download($file, $force_download = true, $sec = 0, $bytes = 1024) + public static function download($file, $force_download = true, $sec = 0, $bytes = 1024, array $options = []) { if (file_exists($file)) { // fire download event - Grav::instance()->fireEvent('onBeforeDownload', new Event(['file' => $file])); + Grav::instance()->fireEvent('onBeforeDownload', new Event(['file' => $file, 'options' => &$options])); - $file_parts = pathinfo($file); - $mimetype = static::getMimeByExtension($file_parts['extension']); + $file_parts = static::pathinfo($file); + $mimetype = $options['mime'] ?? static::getMimeByExtension($file_parts['extension']); $size = filesize($file); // File size // clean all buffers @@ -680,7 +680,7 @@ abstract class Utils if ($force_download) { // output the regular HTTP headers - header('Content-Disposition: attachment; filename="' . $file_parts['basename'] . '"'); + header('Content-Disposition: attachment; filename="' . ($options['download_name'] ?? $file_parts['basename']) . '"'); } // multipart-download and download resuming support @@ -704,7 +704,7 @@ abstract class Utils header('Content-Length: ' . $size); if (Grav::instance()['config']->get('system.cache.enabled')) { - $expires = Grav::instance()['config']->get('system.pages.expires'); + $expires = $options['expires'] ?? Grav::instance()['config']->get('system.pages.expires'); if ($expires > 0) { $expires_date = gmdate('D, d M Y H:i:s T', time() + $expires); header('Cache-Control: max-age=' . $expires); @@ -830,6 +830,31 @@ abstract class Utils return $mimetypes; } + /** + * Return all extensions for given mimetype. The first extension is the default one. + * + * @param string $mime Mime type (eg 'image/jpeg') + * @return string[] List of extensions eg. ['jpg', 'jpe', 'jpeg'] + */ + public static function getExtensionsByMime($mime) + { + $mime = strtolower($mime); + + $media_types = (array)Grav::instance()['config']->get('media.types'); + + $list = []; + foreach ($media_types as $extension => $type) { + if ($extension === '' || $extension === 'defaults') { + continue; + } + + if (isset($type['mime']) && $type['mime'] === $mime) { + $list[] = $extension; + } + } + + return $list; + } /** * Return the mimetype based on filename extension @@ -900,7 +925,7 @@ abstract class Utils */ public static function getMimeByFilename($filename, $default = 'application/octet-stream') { - return static::getMimeByExtension(pathinfo($filename, PATHINFO_EXTENSION), $default); + return static::getMimeByExtension(static::pathinfo($filename, PATHINFO_EXTENSION), $default); } /** @@ -945,7 +970,7 @@ abstract class Utils public static function checkFilename($filename) { $dangerous_extensions = Grav::instance()['config']->get('security.uploads_dangerous_extensions', []); - $extension = pathinfo($filename, PATHINFO_EXTENSION); + $extension = static::pathinfo($filename, PATHINFO_EXTENSION); return !( // Empty filenames are not allowed. @@ -959,6 +984,46 @@ abstract class Utils ); } + /** + * Unicode-safe version of PHP’s pathinfo() function. + * + * @link https://www.php.net/manual/en/function.pathinfo.php + * + * @param string $path + * @param int|null $flags + * @return array|string + */ + public static function pathinfo($path, int $flags = null) + { + $path = str_replace(['%2F', '%5C'], ['/', '\\'], rawurlencode($path)); + + if (null === $flags) { + $info = pathinfo($path); + } else { + $info = pathinfo($path, $flags); + } + + if (is_array($info)) { + return array_map('rawurldecode', $info); + } + + return rawurldecode($info); + } + + /** + * Unicode-safe version of the PHP basename() function. + * + * @link https://www.php.net/manual/en/function.basename.php + * + * @param string $path + * @param string $suffix + * @return string + */ + public static function basename($path, string $suffix = ''): string + { + return rawurldecode(basename(str_replace(['%2F', '%5C'], '/', rawurlencode($path)), $suffix)); + } + /** * Normalize path by processing relative `.` and `..` syntax and merging path * @@ -1594,8 +1659,8 @@ abstract class Utils $route = '/' . $matches[2]; // Exclude filename from the page lookup. - if (pathinfo($route, PATHINFO_EXTENSION)) { - $basename = '/' . basename($route); + if (static::pathinfo($route, PATHINFO_EXTENSION)) { + $basename = '/' . static::basename($route); $route = \dirname($route); } else { $basename = ''; diff --git a/system/src/Grav/Common/Yaml.php b/system/src/Grav/Common/Yaml.php index 330b6c3..0758599 100644 --- a/system/src/Grav/Common/Yaml.php +++ b/system/src/Grav/Common/Yaml.php @@ -3,7 +3,7 @@ /** * @package Grav\Common * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Application/Application.php b/system/src/Grav/Console/Application/Application.php index 21cea87..873b94e 100644 --- a/system/src/Grav/Console/Application/Application.php +++ b/system/src/Grav/Console/Application/Application.php @@ -3,18 +3,21 @@ /** * @package Grav\Console * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Console\Application; use Grav\Common\Grav; +use Symfony\Component\Console\ConsoleEvents; +use Symfony\Component\Console\Event\ConsoleCommandEvent; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\EventDispatcher\EventDispatcher; /** * Class GpmApplication @@ -29,19 +32,48 @@ class Application extends \Symfony\Component\Console\Application /** @var bool */ protected $initialized = false; + /** + * PluginApplication constructor. + * @param string $name + * @param string $version + */ + public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN') + { + parent::__construct($name, $version); + + // Add listener to prepare environment. + $dispatcher = new EventDispatcher(); + $dispatcher->addListener(ConsoleEvents::COMMAND, [$this, 'prepareEnvironment']); + + $this->setDispatcher($dispatcher); + } + /** * @param InputInterface $input * @return string|null */ public function getCommandName(InputInterface $input): ?string { - $this->environment = $input->getOption('env'); - $this->language = $input->getOption('lang') ?? $this->language; + if ($input->hasParameterOption('--env', true)) { + $this->environment = $input->getParameterOption('--env'); + } + if ($input->hasParameterOption('--lang', true)) { + $this->language = $input->getParameterOption('--lang'); + } + $this->init(); return parent::getCommandName($input); } + /** + * @param ConsoleCommandEvent $event + * @return void + */ + public function prepareEnvironment(ConsoleCommandEvent $event): void + { + } + /** * @return void */ @@ -58,7 +90,7 @@ class Application extends \Symfony\Component\Console\Application } /** - * Add global a --env option. + * Add global --env and --lang options. * * @return InputDefinition */ @@ -67,16 +99,16 @@ class Application extends \Symfony\Component\Console\Application $inputDefinition = parent::getDefaultInputDefinition(); $inputDefinition->addOption( new InputOption( - 'env', - null, + '--env', + '', InputOption::VALUE_OPTIONAL, 'Use environment configuration (defaults to localhost)' ) ); $inputDefinition->addOption( new InputOption( - 'lang', - null, + '--lang', + '', InputOption::VALUE_OPTIONAL, 'Language to be used (defaults to en)' ) diff --git a/system/src/Grav/Console/Application/CommandLoader/PluginCommandLoader.php b/system/src/Grav/Console/Application/CommandLoader/PluginCommandLoader.php index 9b7b568..adf6447 100644 --- a/system/src/Grav/Console/Application/CommandLoader/PluginCommandLoader.php +++ b/system/src/Grav/Console/Application/CommandLoader/PluginCommandLoader.php @@ -3,7 +3,7 @@ /** * @package Grav\Console * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Application/GpmApplication.php b/system/src/Grav/Console/Application/GpmApplication.php index df383f2..f9e6b61 100644 --- a/system/src/Grav/Console/Application/GpmApplication.php +++ b/system/src/Grav/Console/Application/GpmApplication.php @@ -3,7 +3,7 @@ /** * @package Grav\Console * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Application/GravApplication.php b/system/src/Grav/Console/Application/GravApplication.php index 739ca39..f06dae6 100644 --- a/system/src/Grav/Console/Application/GravApplication.php +++ b/system/src/Grav/Console/Application/GravApplication.php @@ -3,7 +3,7 @@ /** * @package Grav\Console * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Application/PluginApplication.php b/system/src/Grav/Console/Application/PluginApplication.php index 75e9eb7..e365b1e 100644 --- a/system/src/Grav/Console/Application/PluginApplication.php +++ b/system/src/Grav/Console/Application/PluginApplication.php @@ -3,7 +3,7 @@ /** * @package Grav\Console * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/BackupCommand.php b/system/src/Grav/Console/Cli/BackupCommand.php index a8a025d..1fe84ea 100644 --- a/system/src/Grav/Console/Cli/BackupCommand.php +++ b/system/src/Grav/Console/Cli/BackupCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/CleanCommand.php b/system/src/Grav/Console/Cli/CleanCommand.php index 84b46d6..e6b8f98 100644 --- a/system/src/Grav/Console/Cli/CleanCommand.php +++ b/system/src/Grav/Console/Cli/CleanCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/ClearCacheCommand.php b/system/src/Grav/Console/Cli/ClearCacheCommand.php index daed2a5..7550dd9 100644 --- a/system/src/Grav/Console/Cli/ClearCacheCommand.php +++ b/system/src/Grav/Console/Cli/ClearCacheCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/ComposerCommand.php b/system/src/Grav/Console/Cli/ComposerCommand.php index 5075d1d..0dc9bcd 100644 --- a/system/src/Grav/Console/Cli/ComposerCommand.php +++ b/system/src/Grav/Console/Cli/ComposerCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/InstallCommand.php b/system/src/Grav/Console/Cli/InstallCommand.php index 22258be..33198cb 100644 --- a/system/src/Grav/Console/Cli/InstallCommand.php +++ b/system/src/Grav/Console/Cli/InstallCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/LogViewerCommand.php b/system/src/Grav/Console/Cli/LogViewerCommand.php index d3924f8..d7e127e 100644 --- a/system/src/Grav/Console/Cli/LogViewerCommand.php +++ b/system/src/Grav/Console/Cli/LogViewerCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/NewProjectCommand.php b/system/src/Grav/Console/Cli/NewProjectCommand.php index d67cb1c..7abbc4e 100644 --- a/system/src/Grav/Console/Cli/NewProjectCommand.php +++ b/system/src/Grav/Console/Cli/NewProjectCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php b/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php index 4d234d7..3a69600 100644 --- a/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php +++ b/system/src/Grav/Console/Cli/PageSystemValidatorCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php index d865b4a..0ba2850 100644 --- a/system/src/Grav/Console/Cli/SandboxCommand.php +++ b/system/src/Grav/Console/Cli/SandboxCommand.php @@ -3,13 +3,14 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Console\Cli; use Grav\Common\Filesystem\Folder; +use Grav\Common\Utils; use Grav\Console\GravCommand; use RuntimeException; use Symfony\Component\Console\Input\InputArgument; @@ -200,6 +201,10 @@ class SandboxCommand extends GravCommand $io->newLine(); $io->writeln('Resetting Symbolic Links'); + // Symlink also tests if using git. + if (is_dir($this->source . '/tests')) { + $this->mappings['/tests'] = '/tests'; + } foreach ($this->mappings as $source => $target) { if ((string)(int)$source === (string)$source) { @@ -297,7 +302,7 @@ class SandboxCommand extends GravCommand foreach ($binaries as $bin) { chmod($bin, $dir_perms); - $io->writeln(' bin/' . basename($bin) . ' permissions reset to ' . decoct($dir_perms)); + $io->writeln(' bin/' . Utils::basename($bin) . ' permissions reset to ' . decoct($dir_perms)); } $io->newLine(); diff --git a/system/src/Grav/Console/Cli/SchedulerCommand.php b/system/src/Grav/Console/Cli/SchedulerCommand.php index c5385aa..91fc57d 100644 --- a/system/src/Grav/Console/Cli/SchedulerCommand.php +++ b/system/src/Grav/Console/Cli/SchedulerCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -77,8 +77,6 @@ class SchedulerCommand extends GravCommand $scheduler = $grav['scheduler']; $grav->fireEvent('onSchedulerInitialized', new Event(['scheduler' => $scheduler])); - $this->setHelp('foo'); - $input = $this->getInput(); $io = $this->getIO(); $error = 0; diff --git a/system/src/Grav/Console/Cli/SecurityCommand.php b/system/src/Grav/Console/Cli/SecurityCommand.php index 7f728b6..b6cb662 100644 --- a/system/src/Grav/Console/Cli/SecurityCommand.php +++ b/system/src/Grav/Console/Cli/SecurityCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/ServerCommand.php b/system/src/Grav/Console/Cli/ServerCommand.php index 77bce8b..29b423e 100644 --- a/system/src/Grav/Console/Cli/ServerCommand.php +++ b/system/src/Grav/Console/Cli/ServerCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Cli/YamlLinterCommand.php b/system/src/Grav/Console/Cli/YamlLinterCommand.php index a9628cd..75a7559 100644 --- a/system/src/Grav/Console/Cli/YamlLinterCommand.php +++ b/system/src/Grav/Console/Cli/YamlLinterCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Cli * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/ConsoleCommand.php b/system/src/Grav/Console/ConsoleCommand.php index 044f1b0..c522c88 100644 --- a/system/src/Grav/Console/ConsoleCommand.php +++ b/system/src/Grav/Console/ConsoleCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/ConsoleTrait.php b/system/src/Grav/Console/ConsoleTrait.php index feb10d3..0af4075 100644 --- a/system/src/Grav/Console/ConsoleTrait.php +++ b/system/src/Grav/Console/ConsoleTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Console * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Gpm/DirectInstallCommand.php b/system/src/Grav/Console/Gpm/DirectInstallCommand.php index e5c662b..fbb0220 100644 --- a/system/src/Grav/Console/Gpm/DirectInstallCommand.php +++ b/system/src/Grav/Console/Gpm/DirectInstallCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Gpm * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Gpm/IndexCommand.php b/system/src/Grav/Console/Gpm/IndexCommand.php index ecc91fe..367322b 100644 --- a/system/src/Grav/Console/Gpm/IndexCommand.php +++ b/system/src/Grav/Console/Gpm/IndexCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Gpm * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Gpm/InfoCommand.php b/system/src/Grav/Console/Gpm/InfoCommand.php index 5dddd32..c6f8552 100644 --- a/system/src/Grav/Console/Gpm/InfoCommand.php +++ b/system/src/Grav/Console/Gpm/InfoCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Gpm * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index 92c8e07..d25ebe3 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Gpm * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -579,7 +579,7 @@ class InstallCommand extends GpmCommand $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); $this->tmp = $tmp_dir . '/Grav-' . uniqid(); - $filename = $package->slug . basename($package->zipball_url); + $filename = $package->slug . Utils::basename($package->zipball_url); $filename = preg_replace('/[\\\\\/:"*?&<>|]+/m', '-', $filename); $query = ''; diff --git a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php index b840016..a3d53ff 100644 --- a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php +++ b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Gpm * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Gpm/UninstallCommand.php b/system/src/Grav/Console/Gpm/UninstallCommand.php index cb14c65..a3db657 100644 --- a/system/src/Grav/Console/Gpm/UninstallCommand.php +++ b/system/src/Grav/Console/Gpm/UninstallCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Gpm * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Gpm/UpdateCommand.php b/system/src/Grav/Console/Gpm/UpdateCommand.php index 300fe61..73c5c9e 100644 --- a/system/src/Grav/Console/Gpm/UpdateCommand.php +++ b/system/src/Grav/Console/Gpm/UpdateCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Gpm * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Gpm/VersionCommand.php b/system/src/Grav/Console/Gpm/VersionCommand.php index 124aad3..8629196 100644 --- a/system/src/Grav/Console/Gpm/VersionCommand.php +++ b/system/src/Grav/Console/Gpm/VersionCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Gpm * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/GpmCommand.php b/system/src/Grav/Console/GpmCommand.php index 816e872..a14eb47 100644 --- a/system/src/Grav/Console/GpmCommand.php +++ b/system/src/Grav/Console/GpmCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/GravCommand.php b/system/src/Grav/Console/GravCommand.php index 0249f14..7db18e2 100644 --- a/system/src/Grav/Console/GravCommand.php +++ b/system/src/Grav/Console/GravCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/Plugin/PluginListCommand.php b/system/src/Grav/Console/Plugin/PluginListCommand.php index 81041c0..0226614 100644 --- a/system/src/Grav/Console/Plugin/PluginListCommand.php +++ b/system/src/Grav/Console/Plugin/PluginListCommand.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\Plugin * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Console/TerminalObjects/Table.php b/system/src/Grav/Console/TerminalObjects/Table.php index a71d7c0..153993d 100644 --- a/system/src/Grav/Console/TerminalObjects/Table.php +++ b/system/src/Grav/Console/TerminalObjects/Table.php @@ -3,7 +3,7 @@ /** * @package Grav\Console\TerminalObjects * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Events/FlexRegisterEvent.php b/system/src/Grav/Events/FlexRegisterEvent.php index 13aebf3..b02ed1d 100644 --- a/system/src/Grav/Events/FlexRegisterEvent.php +++ b/system/src/Grav/Events/FlexRegisterEvent.php @@ -3,7 +3,7 @@ /** * @package Grav\Events * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Events/PermissionsRegisterEvent.php b/system/src/Grav/Events/PermissionsRegisterEvent.php index 5e63c85..434dcfa 100644 --- a/system/src/Grav/Events/PermissionsRegisterEvent.php +++ b/system/src/Grav/Events/PermissionsRegisterEvent.php @@ -3,7 +3,7 @@ /** * @package Grav\Events * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Events/PluginsLoadedEvent.php b/system/src/Grav/Events/PluginsLoadedEvent.php index 9dfd18b..13e2226 100644 --- a/system/src/Grav/Events/PluginsLoadedEvent.php +++ b/system/src/Grav/Events/PluginsLoadedEvent.php @@ -3,7 +3,7 @@ /** * @package Grav\Events * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Events/SessionStartEvent.php b/system/src/Grav/Events/SessionStartEvent.php index e724a09..fc4f364 100644 --- a/system/src/Grav/Events/SessionStartEvent.php +++ b/system/src/Grav/Events/SessionStartEvent.php @@ -3,7 +3,7 @@ /** * @package Grav\Events * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Acl/Access.php b/system/src/Grav/Framework/Acl/Access.php index ccc22cf..45cf2bf 100644 --- a/system/src/Grav/Framework/Acl/Access.php +++ b/system/src/Grav/Framework/Acl/Access.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Acl * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -14,7 +14,6 @@ use Countable; use Grav\Common\Utils; use IteratorAggregate; use JsonSerializable; -use RuntimeException; use Traversable; use function count; use function is_array; @@ -25,6 +24,7 @@ use function strlen; /** * Class Access * @package Grav\Framework\Acl + * @implements IteratorAggregate */ class Access implements JsonSerializable, IteratorAggregate, Countable { @@ -34,7 +34,7 @@ class Access implements JsonSerializable, IteratorAggregate, Countable private $rules; /** @var array */ private $ops; - /** @var array */ + /** @var array */ private $acl = []; /** @var array */ private $inherited = []; @@ -78,12 +78,7 @@ class Access implements JsonSerializable, IteratorAggregate, Countable $inherited = array_diff_key($parent->getAllActions(), $acl); $this->inherited += $parent->inherited + array_fill_keys(array_keys($inherited), $name ?? $parent->getName()); - $acl = array_replace($acl, $inherited); - if (null === $acl) { - throw new RuntimeException('Internal error'); - } - - $this->acl = $acl; + $this->acl = array_replace($acl, $inherited); } /** diff --git a/system/src/Grav/Framework/Acl/Action.php b/system/src/Grav/Framework/Acl/Action.php index 1f883a0..6251c3c 100644 --- a/system/src/Grav/Framework/Acl/Action.php +++ b/system/src/Grav/Framework/Acl/Action.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Acl * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -16,11 +16,11 @@ use IteratorAggregate; use RuntimeException; use Traversable; use function count; -use function strlen; /** * Class Action * @package Grav\Framework\Acl + * @implements IteratorAggregate */ class Action implements IteratorAggregate, Countable { @@ -37,7 +37,7 @@ class Action implements IteratorAggregate, Countable /** @var Action|null */ protected $parent; - /** @var Action[] */ + /** @var array */ protected $children = []; /** @@ -48,8 +48,8 @@ class Action implements IteratorAggregate, Countable { $label = $action['label'] ?? null; if (!$label) { - if ($pos = strrpos($name, '.')) { - $label = substr($name, $pos + 1); + if ($pos = mb_strrpos($name, '.')) { + $label = mb_substr($name, $pos + 1); } else { $label = $name; } @@ -114,9 +114,9 @@ class Action implements IteratorAggregate, Countable */ public function getScope(): string { - $pos = strpos($this->name, '.'); + $pos = mb_strpos($this->name, '.'); if ($pos) { - return substr($this->name, 0, $pos); + return mb_substr($this->name, 0, $pos); } return $this->name; @@ -127,7 +127,7 @@ class Action implements IteratorAggregate, Countable */ public function getLevels(): int { - return substr_count($this->name, '.'); + return mb_substr_count($this->name, '.'); } /** @@ -161,12 +161,12 @@ class Action implements IteratorAggregate, Countable */ public function addChild(Action $child): void { - if (strpos($child->name, "{$this->name}.") !== 0) { + if (mb_strpos($child->name, "{$this->name}.") !== 0) { throw new RuntimeException('Bad child'); } $child->setParent($this); - $name = substr($child->name, strlen($this->name) + 1); + $name = mb_substr($child->name, mb_strlen($this->name) + 1); $this->children[$name] = $child; } @@ -190,6 +190,7 @@ class Action implements IteratorAggregate, Countable /** * @return array */ + #[\ReturnTypeWillChange] public function __debugInfo() { return [ diff --git a/system/src/Grav/Framework/Acl/Permissions.php b/system/src/Grav/Framework/Acl/Permissions.php index 0375716..e54590a 100644 --- a/system/src/Grav/Framework/Acl/Permissions.php +++ b/system/src/Grav/Framework/Acl/Permissions.php @@ -3,26 +3,32 @@ /** * @package Grav\Framework\Acl * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Framework\Acl; +use ArrayAccess; use ArrayIterator; +use Countable; +use IteratorAggregate; use RecursiveIteratorIterator; use RuntimeException; use Traversable; +use function count; /** * Class Permissions * @package Grav\Framework\Acl + * @implements ArrayAccess + * @implements IteratorAggregate */ -class Permissions implements \ArrayAccess, \Countable, \IteratorAggregate +class Permissions implements ArrayAccess, Countable, IteratorAggregate { - /** @var Action[] */ + /** @var array */ protected $instances = []; - /** @var Action[] */ + /** @var array */ protected $actions = []; /** @var array */ protected $nested = []; @@ -142,9 +148,6 @@ class Permissions implements \ArrayAccess, \Countable, \IteratorAggregate public function addTypes(array $types): void { $types = array_replace($this->types, $types); - if (null === $types) { - throw new RuntimeException('Internal error'); - } $this->types = $types; } @@ -206,6 +209,7 @@ class Permissions implements \ArrayAccess, \Countable, \IteratorAggregate /** * @return ArrayIterator|Traversable */ + #[\ReturnTypeWillChange] public function getIterator() { return new ArrayIterator($this->actions); @@ -214,6 +218,7 @@ class Permissions implements \ArrayAccess, \Countable, \IteratorAggregate /** * @return array */ + #[\ReturnTypeWillChange] public function __debugInfo() { return [ diff --git a/system/src/Grav/Framework/Acl/PermissionsReader.php b/system/src/Grav/Framework/Acl/PermissionsReader.php index b157a5d..350fc96 100644 --- a/system/src/Grav/Framework/Acl/PermissionsReader.php +++ b/system/src/Grav/Framework/Acl/PermissionsReader.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Acl * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -62,12 +62,14 @@ class PermissionsReader { $list = []; foreach ($actions as $name => $action) { - $prefixNname = $prefix . $name; - $list[$prefixNname] = null; + $prefixName = $prefix . $name; + $list[$prefixName] = null; // Support nested sets of actions. if (isset($action['actions']) && is_array($action['actions'])) { - $list += static::read($action['actions'], "{$prefixNname}."); + $innerList = static::read($action['actions'], "{$prefixName}."); + + $list += $innerList; } unset($action['actions']); @@ -76,7 +78,7 @@ class PermissionsReader $action = static::addDefaults($action); // Build flat list of actions. - $list[$prefixNname] = $action; + $list[$prefixName] = $action; } return $list; @@ -172,9 +174,6 @@ class PermissionsReader $scopes[] = $action; $action = array_replace_recursive(...$scopes); - if (null === $action) { - throw new RuntimeException('Internal error'); - } $newType = $defaults['type'] ?? null; if ($newType && $newType !== $type) { diff --git a/system/src/Grav/Framework/Acl/RecursiveActionIterator.php b/system/src/Grav/Framework/Acl/RecursiveActionIterator.php index ac219da..1fb9a60 100644 --- a/system/src/Grav/Framework/Acl/RecursiveActionIterator.php +++ b/system/src/Grav/Framework/Acl/RecursiveActionIterator.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Acl * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -17,6 +17,7 @@ use RocketTheme\Toolbox\ArrayTraits\Iterator; /** * Class Action * @package Grav\Framework\Acl + * @implements RecursiveIterator */ class RecursiveActionIterator implements RecursiveIterator, \Countable { @@ -26,6 +27,7 @@ class RecursiveActionIterator implements RecursiveIterator, \Countable * @see \Iterator::key() * @return string */ + #[\ReturnTypeWillChange] public function key() { /** @var Action $current */ diff --git a/system/src/Grav/Framework/Cache/AbstractCache.php b/system/src/Grav/Framework/Cache/AbstractCache.php index bfb5125..b6d00a3 100644 --- a/system/src/Grav/Framework/Cache/AbstractCache.php +++ b/system/src/Grav/Framework/Cache/AbstractCache.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Cache * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Cache/Adapter/ChainCache.php b/system/src/Grav/Framework/Cache/Adapter/ChainCache.php index 76f5185..bca940f 100644 --- a/system/src/Grav/Framework/Cache/Adapter/ChainCache.php +++ b/system/src/Grav/Framework/Cache/Adapter/ChainCache.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Cache * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -33,11 +33,15 @@ class ChainCache extends AbstractCache * Chain Cache constructor. * @param array $caches * @param null|int|DateInterval $defaultLifetime - * @throws \Psr\SimpleCache\InvalidArgumentException|InvalidArgumentException + * @throws InvalidArgumentException */ public function __construct(array $caches, $defaultLifetime = null) { - parent::__construct('', $defaultLifetime); + try { + parent::__construct('', $defaultLifetime); + } catch (\Psr\SimpleCache\InvalidArgumentException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } if (!$caches) { throw new InvalidArgumentException('At least one cache must be specified'); diff --git a/system/src/Grav/Framework/Cache/Adapter/DoctrineCache.php b/system/src/Grav/Framework/Cache/Adapter/DoctrineCache.php index 29e9e3b..15afed3 100644 --- a/system/src/Grav/Framework/Cache/Adapter/DoctrineCache.php +++ b/system/src/Grav/Framework/Cache/Adapter/DoctrineCache.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Cache * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -29,12 +29,16 @@ class DoctrineCache extends AbstractCache * @param CacheProvider $doctrineCache * @param string $namespace * @param null|int|DateInterval $defaultLifetime - * @throws \Psr\SimpleCache\InvalidArgumentException|InvalidArgumentException + * @throws InvalidArgumentException */ public function __construct(CacheProvider $doctrineCache, $namespace = '', $defaultLifetime = null) { // Do not use $namespace or $defaultLifetime directly, store them with constructor and fetch with methods. - parent::__construct($namespace, $defaultLifetime); + try { + parent::__construct($namespace, $defaultLifetime); + } catch (\Psr\SimpleCache\InvalidArgumentException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } // Set namespace to Doctrine Cache provider if it was given. $namespace = $this->getNamespace(); diff --git a/system/src/Grav/Framework/Cache/Adapter/FileCache.php b/system/src/Grav/Framework/Cache/Adapter/FileCache.php index 1995e15..7f1d5e7 100644 --- a/system/src/Grav/Framework/Cache/Adapter/FileCache.php +++ b/system/src/Grav/Framework/Cache/Adapter/FileCache.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Cache * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -42,9 +42,13 @@ class FileCache extends AbstractCache */ public function __construct($namespace = '', $defaultLifetime = null, $folder = null) { - parent::__construct($namespace, $defaultLifetime ?: 31557600); // = 1 year + try { + parent::__construct($namespace, $defaultLifetime ?: 31557600); // = 1 year - $this->initFileCache($namespace, $folder ?? ''); + $this->initFileCache($namespace, $folder ?? ''); + } catch (\Psr\SimpleCache\InvalidArgumentException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } } /** @@ -103,7 +107,13 @@ class FileCache extends AbstractCache { $file = $this->getFile($key); - return (!file_exists($file) || @unlink($file) || !file_exists($file)); + $result = false; + if (file_exists($file)) { + $result = @unlink($file); + $result &= !file_exists($file); + } + + return $result; } /** @@ -156,7 +166,7 @@ class FileCache extends AbstractCache */ protected function initFileCache($namespace, $directory) { - if (!isset($directory[0])) { + if ($directory === '') { $directory = sys_get_temp_dir() . '/grav-cache'; } else { $directory = realpath($directory) ?: $directory; @@ -246,6 +256,7 @@ class FileCache extends AbstractCache /** * @return void */ + #[\ReturnTypeWillChange] public function __destruct() { if ($this->tmp !== null && file_exists($this->tmp)) { diff --git a/system/src/Grav/Framework/Cache/Adapter/MemoryCache.php b/system/src/Grav/Framework/Cache/Adapter/MemoryCache.php index c043bf9..21cd89c 100644 --- a/system/src/Grav/Framework/Cache/Adapter/MemoryCache.php +++ b/system/src/Grav/Framework/Cache/Adapter/MemoryCache.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Cache * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Cache/Adapter/SessionCache.php b/system/src/Grav/Framework/Cache/Adapter/SessionCache.php index e189e3e..02fe7c9 100644 --- a/system/src/Grav/Framework/Cache/Adapter/SessionCache.php +++ b/system/src/Grav/Framework/Cache/Adapter/SessionCache.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Cache * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Cache/CacheInterface.php b/system/src/Grav/Framework/Cache/CacheInterface.php index efd9d31..03dfa7a 100644 --- a/system/src/Grav/Framework/Cache/CacheInterface.php +++ b/system/src/Grav/Framework/Cache/CacheInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Cache * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Cache/CacheTrait.php b/system/src/Grav/Framework/Cache/CacheTrait.php index 287f924..37dd6c9 100644 --- a/system/src/Grav/Framework/Cache/CacheTrait.php +++ b/system/src/Grav/Framework/Cache/CacheTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Cache * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Cache/Exception/CacheException.php b/system/src/Grav/Framework/Cache/Exception/CacheException.php index 1db3256..db33883 100644 --- a/system/src/Grav/Framework/Cache/Exception/CacheException.php +++ b/system/src/Grav/Framework/Cache/Exception/CacheException.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Cache * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Cache/Exception/InvalidArgumentException.php b/system/src/Grav/Framework/Cache/Exception/InvalidArgumentException.php index 08a3435..70c0418 100644 --- a/system/src/Grav/Framework/Cache/Exception/InvalidArgumentException.php +++ b/system/src/Grav/Framework/Cache/Exception/InvalidArgumentException.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Cache * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Collection/AbstractFileCollection.php b/system/src/Grav/Framework/Collection/AbstractFileCollection.php index 1be8d12..500aea8 100644 --- a/system/src/Grav/Framework/Collection/AbstractFileCollection.php +++ b/system/src/Grav/Framework/Collection/AbstractFileCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Collection * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -68,6 +68,7 @@ class AbstractFileCollection extends AbstractLazyCollection implements FileColle /** * @param Criteria $criteria * @return ArrayCollection + * @phpstan-return ArrayCollection * @todo Implement lazy matching */ public function matching(Criteria $criteria) @@ -93,6 +94,7 @@ class AbstractFileCollection extends AbstractLazyCollection implements FileColle foreach (array_reverse($orderings) as $field => $ordering) { $next = ClosureExpressionVisitor::sortByField($field, $ordering === Criteria::DESC ? -1 : 1, $next); } + /** @phpstan-ignore-next-line */ if (null === $next) { throw new RuntimeException('Criteria is missing orderings'); } @@ -162,6 +164,7 @@ class AbstractFileCollection extends AbstractLazyCollection implements FileColle * @param SeekableIterator $iterator * @param int $nestingLimit * @return array + * @phpstan-param SeekableIterator $iterator */ protected function doInitializeByIterator(SeekableIterator $iterator, $nestingLimit) { @@ -211,7 +214,6 @@ class AbstractFileCollection extends AbstractLazyCollection implements FileColle protected function doInitializeChildren(array $children, $nestingLimit) { $objects = []; - foreach ($children as $iterator) { $objects += $this->doInitializeByIterator($iterator, $nestingLimit); } diff --git a/system/src/Grav/Framework/Collection/AbstractIndexCollection.php b/system/src/Grav/Framework/Collection/AbstractIndexCollection.php index 25d8672..02916d9 100644 --- a/system/src/Grav/Framework/Collection/AbstractIndexCollection.php +++ b/system/src/Grav/Framework/Collection/AbstractIndexCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Collection * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -14,6 +14,7 @@ use Closure; use Grav\Framework\Compat\Serializable; use Grav\Framework\Flex\Interfaces\FlexObjectInterface; use InvalidArgumentException; +use Iterator; use function array_key_exists; use function array_slice; use function count; @@ -79,17 +80,17 @@ abstract class AbstractIndexCollection implements CollectionInterface /** * {@inheritDoc} */ + #[\ReturnTypeWillChange] public function key() { - /** @phpstan-var TKey $key */ - $key = (string)key($this->entries); - - return $key; + /** @phpstan-var TKey */ + return (string)key($this->entries); } /** * {@inheritDoc} */ + #[\ReturnTypeWillChange] public function next() { $value = next($this->entries); @@ -101,6 +102,7 @@ abstract class AbstractIndexCollection implements CollectionInterface /** * {@inheritDoc} */ + #[\ReturnTypeWillChange] public function current() { $value = current($this->entries); @@ -131,7 +133,7 @@ abstract class AbstractIndexCollection implements CollectionInterface { $key = $this->isAllowedElement($element) ? $this->getCurrentKey($element) : null; - if (!$key || !isset($this->entries[$key])) { + if (null !== $key || !isset($this->entries[$key])) { return false; } @@ -143,49 +145,64 @@ abstract class AbstractIndexCollection implements CollectionInterface /** * Required by interface ArrayAccess. * - * {@inheritDoc} + * @param string|int|null $offset + * @return bool + * @phpstan-param TKey|null $offset */ #[\ReturnTypeWillChange] public function offsetExists($offset) { - return $this->containsKey($offset); + /** @phpstan-ignore-next-line phpstan bug? */ + return $offset !== null ? $this->containsKey($offset) : false; } /** * Required by interface ArrayAccess. * - * {@inheritDoc} + * @param string|int|null $offset + * @return mixed + * @phpstan-param TKey|null $offset */ #[\ReturnTypeWillChange] public function offsetGet($offset) { - return $this->get($offset); + /** @phpstan-ignore-next-line phpstan bug? */ + return $offset !== null ? $this->get($offset) : null; } /** * Required by interface ArrayAccess. * - * {@inheritDoc} + * @param string|int|null $offset + * @param mixed $value + * @return void + * @phpstan-param TKey|null $offset */ #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { if (null === $offset) { $this->add($value); + } else { + /** @phpstan-ignore-next-line phpstan bug? */ + $this->set($offset, $value); } - - $this->set($offset, $value); } /** * Required by interface ArrayAccess. * - * {@inheritDoc} + * @param string|int|null $offset + * @return void + * @phpstan-param TKey|null $offset */ #[\ReturnTypeWillChange] public function offsetUnset($offset) { - $this->remove($offset); + if ($offset !== null) { + /** @phpstan-ignore-next-line phpstan bug? */ + $this->remove($offset); + } } /** @@ -255,6 +272,7 @@ abstract class AbstractIndexCollection implements CollectionInterface /** * {@inheritDoc} */ + #[\ReturnTypeWillChange] public function count() { return count($this->entries); @@ -298,7 +316,9 @@ abstract class AbstractIndexCollection implements CollectionInterface * Required by interface IteratorAggregate. * * {@inheritDoc} + * @phpstan-return Iterator */ + #[\ReturnTypeWillChange] public function getIterator() { return new ArrayIterator($this->loadElements()); @@ -341,6 +361,7 @@ abstract class AbstractIndexCollection implements CollectionInterface * * @return string */ + #[\ReturnTypeWillChange] public function __toString() { return __CLASS__ . '@' . spl_object_hash($this); @@ -395,7 +416,7 @@ abstract class AbstractIndexCollection implements CollectionInterface $keys = $this->getKeys(); shuffle($keys); - return $this->createFrom(array_replace(array_flip($keys), $this->entries) ?? []); + return $this->createFrom(array_replace(array_flip($keys), $this->entries)); } /** @@ -436,9 +457,11 @@ abstract class AbstractIndexCollection implements CollectionInterface * * @param int $size Size of each chunk. * @return array + * @phpstan-return array> */ public function chunk($size) { + /** @phpstan-var array> */ return $this->loadCollection($this->entries)->chunk($size); } @@ -466,6 +489,7 @@ abstract class AbstractIndexCollection implements CollectionInterface * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->loadCollection()->jsonSerialize(); diff --git a/system/src/Grav/Framework/Collection/AbstractLazyCollection.php b/system/src/Grav/Framework/Collection/AbstractLazyCollection.php index 9afaab1..b0a93f5 100644 --- a/system/src/Grav/Framework/Collection/AbstractLazyCollection.php +++ b/system/src/Grav/Framework/Collection/AbstractLazyCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Collection * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -22,11 +22,15 @@ use Doctrine\Common\Collections\AbstractLazyCollection as BaseAbstractLazyCollec */ abstract class AbstractLazyCollection extends BaseAbstractLazyCollection implements CollectionInterface { - /** @var ArrayCollection The backed collection to use */ + /** + * @par ArrayCollection + * @phpstan-var ArrayCollection + */ protected $collection; /** * {@inheritDoc} + * @phpstan-return ArrayCollection */ public function reverse() { @@ -37,6 +41,7 @@ abstract class AbstractLazyCollection extends BaseAbstractLazyCollection impleme /** * {@inheritDoc} + * @phpstan-return ArrayCollection */ public function shuffle() { @@ -57,6 +62,8 @@ abstract class AbstractLazyCollection extends BaseAbstractLazyCollection impleme /** * {@inheritDoc} + * @phpstan-param array $keys + * @phpstan-return ArrayCollection */ public function select(array $keys) { @@ -67,6 +74,8 @@ abstract class AbstractLazyCollection extends BaseAbstractLazyCollection impleme /** * {@inheritDoc} + * @phpstan-param array $keys + * @phpstan-return ArrayCollection */ public function unselect(array $keys) { @@ -78,6 +87,7 @@ abstract class AbstractLazyCollection extends BaseAbstractLazyCollection impleme /** * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { $this->initialize(); diff --git a/system/src/Grav/Framework/Collection/ArrayCollection.php b/system/src/Grav/Framework/Collection/ArrayCollection.php index d76aa05..cad02f2 100644 --- a/system/src/Grav/Framework/Collection/ArrayCollection.php +++ b/system/src/Grav/Framework/Collection/ArrayCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Collection * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -30,7 +30,10 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface */ public function reverse() { - return $this->createFrom(array_reverse($this->toArray())); + $keys = array_reverse($this->toArray()); + + /** @phpstan-var static */ + return $this->createFrom($keys); } /** @@ -43,8 +46,10 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface { $keys = $this->getKeys(); shuffle($keys); + $keys = array_replace(array_flip($keys), $this->toArray()); - return $this->createFrom(array_replace(array_flip($keys), $this->toArray()) ?? []); + /** @phpstan-var static */ + return $this->createFrom($keys); } /** @@ -52,9 +57,11 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface * * @param int $size Size of each chunk. * @return array + * @phpstan-return array> */ public function chunk($size) { + /** @phpstan-var array> */ return array_chunk($this->toArray(), $size, true); } @@ -63,9 +70,9 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface * * Collection is returned in the order of $keys given to the function. * - * @param array $keys + * @param array $keys * @return static - * @phpstan-param array $keys + * @phpstan-param TKey[] $keys * @phpstan-return static */ public function select(array $keys) @@ -77,6 +84,7 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface } } + /** @phpstan-var static */ return $this->createFrom($list); } @@ -85,11 +93,15 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface * * @param array $keys * @return static + * @phpstan-param TKey[] $keys * @phpstan-return static */ public function unselect(array $keys) { - return $this->select(array_diff($this->getKeys(), $keys)); + $list = array_diff($this->getKeys(), $keys); + + /** @phpstan-var static */ + return $this->select($list); } /** @@ -97,6 +109,7 @@ class ArrayCollection extends BaseArrayCollection implements CollectionInterface * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); diff --git a/system/src/Grav/Framework/Collection/CollectionInterface.php b/system/src/Grav/Framework/Collection/CollectionInterface.php index 0739109..e098dd6 100644 --- a/system/src/Grav/Framework/Collection/CollectionInterface.php +++ b/system/src/Grav/Framework/Collection/CollectionInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Collection * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -43,6 +43,7 @@ interface CollectionInterface extends Collection, JsonSerializable * * @param int $size Size of each chunk. * @return array + * @phpstan-return array> */ public function chunk($size); diff --git a/system/src/Grav/Framework/Collection/FileCollection.php b/system/src/Grav/Framework/Collection/FileCollection.php index f7b4f25..bae0e7b 100644 --- a/system/src/Grav/Framework/Collection/FileCollection.php +++ b/system/src/Grav/Framework/Collection/FileCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Collection * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Collection/FileCollectionInterface.php b/system/src/Grav/Framework/Collection/FileCollectionInterface.php index 45c446c..1b56da9 100644 --- a/system/src/Grav/Framework/Collection/FileCollectionInterface.php +++ b/system/src/Grav/Framework/Collection/FileCollectionInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Collection * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Compat/Serializable.php b/system/src/Grav/Framework/Compat/Serializable.php index 3c9bf6a..22e4648 100644 --- a/system/src/Grav/Framework/Compat/Serializable.php +++ b/system/src/Grav/Framework/Compat/Serializable.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Compat * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/ContentBlock/ContentBlock.php b/system/src/Grav/Framework/ContentBlock/ContentBlock.php index efcd5f3..7259df0 100644 --- a/system/src/Grav/Framework/ContentBlock/ContentBlock.php +++ b/system/src/Grav/Framework/ContentBlock/ContentBlock.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\ContentBlock * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -161,6 +161,7 @@ class ContentBlock implements ContentBlockInterface /** * @return string */ + #[\ReturnTypeWillChange] public function __toString() { try { diff --git a/system/src/Grav/Framework/ContentBlock/ContentBlockInterface.php b/system/src/Grav/Framework/ContentBlock/ContentBlockInterface.php index fb445a3..bb0e46f 100644 --- a/system/src/Grav/Framework/ContentBlock/ContentBlockInterface.php +++ b/system/src/Grav/Framework/ContentBlock/ContentBlockInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\ContentBlock * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/ContentBlock/HtmlBlock.php b/system/src/Grav/Framework/ContentBlock/HtmlBlock.php index 5c5eb43..69d417c 100644 --- a/system/src/Grav/Framework/ContentBlock/HtmlBlock.php +++ b/system/src/Grav/Framework/ContentBlock/HtmlBlock.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\ContentBlock * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -29,6 +29,8 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface /** @var array */ protected $scripts = []; /** @var array */ + protected $links = []; + /** @var array */ protected $html = []; /** @@ -40,6 +42,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface $this->sortAssets($assets['styles']); $this->sortAssets($assets['scripts']); + $this->sortAssets($assets['links']); $this->sortAssets($assets['html']); return $assets; @@ -73,6 +76,15 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface return $this->getAssetsInLocation('scripts', $location); } + /** + * @param string $location + * @return array + */ + public function getLinks($location = 'head') + { + return $this->getAssetsInLocation('links', $location); + } + /** * @param string $location * @return array @@ -98,6 +110,9 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface if ($this->scripts) { $array['scripts'] = $this->scripts; } + if ($this->links) { + $array['links'] = $this->links; + } if ($this->html) { $array['html'] = $this->html; } @@ -117,6 +132,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface $this->frameworks = isset($serialized['frameworks']) ? (array) $serialized['frameworks'] : []; $this->styles = isset($serialized['styles']) ? (array) $serialized['styles'] : []; $this->scripts = isset($serialized['scripts']) ? (array) $serialized['scripts'] : []; + $this->links = isset($serialized['links']) ? (array) $serialized['links'] : []; $this->html = isset($serialized['html']) ? (array) $serialized['html'] : []; } @@ -199,11 +215,14 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface $content = (string) $element['content']; $type = !empty($element['type']) ? (string) $element['type'] : 'text/css'; + unset($element['content'], $element['type']); + $this->styles[$location][md5($content) . sha1($content)] = [ ':type' => 'inline', ':priority' => (int) $priority, 'content' => $content, - 'type' => $type + 'type' => $type, + 'element' => $element ]; return true; @@ -229,18 +248,23 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface $src = $element['src']; $type = !empty($element['type']) ? (string) $element['type'] : 'text/javascript'; - $defer = isset($element['defer']); - $async = isset($element['async']); + $loading = !empty($element['loading']) ? (string) $element['loading'] : null; + $defer = !empty($element['defer']); + $async = !empty($element['async']); $handle = !empty($element['handle']) ? (string) $element['handle'] : ''; + unset($element['src'], $element['type'], $element['loading'], $element['defer'], $element['async'], $element['handle']); + $this->scripts[$location][md5($src) . sha1($src)] = [ ':type' => 'file', ':priority' => (int) $priority, 'src' => $src, 'type' => $type, + 'loading' => $loading, 'defer' => $defer, 'async' => $async, - 'handle' => $handle + 'handle' => $handle, + 'element' => $element ]; return true; @@ -266,12 +290,83 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface $content = (string) $element['content']; $type = !empty($element['type']) ? (string) $element['type'] : 'text/javascript'; + $loading = !empty($element['loading']) ? (string) $element['loading'] : null; + + unset($element['content'], $element['type'], $element['loading']); $this->scripts[$location][md5($content) . sha1($content)] = [ ':type' => 'inline', ':priority' => (int) $priority, 'content' => $content, - 'type' => $type + 'type' => $type, + 'loading' => $loading, + 'element' => $element + ]; + + return true; + } + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addModule($element, $priority = 0, $location = 'head') + { + if (!is_array($element)) { + $element = ['src' => (string) $element]; + } + + $element['type'] = 'module'; + + return $this->addScript($element, $priority, $location); + } + + /** + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addInlineModule($element, $priority = 0, $location = 'head') + { + if (!is_array($element)) { + $element = ['content' => (string) $element]; + } + + $element['type'] = 'module'; + + return $this->addInlineScript($element, $priority, $location); + } + + /** + * @param array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addLink($element, $priority = 0, $location = 'head') + { + if (!is_array($element) || empty($element['rel']) || empty($element['href'])) { + return false; + } + + if (!isset($this->links[$location])) { + $this->links[$location] = []; + } + + $rel = (string) $element['rel']; + $href = (string) $element['href']; + + unset($element['rel'], $element['href']); + + $this->links[$location][md5($href) . sha1($href)] = [ + ':type' => 'file', + ':priority' => (int) $priority, + 'href' => $href, + 'rel' => $rel, + 'element' => $element, ]; return true; @@ -309,6 +404,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface 'frameworks' => $this->frameworks, 'styles' => $this->styles, 'scripts' => $this->scripts, + 'links' => $this->links, 'html' => $this->html ]; @@ -333,6 +429,14 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface } } + foreach ($blockAssets['links'] as $location => $links) { + if (!isset($assets['links'][$location])) { + $assets['links'][$location] = $links; + } elseif ($links) { + $assets['links'][$location] += $links; + } + } + foreach ($blockAssets['html'] as $location => $htmls) { if (!isset($assets['html'][$location])) { $assets['html'][$location] = $htmls; @@ -391,7 +495,7 @@ class HtmlBlock extends ContentBlock implements HtmlBlockInterface */ protected function sortAssets(array &$array) { - foreach ($array as $location => &$items) { + foreach ($array as &$items) { $this->sortAssetsInLocation($items); } } diff --git a/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php b/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php index 616e4a2..b151d7b 100644 --- a/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php +++ b/system/src/Grav/Framework/ContentBlock/HtmlBlockInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\ContentBlock * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -37,6 +37,13 @@ interface HtmlBlockInterface extends ContentBlockInterface */ public function getScripts($location = 'head'); + + /** + * @param string $location + * @return array + */ + public function getLinks($location = 'head'); + /** * @param string $location * @return array @@ -76,7 +83,6 @@ interface HtmlBlockInterface extends ContentBlockInterface */ public function addScript($element, $priority = 0, $location = 'head'); - /** * @param string|array $element * @param int $priority @@ -85,6 +91,35 @@ interface HtmlBlockInterface extends ContentBlockInterface */ public function addInlineScript($element, $priority = 0, $location = 'head'); + + /** + * Shortcut for writing addScript(['type' => 'module', 'src' => ...]). + * + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addModule($element, $priority = 0, $location = 'head'); + + /** + * Shortcut for writing addInlineScript(['type' => 'module', 'content' => ...]). + * + * @param string|array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addInlineModule($element, $priority = 0, $location = 'head'); + + /** + * @param array $element + * @param int $priority + * @param string $location + * @return bool + */ + public function addLink($element, $priority = 0, $location = 'head'); + /** * @param string $html * @param int $priority diff --git a/system/src/Grav/Framework/Controller/Traits/ControllerResponseTrait.php b/system/src/Grav/Framework/Controller/Traits/ControllerResponseTrait.php index afa08aa..24e1fc2 100644 --- a/system/src/Grav/Framework/Controller/Traits/ControllerResponseTrait.php +++ b/system/src/Grav/Framework/Controller/Traits/ControllerResponseTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Controller * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -97,7 +97,7 @@ trait ControllerResponseTrait $headers = $headers ?? []; $options = $options ?? ['force_download' => true]; - $file_parts = pathinfo($filename); + $file_parts = Utils::pathinfo($filename); if (!isset($headers['Content-Type'])) { $mimetype = Utils::getMimeByExtension($file_parts['extension']); @@ -140,9 +140,9 @@ trait ControllerResponseTrait $code = (int)$this->getConfig()->get('system.pages.redirect_default_code', 302); } + $ext = Utils::pathinfo($url, PATHINFO_EXTENSION); $accept = $this->getAccept(['application/json', 'text/html']); - - if ($accept === 'application/json') { + if ($ext === 'json' || $accept === 'application/json') { return $this->createJsonResponse(['code' => $code, 'status' => 'redirect', 'redirect' => $url]); } @@ -217,6 +217,7 @@ trait ControllerResponseTrait 'code' => $code, 'status' => 'error', 'message' => $message, + 'redirect' => null, 'error' => [ 'code' => $code, 'message' => $message diff --git a/system/src/Grav/Framework/DI/Container.php b/system/src/Grav/Framework/DI/Container.php index 76434a3..dde0da3 100644 --- a/system/src/Grav/Framework/DI/Container.php +++ b/system/src/Grav/Framework/DI/Container.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\DI * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/File/AbstractFile.php b/system/src/Grav/Framework/File/AbstractFile.php index b82bb33..b216ea6 100644 --- a/system/src/Grav/Framework/File/AbstractFile.php +++ b/system/src/Grav/Framework/File/AbstractFile.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -55,6 +55,7 @@ class AbstractFile implements FileInterface /** * Unlock file when the object gets destroyed. */ + #[\ReturnTypeWillChange] public function __destruct() { if ($this->isLocked()) { @@ -65,6 +66,7 @@ class AbstractFile implements FileInterface /** * @return void */ + #[\ReturnTypeWillChange] public function __clone() { $this->handle = null; @@ -191,15 +193,16 @@ class AbstractFile implements FileInterface $this->handle = @fopen($this->filepath, 'cb+') ?: null; if (!$this->handle) { $error = error_get_last(); + $message = $error['message'] ?? 'Unknown error'; - throw new RuntimeException("Opening file for writing failed on error {$error['message']}"); + throw new RuntimeException("Opening file for writing failed on error {$message}"); } } $lock = $block ? LOCK_EX : LOCK_EX | LOCK_NB; // Some filesystems do not support file locks, only fail if another process holds the lock. - $this->locked = flock($this->handle, $lock, $wouldblock) || !$wouldblock; + $this->locked = flock($this->handle, $lock, $wouldBlock) || !$wouldBlock; return $this->locked; } diff --git a/system/src/Grav/Framework/File/CsvFile.php b/system/src/Grav/Framework/File/CsvFile.php index 999f88a..7eba91e 100644 --- a/system/src/Grav/Framework/File/CsvFile.php +++ b/system/src/Grav/Framework/File/CsvFile.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -28,4 +28,13 @@ class CsvFile extends DataFile { parent::__construct($filepath, $formatter); } + + /** + * @return array + */ + public function load(): array + { + /** @var array */ + return parent::load(); + } } diff --git a/system/src/Grav/Framework/File/DataFile.php b/system/src/Grav/Framework/File/DataFile.php index 114146f..189db53 100644 --- a/system/src/Grav/Framework/File/DataFile.php +++ b/system/src/Grav/Framework/File/DataFile.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/File/File.php b/system/src/Grav/Framework/File/File.php index 1d4055a..b1a1c4f 100644 --- a/system/src/Grav/Framework/File/File.php +++ b/system/src/Grav/Framework/File/File.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -20,15 +20,6 @@ use function is_string; */ class File extends AbstractFile { - /** - * {@inheritdoc} - * @see FileInterface::load() - */ - public function load() - { - return parent::load(); - } - /** * {@inheritdoc} * @see FileInterface::save() diff --git a/system/src/Grav/Framework/File/Formatter/AbstractFormatter.php b/system/src/Grav/Framework/File/Formatter/AbstractFormatter.php index f5ff3f2..6a6981b 100644 --- a/system/src/Grav/Framework/File/Formatter/AbstractFormatter.php +++ b/system/src/Grav/Framework/File/Formatter/AbstractFormatter.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File\Formatter * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/File/Formatter/CsvFormatter.php b/system/src/Grav/Framework/File/Formatter/CsvFormatter.php index 9d0a9a8..37ab5bb 100644 --- a/system/src/Grav/Framework/File/Formatter/CsvFormatter.php +++ b/system/src/Grav/Framework/File/Formatter/CsvFormatter.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File\Formatter * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -16,6 +16,7 @@ use Grav\Framework\File\Interfaces\FileFormatterInterface; use JsonSerializable; use RuntimeException; use stdClass; +use function count; use function is_array; use function is_object; use function is_scalar; diff --git a/system/src/Grav/Framework/File/Formatter/IniFormatter.php b/system/src/Grav/Framework/File/Formatter/IniFormatter.php index ec16959..ecf67d1 100644 --- a/system/src/Grav/Framework/File/Formatter/IniFormatter.php +++ b/system/src/Grav/Framework/File/Formatter/IniFormatter.php @@ -5,13 +5,14 @@ declare(strict_types=1); /** * @package Grav\Framework\File\Formatter * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Framework\File\Formatter; use Grav\Framework\File\Interfaces\FileFormatterInterface; +use RuntimeException; /** * Class IniFormatter @@ -59,7 +60,7 @@ class IniFormatter extends AbstractFormatter $decoded = @parse_ini_string($data); if ($decoded === false) { - throw new \RuntimeException('Decoding INI failed'); + throw new RuntimeException('Decoding INI failed'); } return $decoded; diff --git a/system/src/Grav/Framework/File/Formatter/JsonFormatter.php b/system/src/Grav/Framework/File/Formatter/JsonFormatter.php index 6b19690..2bd6c79 100644 --- a/system/src/Grav/Framework/File/Formatter/JsonFormatter.php +++ b/system/src/Grav/Framework/File/Formatter/JsonFormatter.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File\Formatter * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -75,9 +75,11 @@ class JsonFormatter extends AbstractFormatter if (is_string($options)) { $list = preg_split('/[\s,|]+/', $options); $options = 0; - foreach ($list as $option) { - if (isset($this->encodeOptions[$option])) { - $options += $this->encodeOptions[$option]; + if ($list) { + foreach ($list as $option) { + if (isset($this->encodeOptions[$option])) { + $options += $this->encodeOptions[$option]; + } } } } else { @@ -100,9 +102,11 @@ class JsonFormatter extends AbstractFormatter if (is_string($options)) { $list = preg_split('/[\s,|]+/', $options); $options = 0; - foreach ($list as $option) { - if (isset($this->decodeOptions[$option])) { - $options += $this->decodeOptions[$option]; + if ($list) { + foreach ($list as $option) { + if (isset($this->decodeOptions[$option])) { + $options += $this->decodeOptions[$option]; + } } } } else { @@ -117,6 +121,7 @@ class JsonFormatter extends AbstractFormatter * Returns recursion depth used in decode() function. * * @return int + * @phpstan-return positive-int */ public function getDecodeDepth(): int { diff --git a/system/src/Grav/Framework/File/Formatter/MarkdownFormatter.php b/system/src/Grav/Framework/File/Formatter/MarkdownFormatter.php index 8a624df..e36276a 100644 --- a/system/src/Grav/Framework/File/Formatter/MarkdownFormatter.php +++ b/system/src/Grav/Framework/File/Formatter/MarkdownFormatter.php @@ -5,13 +5,14 @@ declare(strict_types=1); /** * @package Grav\Framework\File\Formatter * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Framework\File\Formatter; use Grav\Framework\File\Interfaces\FileFormatterInterface; +use RuntimeException; /** * Class MarkdownFormatter @@ -99,7 +100,7 @@ class MarkdownFormatter extends AbstractFormatter // Normalize line endings to Unix style. $encoded = preg_replace("/(\r\n|\r)/u", "\n", $encoded); if (null === $encoded) { - throw new \RuntimeException('Encoding markdown failed'); + throw new RuntimeException('Encoding markdown failed'); } return $encoded; @@ -126,7 +127,7 @@ class MarkdownFormatter extends AbstractFormatter // Normalize line endings to Unix style. $data = preg_replace("/(\r\n|\r)/u", "\n", $data); if (null === $data) { - throw new \RuntimeException('Decoding markdown failed'); + throw new RuntimeException('Decoding markdown failed'); } // Parse header. diff --git a/system/src/Grav/Framework/File/Formatter/SerializeFormatter.php b/system/src/Grav/Framework/File/Formatter/SerializeFormatter.php index f045d71..25aee81 100644 --- a/system/src/Grav/Framework/File/Formatter/SerializeFormatter.php +++ b/system/src/Grav/Framework/File/Formatter/SerializeFormatter.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File\Formatter * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/File/Formatter/YamlFormatter.php b/system/src/Grav/Framework/File/Formatter/YamlFormatter.php index 32d4d29..31aff2c 100644 --- a/system/src/Grav/Framework/File/Formatter/YamlFormatter.php +++ b/system/src/Grav/Framework/File/Formatter/YamlFormatter.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File\Formatter * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -107,7 +107,9 @@ class YamlFormatter extends AbstractFormatter $saved = @ini_get('yaml.decode_php'); @ini_set('yaml.decode_php', '0'); $decoded = @yaml_parse($data); - @ini_set('yaml.decode_php', $saved); + if ($saved !== false) { + @ini_set('yaml.decode_php', $saved); + } if ($decoded !== false) { return (array) $decoded; diff --git a/system/src/Grav/Framework/File/IniFile.php b/system/src/Grav/Framework/File/IniFile.php index 6cda609..0807ee3 100644 --- a/system/src/Grav/Framework/File/IniFile.php +++ b/system/src/Grav/Framework/File/IniFile.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -28,4 +28,13 @@ class IniFile extends DataFile { parent::__construct($filepath, $formatter); } + + /** + * @return array + */ + public function load(): array + { + /** @var array */ + return parent::load(); + } } diff --git a/system/src/Grav/Framework/File/Interfaces/FileFormatterInterface.php b/system/src/Grav/Framework/File/Interfaces/FileFormatterInterface.php index 49eda4f..78714af 100644 --- a/system/src/Grav/Framework/File/Interfaces/FileFormatterInterface.php +++ b/system/src/Grav/Framework/File/Interfaces/FileFormatterInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/File/Interfaces/FileInterface.php b/system/src/Grav/Framework/File/Interfaces/FileInterface.php index 015b1ad..f2cc288 100644 --- a/system/src/Grav/Framework/File/Interfaces/FileInterface.php +++ b/system/src/Grav/Framework/File/Interfaces/FileInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/File/JsonFile.php b/system/src/Grav/Framework/File/JsonFile.php index f3b0902..7751e84 100644 --- a/system/src/Grav/Framework/File/JsonFile.php +++ b/system/src/Grav/Framework/File/JsonFile.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/File/MarkdownFile.php b/system/src/Grav/Framework/File/MarkdownFile.php index 4ae3aa0..a79d5ce 100644 --- a/system/src/Grav/Framework/File/MarkdownFile.php +++ b/system/src/Grav/Framework/File/MarkdownFile.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -28,4 +28,13 @@ class MarkdownFile extends DataFile { parent::__construct($filepath, $formatter); } + + /** + * @return array + */ + public function load(): array + { + /** @var array */ + return parent::load(); + } } diff --git a/system/src/Grav/Framework/File/YamlFile.php b/system/src/Grav/Framework/File/YamlFile.php index 29224ce..c4300ad 100644 --- a/system/src/Grav/Framework/File/YamlFile.php +++ b/system/src/Grav/Framework/File/YamlFile.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\File * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -28,4 +28,13 @@ class YamlFile extends DataFile { parent::__construct($filepath, $formatter); } + + /** + * @return array + */ + public function load(): array + { + /** @var array */ + return parent::load(); + } } diff --git a/system/src/Grav/Framework/Filesystem/Filesystem.php b/system/src/Grav/Framework/Filesystem/Filesystem.php index 9b077d7..ddbbab0 100644 --- a/system/src/Grav/Framework/Filesystem/Filesystem.php +++ b/system/src/Grav/Framework/Filesystem/Filesystem.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Filesystem * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -15,6 +15,7 @@ use Grav\Framework\Filesystem\Interfaces\FilesystemInterface; use RuntimeException; use function count; use function dirname; +use function is_array; use function pathinfo; /** @@ -150,7 +151,10 @@ class Filesystem implements FilesystemInterface */ public function basename(string $path, ?string $suffix = null): string { - return $suffix ? basename($path, $suffix) : basename($path); + // Escape path. + $path = str_replace(['%2F', '%5C'], '/', rawurlencode($path)); + + return rawurldecode($suffix ? basename($path, $suffix) : basename($path)); } /** @@ -176,6 +180,7 @@ class Filesystem implements FilesystemInterface * @param string $path * @param int $levels * @return string + * @phpstan-param positive-int $levels */ public function pathname(string $path, int $levels = 1): string { @@ -204,6 +209,7 @@ class Filesystem implements FilesystemInterface * @param string $path * @param int $levels * @return array + * @phpstan-param positive-int $levels */ protected function dirnameInternal(?string $scheme, string $path, int $levels = 1): array { @@ -229,20 +235,30 @@ class Filesystem implements FilesystemInterface */ protected function pathinfoInternal(?string $scheme, string $path, ?int $options = null) { - if ($options) { - return pathinfo($path, $options); + $path = str_replace(['%2F', '%5C'], ['/', '\\'], rawurlencode($path)); + + if (null === $options) { + $info = pathinfo($path); + } else { + $info = pathinfo($path, $options); } - $info = pathinfo($path); + if (!is_array($info)) { + return rawurldecode($info); + } + + $info = array_map('rawurldecode', $info); if (null !== $scheme) { $info['scheme'] = $scheme; - $dirname = isset($info['dirname']) && $info['dirname'] !== '.' ? $info['dirname'] : null; - if (null !== $dirname) { + /** @phpstan-ignore-next-line because pathinfo('') doesn't have dirname */ + $dirname = $info['dirname'] ?? '.'; + + if ('' !== $dirname && '.' !== $dirname) { // In Windows dirname may be using backslashes, fix that. if (DIRECTORY_SEPARATOR !== '/') { - $dirname = str_replace('\\', '/', $dirname); + $dirname = str_replace(DIRECTORY_SEPARATOR, '/', $dirname); } $info['dirname'] = $scheme . '://' . $dirname; diff --git a/system/src/Grav/Framework/Filesystem/Interfaces/FilesystemInterface.php b/system/src/Grav/Framework/Filesystem/Interfaces/FilesystemInterface.php index 0e280a8..4006c8f 100644 --- a/system/src/Grav/Framework/Filesystem/Interfaces/FilesystemInterface.php +++ b/system/src/Grav/Framework/Filesystem/Interfaces/FilesystemInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Filesystem * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -31,6 +31,7 @@ interface FilesystemInterface * @param int $levels The number of parent directories to go up (>= 1). * @return string Returns parent path. * @throws RuntimeException + * @phpstan-param positive-int $levels * @api */ public function parent(string $path, int $levels = 1): string; @@ -46,7 +47,7 @@ interface FilesystemInterface public function normalize(string $path): string; /** - * Returns filename component of path. + * Unicode-safe and stream-safe `\basename()` replacement. * * @param string $path A filename or path, does not need to exist as a file. * @param string|null $suffix If the filename ends in suffix this will also be cut off. @@ -56,7 +57,7 @@ interface FilesystemInterface public function basename(string $path, ?string $suffix = null): string; /** - * Stream-safe `\dirname()` replacement. + * Unicode-safe and stream-safe `\dirname()` replacement. * * @see http://php.net/manual/en/function.dirname.php * @@ -64,12 +65,13 @@ interface FilesystemInterface * @param int $levels The number of parent directories to go up (>= 1). * @return string Returns path to the directory. * @throws RuntimeException + * @phpstan-param positive-int $levels * @api */ public function dirname(string $path, int $levels = 1): string; /** - * Stream-safe `\pathinfo()` replacement. + * Unicode-safe and stream-safe `\pathinfo()` replacement. * * @see http://php.net/manual/en/function.pathinfo.php * diff --git a/system/src/Grav/Framework/Flex/Flex.php b/system/src/Grav/Framework/Flex/Flex.php index ce28521..4d662d1 100644 --- a/system/src/Grav/Framework/Flex/Flex.php +++ b/system/src/Grav/Framework/Flex/Flex.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -62,7 +62,7 @@ class Flex implements FlexInterface */ public function addDirectoryType(string $type, string $blueprint, array $config = []) { - $config = array_replace_recursive(['enabled' => true], $this->config ?? [], $config); + $config = array_replace_recursive(['enabled' => true], $this->config, $config); $this->types[$type] = new FlexDirectory($type, $blueprint, $config); @@ -123,6 +123,7 @@ class Flex implements FlexInterface * @param array|null $keys * @param string|null $keyField * @return FlexCollectionInterface|null + * @phpstan-return FlexCollectionInterface|null */ public function getCollection(string $type, array $keys = null, string $keyField = null): ?FlexCollectionInterface { @@ -137,11 +138,12 @@ class Flex implements FlexInterface * collection_class: Class to be used to create the collection. Defaults to ObjectCollection. * @return FlexCollectionInterface * @throws RuntimeException + * @phpstan-return FlexCollectionInterface */ public function getMixedCollection(array $keys, array $options = []): FlexCollectionInterface { $collectionClass = $options['collection_class'] ?? ObjectCollection::class; - if (!class_exists($collectionClass)) { + if (!is_a($collectionClass, FlexCollectionInterface::class, true)) { throw new RuntimeException(sprintf('Cannot create collection: Class %s does not exist', $collectionClass)); } @@ -231,7 +233,7 @@ class Flex implements FlexInterface // Use the original key ordering. if (!$guessed) { - $list = array_replace(array_fill_keys($keys, null), $list) ?? []; + $list = array_replace(array_fill_keys($keys, null), $list); } else { // We have mixed keys, we need to map flex keys back to storage keys. $results = []; diff --git a/system/src/Grav/Framework/Flex/FlexCollection.php b/system/src/Grav/Framework/Flex/FlexCollection.php index 54e0665..186c60a 100644 --- a/system/src/Grav/Framework/Flex/FlexCollection.php +++ b/system/src/Grav/Framework/Flex/FlexCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -19,6 +19,7 @@ use Grav\Common\User\Interfaces\UserInterface; use Grav\Common\Utils; use Grav\Framework\Cache\CacheInterface; use Grav\Framework\ContentBlock\HtmlBlock; +use Grav\Framework\Flex\Interfaces\FlexIndexInterface; use Grav\Framework\Flex\Interfaces\FlexObjectInterface; use Grav\Framework\Object\ObjectCollection; use Grav\Framework\Flex\Interfaces\FlexCollectionInterface; @@ -47,7 +48,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface private $_flexDirectory; /** @var string */ - private $_keyField; + private $_keyField = 'storage_key'; /** * Get list of cached methods. @@ -124,6 +125,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface */ public function getFlexFeatures(): array { + /** @var array $implements */ $implements = class_implements($this); $list = []; @@ -152,7 +154,11 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface arsort($matching, SORT_NUMERIC); } - return $this->select(array_keys($matching)); + /** @var string[] $array */ + $array = array_keys($matching); + + /** @phpstan-var static */ + return $this->select($array); } /** @@ -163,7 +169,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface { $criteria = Criteria::create()->orderBy($order); - /** @var FlexCollectionInterface $matching */ + /** @phpstan-var FlexCollectionInterface $matching */ $matching = $this->matching($criteria); return $matching; @@ -171,7 +177,8 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface /** * @param array $filters - * @return FlexCollectionInterface|Collection + * @return static + * @phpstan-return static */ public function filterBy(array $filters) { @@ -182,6 +189,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface $criteria->andWhere($expr->eq($key, $value)); } + /** @phpstan-var static */ return $this->matching($criteria); } @@ -336,6 +344,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface */ public function getIndex() { + /** @phpstan-var FlexIndexInterface */ return $this->getFlexDirectory()->getIndex($this->getKeys(), $this->getKeyField()); } @@ -460,7 +469,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface * @param string $key * @return array */ - public function getMetaData(string $key): array + public function getMetaData($key): array { $object = $this->get($key); @@ -481,7 +490,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface */ public function getKeyField(): string { - return $this->_keyField ?? 'storage_key'; + return $this->_keyField; } /** @@ -496,13 +505,18 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface $list = $this->call('isAuthorized', [$action, $scope, $user]); $list = array_filter($list); - return $this->select(array_keys($list)); + /** @var string[] $keys */ + $keys = array_keys($list); + + /** @phpstan-var static */ + return $this->select($keys); } /** * @param string $value * @param string $field - * @return T|null + * @return FlexObjectInterface|null + * @phpstan-return T|null */ public function find($value, $field = 'id') { @@ -520,6 +534,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface /** * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { $elements = []; @@ -538,6 +553,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface /** * @return array */ + #[\ReturnTypeWillChange] public function __debugInfo() { return [ diff --git a/system/src/Grav/Framework/Flex/FlexDirectory.php b/system/src/Grav/Framework/Flex/FlexDirectory.php index 29f1490..f96633b 100644 --- a/system/src/Grav/Framework/Flex/FlexDirectory.php +++ b/system/src/Grav/Framework/Flex/FlexDirectory.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -21,7 +21,7 @@ use Grav\Common\Utils; use Grav\Framework\Cache\Adapter\DoctrineCache; use Grav\Framework\Cache\Adapter\MemoryCache; use Grav\Framework\Cache\CacheInterface; -use Grav\Framework\Flex\Interfaces\FlexAuthorizeInterface; +use Grav\Framework\Filesystem\Filesystem; use Grav\Framework\Flex\Interfaces\FlexCollectionInterface; use Grav\Framework\Flex\Interfaces\FlexDirectoryInterface; use Grav\Framework\Flex\Interfaces\FlexFormInterface; @@ -45,7 +45,6 @@ use function is_callable; /** * Class FlexDirectory * @package Grav\Framework\Flex - * @template T */ class FlexDirectory implements FlexDirectoryInterface { @@ -57,9 +56,15 @@ class FlexDirectory implements FlexDirectoryInterface protected $blueprint_file; /** @var Blueprint[] */ protected $blueprints; - /** @var FlexIndexInterface[] */ + /** + * @var FlexIndexInterface[] + * @phpstan-var FlexIndexInterface[] + */ protected $indexes = []; - /** @var FlexCollectionInterface|null */ + /** + * @var FlexCollectionInterface|null + * @phpstan-var FlexCollectionInterface|null + */ protected $collection; /** @var bool */ protected $enabled; @@ -213,8 +218,17 @@ class FlexDirectory implements FlexDirectoryInterface /** @var UniformResourceLocator $locator */ $locator = $grav['locator']; - /** @var string $filename Filename is always string */ - $filename = $locator->findResource($this->getDirectoryConfigUri($name), true, true); + + $filename = $this->getDirectoryConfigUri($name); + if (file_exists($filename)) { + $filename = $locator->findResource($filename, true); + } else { + $filesystem = Filesystem::getInstance(); + $dirname = $filesystem->dirname($filename); + $basename = $filesystem->basename($filename); + $dirname = $locator->findResource($dirname, true) ?: $locator->findResource($dirname, true, true); + $filename = "{$dirname}/{$basename}"; + } $file = YamlFile::instance($filename); if (!empty($data)) { @@ -318,7 +332,7 @@ class FlexDirectory implements FlexDirectoryInterface * @param array|null $keys Array of keys. * @param string|null $keyField Field to be used as the key. * @return FlexCollectionInterface - * @phpstan-return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface */ public function getCollection(array $keys = null, string $keyField = null): FlexCollectionInterface { @@ -345,6 +359,7 @@ class FlexDirectory implements FlexDirectoryInterface * @param array|null $keys Array of keys. * @param string|null $keyField Field to be used as the key. * @return FlexIndexInterface + * @phpstan-return FlexIndexInterface */ public function getIndex(array $keys = null, string $keyField = null): FlexIndexInterface { @@ -353,7 +368,7 @@ class FlexDirectory implements FlexDirectoryInterface $index = clone $index; if (null !== $keys) { - /** @var FlexIndexInterface $index */ + /** @var FlexIndexInterface $index */ $index = $index->select($keys); } @@ -487,8 +502,11 @@ class FlexDirectory implements FlexDirectoryInterface */ public function createObject(array $data, string $key = '', bool $validate = false): FlexObjectInterface { - /** @var string|FlexObjectInterface $className */ + /** @phpstan-var class-string $className */ $className = $this->objectClassName ?: $this->getObjectClass(); + if (!is_a($className, FlexObjectInterface::class, true)) { + throw new \RuntimeException('Bad object class: ' . $className); + } return new $className($data, $key, $this, $validate); } @@ -497,11 +515,15 @@ class FlexDirectory implements FlexDirectoryInterface * @param array $entries * @param string|null $keyField * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface */ public function createCollection(array $entries, string $keyField = null): FlexCollectionInterface { - /** @var string|FlexCollectionInterface $className */ + /** phpstan-var class-string $className */ $className = $this->collectionClassName ?: $this->getCollectionClass(); + if (!is_a($className, FlexCollectionInterface::class, true)) { + throw new \RuntimeException('Bad collection class: ' . $className); + } return $className::createFromArray($entries, $this, $keyField); } @@ -510,11 +532,15 @@ class FlexDirectory implements FlexDirectoryInterface * @param array $entries * @param string|null $keyField * @return FlexIndexInterface + * @phpstan-return FlexIndexInterface */ public function createIndex(array $entries, string $keyField = null): FlexIndexInterface { - /** @var string|FlexIndexInterface $className */ + /** @phpstan-var class-string $className */ $className = $this->indexClassName ?: $this->getIndexClass(); + if (!is_a($className, FlexIndexInterface::class, true)) { + throw new \RuntimeException('Bad index class: ' . $className); + } return $className::createFromArray($entries, $this, $keyField); } @@ -560,6 +586,7 @@ class FlexDirectory implements FlexDirectoryInterface * @param array $entries * @param string|null $keyField * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface */ public function loadCollection(array $entries, string $keyField = null): FlexCollectionInterface { @@ -889,12 +916,17 @@ class FlexDirectory implements FlexDirectoryInterface $className = $storage['class'] ?? SimpleStorage::class; $options = $storage['options'] ?? []; + if (!is_a($className, FlexStorageInterface::class, true)) { + throw new \RuntimeException('Bad storage class: ' . $className); + } + return new $className($options); } /** * @param string $keyField * @return FlexIndexInterface + * @phpstan-return FlexIndexInterface */ protected function loadIndex(string $keyField): FlexIndexInterface { @@ -924,7 +956,7 @@ class FlexDirectory implements FlexDirectoryInterface } if (!is_array($keys)) { - /** @var string|FlexIndexInterface $className */ + /** @phpstan-var class-string $className */ $className = $this->getIndexClass(); $keys = $className::loadEntriesFromStorage($storage); if (!$cache instanceof MemoryCache) { @@ -946,7 +978,7 @@ class FlexDirectory implements FlexDirectoryInterface // We need to do this in two steps as orderBy() calls loadIndex() again and we do not want infinite loop. $this->indexes['storage_key'] = $index = $this->createIndex($keys, 'storage_key'); if ($ordering) { - /** @var FlexCollectionInterface $collection */ + /** @var FlexCollectionInterface $collection */ $collection = $this->indexes['storage_key']->orderBy($ordering); $this->indexes['storage_key'] = $index = $collection->getIndex(); } @@ -1035,7 +1067,9 @@ class FlexDirectory implements FlexDirectoryInterface $newKey = $object->getStorageKey(); if ($oldKey !== $newKey) { - $object->triggerEvent('move'); + if (method_exists($object, 'triggerEvent')) { + $object->triggerEvent('move'); + } $storage->renameRow($oldKey, $newKey); // TODO: media support. } diff --git a/system/src/Grav/Framework/Flex/FlexDirectoryForm.php b/system/src/Grav/Framework/Flex/FlexDirectoryForm.php index 8d608fd..709f418 100644 --- a/system/src/Grav/Framework/Flex/FlexDirectoryForm.php +++ b/system/src/Grav/Framework/Flex/FlexDirectoryForm.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -358,6 +358,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, JsonSerializable * @param string $name * @return mixed|null */ + #[\ReturnTypeWillChange] public function __get($name) { $method = "get{$name}"; @@ -375,6 +376,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, JsonSerializable * @param mixed $value * @return void */ + #[\ReturnTypeWillChange] public function __set($name, $value) { $method = "set{$name}"; @@ -387,6 +389,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, JsonSerializable * @param string $name * @return bool */ + #[\ReturnTypeWillChange] public function __isset($name) { $method = "get{$name}"; @@ -403,6 +406,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, JsonSerializable * @param string $name * @return void */ + #[\ReturnTypeWillChange] public function __unset($name) { } @@ -493,6 +497,7 @@ class FlexDirectoryForm implements FlexDirectoryFormInterface, JsonSerializable * Filter validated data. * * @param ArrayAccess|Data|null $data + * @phpstan-param ArrayAccess|Data|null $data */ protected function filterData($data = null): void { diff --git a/system/src/Grav/Framework/Flex/FlexForm.php b/system/src/Grav/Framework/Flex/FlexForm.php index d25cefc..a1263f6 100644 --- a/system/src/Grav/Framework/Flex/FlexForm.php +++ b/system/src/Grav/Framework/Flex/FlexForm.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -444,6 +444,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable * @param string $name * @return mixed|null */ + #[\ReturnTypeWillChange] public function __get($name) { $method = "get{$name}"; @@ -461,6 +462,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable * @param mixed $value * @return void */ + #[\ReturnTypeWillChange] public function __set($name, $value) { $method = "set{$name}"; @@ -473,6 +475,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable * @param string $name * @return bool */ + #[\ReturnTypeWillChange] public function __isset($name) { $method = "get{$name}"; @@ -489,6 +492,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable * @param string $name * @return void */ + #[\ReturnTypeWillChange] public function __unset($name) { } @@ -594,6 +598,7 @@ class FlexForm implements FlexObjectFormInterface, JsonSerializable * * @param ArrayAccess|Data|null $data * @return void + * @phpstan-param ArrayAccess|Data|null $data */ protected function filterData($data = null): void { diff --git a/system/src/Grav/Framework/Flex/FlexFormFlash.php b/system/src/Grav/Framework/Flex/FlexFormFlash.php index feb7a9e..3f52cdb 100644 --- a/system/src/Grav/Framework/Flex/FlexFormFlash.php +++ b/system/src/Grav/Framework/Flex/FlexFormFlash.php @@ -3,7 +3,7 @@ /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/FlexIndex.php b/system/src/Grav/Framework/Flex/FlexIndex.php index 3ce0a46..54438af 100644 --- a/system/src/Grav/Framework/Flex/FlexIndex.php +++ b/system/src/Grav/Framework/Flex/FlexIndex.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -11,6 +11,7 @@ namespace Grav\Framework\Flex; use Exception; use Grav\Common\Debugger; +use Grav\Common\File\CompiledJsonFile; use Grav\Common\File\CompiledYamlFile; use Grav\Common\Grav; use Grav\Common\Inflector; @@ -39,14 +40,14 @@ use function in_array; * @implements FlexIndexInterface * @mixin C */ -class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexIndexInterface +class FlexIndex extends ObjectIndex implements FlexIndexInterface { const VERSION = 1; /** @var FlexDirectory|null */ private $_flexDirectory; /** @var string */ - private $_keyField; + private $_keyField = 'storage_key'; /** @var array */ private $_indexKeys; @@ -117,6 +118,14 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde $this->setKeyField(null); } + /** + * @return string + */ + public function getKey() + { + return $this->_key ?: $this->getFlexType() . '@@' . spl_object_hash($this); + } + /** * {@inheritdoc} * @see FlexCommonInterface::hasFlexFeature() @@ -132,6 +141,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde */ public function getFlexFeatures(): array { + /** @var array $implements */ $implements = class_implements($this->getFlexDirectory()->getCollectionClass()); $list = []; @@ -164,7 +174,6 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde return $this->orderBy($orderings); } - /** * {@inheritdoc} * @see FlexCollectionInterface::filterBy() @@ -353,7 +362,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde */ public function getKeyField(): string { - return $this->_keyField ?? 'storage_key'; + return $this->_keyField; } /** @@ -416,7 +425,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde $previous = $search; } - return $this->createFrom(array_replace($previous ?? [], $this->getEntries()) ?? []); + return $this->createFrom(array_replace($previous ?? [], $this->getEntries())); } /** @@ -432,12 +441,13 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde * @param array $arguments * @return mixed */ + #[\ReturnTypeWillChange] public function __call($name, $arguments) { /** @var Debugger $debugger */ $debugger = Grav::instance()['debugger']; - /** @var FlexCollection $className */ + /** @phpstan-var class-string $className */ $className = $this->getFlexDirectory()->getCollectionClass(); $cachedMethods = $className::getCachedMethods(); @@ -492,9 +502,13 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde } } else { $collection = $this->loadCollection(); - $result = $collection->{$name}(...$arguments); - if (!isset($cachedMethods[$name])) { - $debugger->addMessage("Call '{$flexType}:{$name}()' isn't cached", 'debug'); + if (\is_callable([$collection, $name])) { + $result = $collection->{$name}(...$arguments); + if (!isset($cachedMethods[$name])) { + $debugger->addMessage("Call '{$flexType}:{$name}()' isn't cached", 'debug'); + } + } else { + $result = null; } } @@ -522,6 +536,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde /** * @return array */ + #[\ReturnTypeWillChange] public function __debugInfo() { return [ @@ -607,9 +622,11 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde * @param string $key * @param mixed $value * @return ObjectInterface|null + * @phpstan-return T|null */ protected function loadElement($key, $value): ?ObjectInterface { + /** @phpstan-var T[] $objects */ $objects = $this->getFlexDirectory()->loadObjects([$key => $value]); return $objects ? reset($objects): null; @@ -618,10 +635,14 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde /** * @param array|null $entries * @return ObjectInterface[] + * @phpstan-return T[] */ protected function loadElements(array $entries = null): array { - return $this->getFlexDirectory()->loadObjects($entries ?? $this->getEntries()); + /** @phpstan-var T[] $objects */ + $objects = $this->getFlexDirectory()->loadObjects($entries ?? $this->getEntries()); + + return $objects; } /** @@ -824,7 +845,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde /** * @param FlexStorageInterface $storage - * @return CompiledYamlFile|null + * @return CompiledYamlFile|CompiledJsonFile|null */ protected static function getIndexFile(FlexStorageInterface $storage) { diff --git a/system/src/Grav/Framework/Flex/FlexObject.php b/system/src/Grav/Framework/Flex/FlexObject.php index ac51b34..afc656c 100644 --- a/system/src/Grav/Framework/Flex/FlexObject.php +++ b/system/src/Grav/Framework/Flex/FlexObject.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -69,13 +69,13 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface private $_forms = []; /** @var Blueprint[] */ private $_blueprint = []; - /** @var array */ + /** @var array|null */ private $_meta; - /** @var array */ + /** @var array|null */ protected $_original; - /** @var string */ + /** @var string|null */ protected $storage_key; - /** @var int */ + /** @var int|null */ protected $storage_timestamp; /** @@ -163,6 +163,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface */ public function getFlexFeatures(): array { + /** @var array $implements */ $implements = class_implements($this); $list = []; @@ -656,6 +657,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface /** * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->getElements(); @@ -775,7 +777,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface $value = reset($result); $meta = $value['__META'] ?? null; if ($meta) { - /** @var FlexIndex $indexClass */ + /** @phpstan-var class-string $indexClass */ $indexClass = $this->getFlexDirectory()->getIndexClass(); $indexClass::updateObjectMeta($meta, $value, $storage); $this->_meta = $meta; @@ -887,8 +889,8 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface public function getDefaultValue(string $name, string $separator = null) { $separator = $separator ?: '.'; - $path = explode($separator, $name) ?: []; - $offset = array_shift($path) ?? ''; + $path = explode($separator, $name); + $offset = array_shift($path); $current = $this->getDefaultValues(); @@ -950,6 +952,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface * * @return string */ + #[\ReturnTypeWillChange] public function __toString() { return $this->getFlexKey(); @@ -958,6 +961,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface /** * @return array */ + #[\ReturnTypeWillChange] public function __debugInfo() { return [ @@ -973,6 +977,7 @@ class FlexObject implements FlexObjectInterface, FlexAuthorizeInterface /** * Clone object. */ + #[\ReturnTypeWillChange] public function __clone() { // Allows future compatibility as parent::__clone() works. diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexAuthorizeInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexAuthorizeInterface.php index 102dbf4..c1025a4 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexAuthorizeInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexAuthorizeInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexCollectionInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexCollectionInterface.php index 16be3d5..d14b69f 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexCollectionInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexCollectionInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -140,5 +140,5 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI * @param string $key Key. * @return array */ - public function getMetaData(string $key): array; + public function getMetaData($key): array; } diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexCommonInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexCommonInterface.php index ed045e2..7c1975f 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexCommonInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexCommonInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexDirectoryFormInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexDirectoryFormInterface.php index df6f7d6..203c766 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexDirectoryFormInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexDirectoryFormInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexDirectoryInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexDirectoryInterface.php index 07eab01..a77df95 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexDirectoryInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexDirectoryInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -105,6 +105,7 @@ interface FlexDirectoryInterface extends FlexAuthorizeInterface * @param array|null $keys Array of keys. * @param string|null $keyField Field to be used as the key. * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface */ public function getCollection(array $keys = null, string $keyField = null): FlexCollectionInterface; @@ -116,6 +117,7 @@ interface FlexDirectoryInterface extends FlexAuthorizeInterface * @param array|null $keys Array of keys. * @param string|null $keyField Field to be used as the key. * @return FlexIndexInterface + * @phpstan-return FlexIndexInterface */ public function getIndex(array $keys = null, string $keyField = null): FlexIndexInterface; @@ -170,6 +172,7 @@ interface FlexDirectoryInterface extends FlexAuthorizeInterface * @param array $entries * @param string|null $keyField * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface */ public function createCollection(array $entries, string $keyField = null): FlexCollectionInterface; @@ -177,6 +180,7 @@ interface FlexDirectoryInterface extends FlexAuthorizeInterface * @param array $entries * @param string|null $keyField * @return FlexIndexInterface + * @phpstan-return FlexIndexInterface */ public function createIndex(array $entries, string $keyField = null): FlexIndexInterface; @@ -199,6 +203,7 @@ interface FlexDirectoryInterface extends FlexAuthorizeInterface * @param array $entries * @param string|null $keyField * @return FlexCollectionInterface + * @phpstan-return FlexCollectionInterface */ public function loadCollection(array $entries, string $keyField = null): FlexCollectionInterface; diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexFormInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexFormInterface.php index 32dab19..ba9996a 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexFormInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexFormInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -43,4 +43,9 @@ interface FlexFormInterface extends Serializable, FormInterface * @return Route|null Returns Route object or null if file uploads are not enabled. */ public function getFileDeleteAjaxRoute($field, $filename); + +// /** +// * @return FlexObjectInterface +// */ +// public function getObject(); } diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexIndexInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexIndexInterface.php index 71dd727..d8f8ba3 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexIndexInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexIndexInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexInterface.php index 3c5a103..f1376a5 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -59,6 +59,7 @@ interface FlexInterface extends Countable * @param array|null $keys * @param string|null $keyField * @return FlexCollectionInterface|null + * @phpstan-return FlexCollectionInterface|null */ public function getCollection(string $type, array $keys = null, string $keyField = null): ?FlexCollectionInterface; @@ -68,6 +69,7 @@ interface FlexInterface extends Countable * collection_class: Class to be used to create the collection. Defaults to ObjectCollection. * @return FlexCollectionInterface * @throws RuntimeException + * @phpstan-return FlexCollectionInterface */ public function getMixedCollection(array $keys, array $options = []): FlexCollectionInterface; diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexObjectFormInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexObjectFormInterface.php index 044ee61..190a963 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexObjectFormInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexObjectFormInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexObjectInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexObjectInterface.php index a1e3e3b..d02bc8b 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexObjectInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexObjectInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -23,6 +23,7 @@ use RuntimeException; /** * Defines Flex Objects. * + * @extends ArrayAccess * @used-by \Grav\Framework\Flex\FlexObject * @since 1.6 */ diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexStorageInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexStorageInterface.php index 08c4335..4209924 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexStorageInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexStorageInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/Interfaces/FlexTranslateInterface.php b/system/src/Grav/Framework/Flex/Interfaces/FlexTranslateInterface.php index 28e4888..8df11fa 100644 --- a/system/src/Grav/Framework/Flex/Interfaces/FlexTranslateInterface.php +++ b/system/src/Grav/Framework/Flex/Interfaces/FlexTranslateInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/Pages/FlexPageCollection.php b/system/src/Grav/Framework/Flex/Pages/FlexPageCollection.php index 9482568..5901557 100644 --- a/system/src/Grav/Framework/Flex/Pages/FlexPageCollection.php +++ b/system/src/Grav/Framework/Flex/Pages/FlexPageCollection.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -13,6 +13,7 @@ namespace Grav\Framework\Flex\Pages; use Grav\Common\Page\Interfaces\PageInterface; use Grav\Framework\Flex\FlexCollection; +use Grav\Framework\Flex\Interfaces\FlexObjectInterface; use function array_search; use function assert; use function is_int; @@ -20,7 +21,7 @@ use function is_int; /** * Class FlexPageCollection * @package Grav\Plugin\FlexObjects\Types\FlexPages - * @template T of \Grav\Framework\Flex\Interfaces\FlexObjectInterface + * @template T of FlexObjectInterface * @extends FlexCollection */ class FlexPageCollection extends FlexCollection @@ -56,8 +57,10 @@ class FlexPageCollection extends FlexCollection */ public function withPublished(bool $bool = true) { + /** @var string[] $list */ $list = array_keys(array_filter($this->call('isPublished', [$bool]))); + /** @phpstan-var static */ return $this->select($list); } @@ -68,8 +71,10 @@ class FlexPageCollection extends FlexCollection */ public function withVisible(bool $bool = true) { + /** @var string[] $list */ $list = array_keys(array_filter($this->call('isVisible', [$bool]))); + /** @phpstan-var static */ return $this->select($list); } @@ -80,8 +85,10 @@ class FlexPageCollection extends FlexCollection */ public function withRoutable(bool $bool = true) { + /** @var string[] $list */ $list = array_keys(array_filter($this->call('isRoutable', [$bool]))); + /** @phpstan-var static */ return $this->select($list); } @@ -148,9 +155,10 @@ class FlexPageCollection extends FlexCollection public function adjacentSibling($path, $direction = 1) { $keys = $this->getKeys(); + $direction = (int)$direction; $pos = array_search($path, $keys, true); - if ($pos !== false) { + if (is_int($pos)) { $pos += $direction; if (isset($keys[$pos])) { return $this[$keys[$pos]]; @@ -170,7 +178,7 @@ class FlexPageCollection extends FlexCollection { $pos = array_search($path, $this->getKeys(), true); - return $pos !== false ? $pos : null; + return is_int($pos) ? $pos : null; } /** @@ -184,7 +192,6 @@ class FlexPageCollection extends FlexCollection $keys = $collection->getStorageKeys(); // Assign next free order. - /** @var FlexPageObject|null $last */ $last = null; $order = 0; foreach ($keys as $folder => $key) { @@ -196,8 +203,9 @@ class FlexPageCollection extends FlexCollection } } + /** @var FlexPageObject|null $last */ $last = $collection[$last]; - return sprintf('%d.', $last ? $last->value('order') + 1 : 1); + return sprintf('%d.', $last ? $last->getFormValue('order') + 1 : 1); } } diff --git a/system/src/Grav/Framework/Flex/Pages/FlexPageIndex.php b/system/src/Grav/Framework/Flex/Pages/FlexPageIndex.php index 904d1f6..5bb5517 100644 --- a/system/src/Grav/Framework/Flex/Pages/FlexPageIndex.php +++ b/system/src/Grav/Framework/Flex/Pages/FlexPageIndex.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php b/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php index ebc26b4..e700424 100644 --- a/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php +++ b/system/src/Grav/Framework/Flex/Pages/FlexPageObject.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -55,6 +55,7 @@ class FlexPageObject extends FlexObject implements PageInterface, FlexTranslateI /** * Clone page. */ + #[\ReturnTypeWillChange] public function __clone() { parent::__clone(); diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageAuthorsTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageAuthorsTrait.php index 5d3e968..d0934e1 100644 --- a/system/src/Grav/Framework/Flex/Pages/Traits/PageAuthorsTrait.php +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageAuthorsTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageContentTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageContentTrait.php index 6aff732..43dfee1 100644 --- a/system/src/Grav/Framework/Flex/Pages/Traits/PageContentTrait.php +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageContentTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -75,13 +75,13 @@ trait PageContentTrait 'template' => 'template', ]; - /** @var object */ + /** @var object|null */ protected $header; - /** @var string */ + /** @var string|null */ protected $_summary; - /** @var string */ + /** @var string|null */ protected $_content; /** @@ -100,6 +100,7 @@ trait PageContentTrait /** * @inheritdoc + * @return Header */ public function header($var = null) { @@ -288,7 +289,7 @@ trait PageContentTrait 'process', $var, function ($value) { - $value = array_replace(Grav::instance()['config']->get('system.pages.process', []), is_array($value) ? $value : []) ?? []; + $value = array_replace(Grav::instance()['config']->get('system.pages.process', []), is_array($value) ? $value : []); foreach ($value as $process => $status) { $value[$process] = (bool)$status; } @@ -664,6 +665,7 @@ trait PageContentTrait */ protected function processContent($content): string { + $content = is_string($content) ? $content : ''; $grav = Grav::instance(); /** @var Config $config */ @@ -676,7 +678,6 @@ trait PageContentTrait $twig_first = $this->getNestedProperty('header.twig_first') ?? $config->get('system.pages.twig_first', false); $never_cache_twig = $this->getNestedProperty('header.never_cache_twig') ?? $config->get('system.pages.never_cache_twig', false); - $cached = null; if ($cache_enable) { $cache = $this->getCache('render'); $key = md5($this->getCacheKey() . '-content'); @@ -688,12 +689,10 @@ trait PageContentTrait if ($process_twig && $never_cache_twig) { $this->_content = $this->processTwig($this->_content); } - } else { - $cached = null; } } - if (!$cached) { + if (null === $this->_content) { $markdown_options = []; if ($process_markdown) { // Build markdown options. @@ -746,6 +745,7 @@ trait PageContentTrait } if ($process_twig) { + \assert(is_string($this->_content)); $this->_content = $this->processTwig($this->_content); } } @@ -755,6 +755,8 @@ trait PageContentTrait } } + \assert(is_string($this->_content)); + // Handle summary divider $delimiter = $config->get('site.summary.delimiter', '==='); $divider_pos = mb_strpos($this->_content, "

{$delimiter}

"); diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageLegacyTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageLegacyTrait.php index 6453bcf..d753803 100644 --- a/system/src/Grav/Framework/Flex/Pages/Traits/PageLegacyTrait.php +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageLegacyTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -17,13 +17,12 @@ use Grav\Common\Page\Interfaces\PageInterface; use Grav\Common\Page\Pages; use Grav\Common\Utils; use Grav\Common\Yaml; -use Grav\Framework\Cache\CacheInterface; use Grav\Framework\File\Formatter\MarkdownFormatter; use Grav\Framework\File\Formatter\YamlFormatter; use Grav\Framework\Filesystem\Filesystem; -use Grav\Framework\Flex\FlexDirectory; use Grav\Framework\Flex\Interfaces\FlexCollectionInterface; use Grav\Framework\Flex\Interfaces\FlexIndexInterface; +use Grav\Framework\Flex\Pages\FlexPageCollection; use Grav\Framework\Flex\Pages\FlexPageIndex; use Grav\Framework\Flex\Pages\FlexPageObject; use InvalidArgumentException; @@ -300,7 +299,7 @@ trait PageLegacyTrait $parentStorageKey = ltrim($filesystem->dirname("/{$this->getMasterKey()}"), '/'); - /** @var FlexPageIndex $index */ + /** @var FlexPageIndex> $index */ $index = $this->getFlexDirectory()->getIndex(); if ($parent) { @@ -323,8 +322,9 @@ trait PageLegacyTrait if ($this instanceof FlexPageObject) { $key = trim($parentKey . '/' . $this->folder(), '/'); $key = preg_replace(static::PAGE_ORDER_PREFIX_REGEX, '', $key); + \assert(is_string($key)); } else { - $key = trim($parentKey . '/' . basename($this->getKey()), '/'); + $key = trim($parentKey . '/' . Utils::basename($this->getKey()), '/'); } if ($index->containsKey($key)) { @@ -336,7 +336,7 @@ trait PageLegacyTrait } while ($index->containsKey($test)); $key = $test; } - $folder = basename($key); + $folder = Utils::basename($key); // Get the folder name. $order = $this->getProperty('order'); @@ -539,7 +539,7 @@ trait PageLegacyTrait if ($language) { $language = '.' . $language; } - $format = '.' . ($this->getProperty('format') ?? pathinfo($this->name(), PATHINFO_EXTENSION)); + $format = '.' . ($this->getProperty('format') ?? Utils::pathinfo($this->name(), PATHINFO_EXTENSION)); return $language . $format; } diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php index 90773cd..c4c8cd7 100644 --- a/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageRoutableTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -15,10 +15,10 @@ use Grav\Common\Page\Interfaces\PageCollectionInterface; use Grav\Common\Page\Interfaces\PageInterface; use Grav\Common\Page\Pages; use Grav\Common\Uri; +use Grav\Common\Utils; use Grav\Framework\Filesystem\Filesystem; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use RuntimeException; -use function dirname; use function is_string; /** @@ -375,7 +375,7 @@ trait PageRoutableTrait $value = $this->getMasterKey() ?: $this->getKey(); } - return basename($value) ?: null; + return Utils::basename($value) ?: null; } ); } diff --git a/system/src/Grav/Framework/Flex/Pages/Traits/PageTranslateTrait.php b/system/src/Grav/Framework/Flex/Pages/Traits/PageTranslateTrait.php index 877fec1..4bec685 100644 --- a/system/src/Grav/Framework/Flex/Pages/Traits/PageTranslateTrait.php +++ b/system/src/Grav/Framework/Flex/Pages/Traits/PageTranslateTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -26,6 +26,14 @@ trait PageTranslateTrait /** @var PageInterface[] */ private $_translations = []; + /** + * @return bool + */ + public function translated(): bool + { + return (bool)$this->translatedLanguages(true); + } + /** * @param string|null $languageCode * @param bool|null $fallback diff --git a/system/src/Grav/Framework/Flex/Storage/AbstractFilesystemStorage.php b/system/src/Grav/Framework/Flex/Storage/AbstractFilesystemStorage.php index 1934f50..ee04c51 100644 --- a/system/src/Grav/Framework/Flex/Storage/AbstractFilesystemStorage.php +++ b/system/src/Grav/Framework/Flex/Storage/AbstractFilesystemStorage.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -127,6 +127,10 @@ abstract class AbstractFilesystemStorage implements FlexStorageInterface $formatterClassName = $formatter['class'] ?? JsonFormatter::class; $formatterOptions = $formatter['options'] ?? []; + if (!is_a($formatterClassName, FileFormatterInterface::class, true)) { + throw new \InvalidArgumentException('Bad Data Formatter'); + } + $this->dataFormatter = new $formatterClassName($formatterOptions); } diff --git a/system/src/Grav/Framework/Flex/Storage/FileStorage.php b/system/src/Grav/Framework/Flex/Storage/FileStorage.php index eabd658..1864439 100644 --- a/system/src/Grav/Framework/Flex/Storage/FileStorage.php +++ b/system/src/Grav/Framework/Flex/Storage/FileStorage.php @@ -5,13 +5,14 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Framework\Flex\Storage; use FilesystemIterator; +use Grav\Common\Utils; use Grav\Framework\Flex\Interfaces\FlexStorageInterface; use RuntimeException; use SplFileInfo; @@ -125,7 +126,7 @@ class FileStorage extends FolderStorage */ protected function getKeyFromPath(string $path): string { - return basename($path, $this->dataFormatter->getDefaultFileExtension()); + return Utils::basename($path, $this->dataFormatter->getDefaultFileExtension()); } /** diff --git a/system/src/Grav/Framework/Flex/Storage/FolderStorage.php b/system/src/Grav/Framework/Flex/Storage/FolderStorage.php index b2b9533..600e989 100644 --- a/system/src/Grav/Framework/Flex/Storage/FolderStorage.php +++ b/system/src/Grav/Framework/Flex/Storage/FolderStorage.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -352,7 +352,7 @@ class FolderStorage extends AbstractFilesystemStorage */ protected function getKeyFromPath(string $path): string { - return basename($path); + return Utils::basename($path); } /** @@ -688,7 +688,7 @@ class FolderStorage extends AbstractFilesystemStorage $pattern .= '/{FILE}{EXT}'; } else { $filesystem = Filesystem::getInstance(true); - $this->dataFile = basename($pattern, $extension); + $this->dataFile = Utils::basename($pattern, $extension); $pattern = $filesystem->dirname($pattern) . '/{FILE}{EXT}'; } } diff --git a/system/src/Grav/Framework/Flex/Storage/SimpleStorage.php b/system/src/Grav/Framework/Flex/Storage/SimpleStorage.php index 6faac9d..73e2b06 100644 --- a/system/src/Grav/Framework/Flex/Storage/SimpleStorage.php +++ b/system/src/Grav/Framework/Flex/Storage/SimpleStorage.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -13,6 +13,7 @@ namespace Grav\Framework\Flex\Storage; use Grav\Common\Data\Data; use Grav\Common\Filesystem\Folder; +use Grav\Common\Utils; use Grav\Framework\Filesystem\Filesystem; use InvalidArgumentException; use LogicException; @@ -30,7 +31,7 @@ class SimpleStorage extends AbstractFilesystemStorage protected $dataFolder; /** @var string */ protected $dataPattern; - /** @var string */ + /** @var string|null */ protected $prefix; /** @var array|null */ protected $data; @@ -53,9 +54,9 @@ class SimpleStorage extends AbstractFilesystemStorage $filesystem = Filesystem::getInstance(true); $extension = $this->dataFormatter->getDefaultFileExtension(); - $pattern = basename($options['folder']); + $pattern = Utils::basename($options['folder']); - $this->dataPattern = basename($pattern, $extension) . $extension; + $this->dataPattern = Utils::basename($pattern, $extension) . $extension; $this->dataFolder = $filesystem->dirname($options['folder']); $this->keyField = $options['key'] ?? 'storage_key'; $this->keyLen = (int)($options['key_len'] ?? 32); @@ -432,7 +433,7 @@ class SimpleStorage extends AbstractFilesystemStorage */ protected function getKeyFromPath(string $path): string { - return basename($path); + return Utils::basename($path); } /** diff --git a/system/src/Grav/Framework/Flex/Traits/FlexAuthorizeTrait.php b/system/src/Grav/Framework/Flex/Traits/FlexAuthorizeTrait.php index 8cbd1d5..ef4c433 100644 --- a/system/src/Grav/Framework/Flex/Traits/FlexAuthorizeTrait.php +++ b/system/src/Grav/Framework/Flex/Traits/FlexAuthorizeTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Flex/Traits/FlexMediaTrait.php b/system/src/Grav/Framework/Flex/Traits/FlexMediaTrait.php index dabfe17..ad437eb 100644 --- a/system/src/Grav/Framework/Flex/Traits/FlexMediaTrait.php +++ b/system/src/Grav/Framework/Flex/Traits/FlexMediaTrait.php @@ -5,7 +5,7 @@ namespace Grav\Framework\Flex\Traits; /** * @package Grav\Framework\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -44,7 +44,7 @@ trait FlexMediaTrait } /** @var array */ - protected $_uploads; + protected $_uploads = []; /** * @return string|null @@ -119,7 +119,7 @@ trait FlexMediaTrait // Load settings for the field. $schema = $this->getBlueprint()->schema(); - $settings = $field && is_object($schema) ? (array)$schema->getProperty($field) : null; + $settings = (array)$schema->getProperty($field); if (!is_array($settings)) { return null; } @@ -165,6 +165,9 @@ trait FlexMediaTrait return $settings + ['accept' => '*', 'limit' => 1000, 'self' => true]; } + /** + * @return array + */ protected function getMediaFields(): array { // Load settings for the field. @@ -286,6 +289,7 @@ trait FlexMediaTrait /** * @return array */ + #[\ReturnTypeWillChange] public function __debugInfo() { return parent::__debugInfo() + [ @@ -342,7 +346,7 @@ trait FlexMediaTrait } // Calculate path without the retina scaling factor. - $realpath = $filesystem->pathname($filepath) . str_replace(['@3x', '@2x'], '', basename($filepath)); + $realpath = $filesystem->pathname($filepath) . str_replace(['@3x', '@2x'], '', Utils::basename($filepath)); $list[$filename] = [$file, $settings]; @@ -397,11 +401,11 @@ trait FlexMediaTrait } /** - * @return array + * @return array */ protected function getUpdatedMedia(): array { - return $this->_uploads ?? []; + return $this->_uploads; } /** @@ -504,7 +508,7 @@ trait FlexMediaTrait user_error(__METHOD__ . '() is deprecated since Grav 1.7, use Media class that implements MediaUploadInterface instead', E_USER_DEPRECATED); // Check the file extension. - $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); + $extension = strtolower(Utils::pathinfo($filename, PATHINFO_EXTENSION)); $grav = Grav::instance(); diff --git a/system/src/Grav/Framework/Flex/Traits/FlexRelatedDirectoryTrait.php b/system/src/Grav/Framework/Flex/Traits/FlexRelatedDirectoryTrait.php index 9f7380c..de98359 100644 --- a/system/src/Grav/Framework/Flex/Traits/FlexRelatedDirectoryTrait.php +++ b/system/src/Grav/Framework/Flex/Traits/FlexRelatedDirectoryTrait.php @@ -5,15 +5,15 @@ declare(strict_types=1); /** * @package Grav\Common\Flex * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Framework\Flex\Traits; -use Grav\Framework\Flex\FlexCollection; use Grav\Framework\Flex\FlexDirectory; use Grav\Framework\Flex\Interfaces\FlexCollectionInterface; +use Grav\Framework\Flex\Interfaces\FlexObjectInterface; use RuntimeException; use function in_array; @@ -26,7 +26,7 @@ trait FlexRelatedDirectoryTrait /** * @param string $type * @param string $property - * @return FlexCollectionInterface + * @return FlexCollectionInterface */ protected function getCollectionByProperty($type, $property) { @@ -34,9 +34,9 @@ trait FlexRelatedDirectoryTrait $collection = $directory->getCollection(); $list = $this->getNestedProperty($property) ?: []; - /** @var FlexCollection $collection */ + /** @var FlexCollectionInterface $collection */ $collection = $collection->filter(static function ($object) use ($list) { - return in_array($object->id, $list, true); + return in_array($object->getKey(), $list, true); }); return $collection; diff --git a/system/src/Grav/Framework/Form/FormFlash.php b/system/src/Grav/Framework/Form/FormFlash.php index 864e992..863eb4a 100644 --- a/system/src/Grav/Framework/Form/FormFlash.php +++ b/system/src/Grav/Framework/Form/FormFlash.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Form * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -343,7 +343,7 @@ class FormFlash implements FormFlashInterface // Prepare upload data for later save $data = [ - 'name' => basename($filename), + 'name' => Utils::basename($filename), 'type' => Utils::getMimeByLocalFile($filename), 'size' => filesize($filename), ]; diff --git a/system/src/Grav/Framework/Form/FormFlashFile.php b/system/src/Grav/Framework/Form/FormFlashFile.php index dc510e2..65af544 100644 --- a/system/src/Grav/Framework/Form/FormFlashFile.php +++ b/system/src/Grav/Framework/Form/FormFlashFile.php @@ -3,14 +3,17 @@ /** * @package Grav\Framework\Form * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Framework\Form; +use Grav\Common\Security; +use Grav\Common\Utils; use Grav\Framework\Psr7\Stream; use InvalidArgumentException; +use JsonSerializable; use Psr\Http\Message\StreamInterface; use Psr\Http\Message\UploadedFileInterface; use RuntimeException; @@ -23,7 +26,7 @@ use function sprintf; * Class FormFlashFile * @package Grav\Framework\Form */ -class FormFlashFile implements UploadedFileInterface, \JsonSerializable +class FormFlashFile implements UploadedFileInterface, JsonSerializable { /** @var string */ private $field; @@ -175,11 +178,27 @@ class FormFlashFile implements UploadedFileInterface, \JsonSerializable /** * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->upload; } + /** + * @return void + */ + public function checkXss(): void + { + $tmpFile = $this->getTmpFile(); + $mime = $this->getClientMediaType(); + if (Utils::contains($mime, 'svg', false)) { + $response = Security::detectXssFromSvgFile($tmpFile); + if ($response) { + throw new RuntimeException(sprintf('SVG file XSS check failed on %s', $response)); + } + } + } + /** * @return string|null */ @@ -199,6 +218,7 @@ class FormFlashFile implements UploadedFileInterface, \JsonSerializable /** * @return array */ + #[\ReturnTypeWillChange] public function __debugInfo() { return [ diff --git a/system/src/Grav/Framework/Form/Interfaces/FormFactoryInterface.php b/system/src/Grav/Framework/Form/Interfaces/FormFactoryInterface.php index d21d4aa..6a85f66 100644 --- a/system/src/Grav/Framework/Form/Interfaces/FormFactoryInterface.php +++ b/system/src/Grav/Framework/Form/Interfaces/FormFactoryInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Form * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Form/Interfaces/FormFlashInterface.php b/system/src/Grav/Framework/Form/Interfaces/FormFlashInterface.php index d51bd8d..44bee02 100644 --- a/system/src/Grav/Framework/Form/Interfaces/FormFlashInterface.php +++ b/system/src/Grav/Framework/Form/Interfaces/FormFlashInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Form * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Form/Interfaces/FormInterface.php b/system/src/Grav/Framework/Form/Interfaces/FormInterface.php index 9815646..0edfc42 100644 --- a/system/src/Grav/Framework/Form/Interfaces/FormInterface.php +++ b/system/src/Grav/Framework/Form/Interfaces/FormInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Form * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Form/Traits/FormTrait.php b/system/src/Grav/Framework/Form/Traits/FormTrait.php index d77a402..710d8b0 100644 --- a/system/src/Grav/Framework/Form/Traits/FormTrait.php +++ b/system/src/Grav/Framework/Form/Traits/FormTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Form * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -23,6 +23,7 @@ use Grav\Common\User\Interfaces\UserInterface; use Grav\Common\Utils; use Grav\Framework\Compat\Serializable; use Grav\Framework\ContentBlock\HtmlBlock; +use Grav\Framework\Form\FormFlashFile; use Grav\Framework\Form\Interfaces\FormFlashInterface; use Grav\Framework\Form\Interfaces\FormInterface; use Grav\Framework\Session\SessionInterface; @@ -65,10 +66,10 @@ trait FormTrait private $sessionid; /** @var bool */ private $submitted; - /** @var ArrayAccess|Data|null */ + /** @var ArrayAccess|Data|null */ private $data; - /** @var array|UploadedFileInterface[] */ - private $files; + /** @var UploadedFileInterface[] */ + private $files = []; /** @var FormFlashInterface|null */ private $flash; /** @var string */ @@ -203,7 +204,7 @@ trait FormTrait */ public function getFiles(): array { - return $this->files ?? []; + return $this->files; } /** @@ -221,8 +222,8 @@ trait FormTrait */ public function getDefaultValue(string $name) { - $path = explode('.', $name) ?: []; - $offset = array_shift($path) ?? ''; + $path = explode('.', $name); + $offset = array_shift($path); $current = $this->getDefaultValues(); @@ -692,7 +693,7 @@ trait FormTrait throw new RuntimeException(sprintf('FlexForm: Bad HTTP method %s', $method)); } - $body = $request->getParsedBody(); + $body = (array)$request->getParsedBody(); $data = isset($body['data']) ? $this->decodeData($body['data']) : null; $flash = $this->getFlash(); @@ -721,6 +722,7 @@ trait FormTrait * @param ArrayAccess|Data|null $data * @return void * @throws ValidationException + * @phpstan-param ArrayAccess|Data|null $data * @throws Exception */ protected function validateData($data = null): void @@ -735,6 +737,7 @@ trait FormTrait * * @param ArrayAccess|Data|null $data * @return void + * @phpstan-param ArrayAccess|Data|null $data */ protected function filterData($data = null): void { @@ -773,13 +776,16 @@ trait FormTrait { // Handle bad filenames. $filename = $file->getClientFilename(); - if ($filename && !Utils::checkFilename($filename)) { $grav = Grav::instance(); throw new RuntimeException( sprintf($grav['language']->translate('PLUGIN_FORM.FILEUPLOAD_UNABLE_TO_UPLOAD', null, true), $filename, 'Bad filename') ); } + + if ($file instanceof FormFlashFile) { + $file->checkXss(); + } } /** @@ -797,9 +803,7 @@ trait FormTrait // Decode JSON encoded fields and merge them to data. if (isset($data['_json'])) { $data = array_replace_recursive($data, $this->jsonDecode($data['_json'])); - if (null === $data) { - throw new RuntimeException(__METHOD__ . '(): Unexpected error'); - } + unset($data['_json']); } diff --git a/system/src/Grav/Framework/Interfaces/RenderInterface.php b/system/src/Grav/Framework/Interfaces/RenderInterface.php index 7a7d9d3..5bc6e58 100644 --- a/system/src/Grav/Framework/Interfaces/RenderInterface.php +++ b/system/src/Grav/Framework/Interfaces/RenderInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Interfaces * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Logger/Processors/UserProcessor.php b/system/src/Grav/Framework/Logger/Processors/UserProcessor.php index 885b4f0..f0ebef1 100644 --- a/system/src/Grav/Framework/Logger/Processors/UserProcessor.php +++ b/system/src/Grav/Framework/Logger/Processors/UserProcessor.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Logger * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Media/Interfaces/MediaCollectionInterface.php b/system/src/Grav/Framework/Media/Interfaces/MediaCollectionInterface.php index a3587d8..2bac98f 100644 --- a/system/src/Grav/Framework/Media/Interfaces/MediaCollectionInterface.php +++ b/system/src/Grav/Framework/Media/Interfaces/MediaCollectionInterface.php @@ -3,15 +3,21 @@ /** * @package Grav\Framework\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Framework\Media\Interfaces; +use ArrayAccess; +use Countable; +use Iterator; + /** * Class implements media collection interface. + * @extends ArrayAccess + * @extends Iterator */ -interface MediaCollectionInterface extends \ArrayAccess, \Countable, \Iterator +interface MediaCollectionInterface extends ArrayAccess, Countable, Iterator { } diff --git a/system/src/Grav/Framework/Media/Interfaces/MediaInterface.php b/system/src/Grav/Framework/Media/Interfaces/MediaInterface.php index 2c5a4b3..8688ad1 100644 --- a/system/src/Grav/Framework/Media/Interfaces/MediaInterface.php +++ b/system/src/Grav/Framework/Media/Interfaces/MediaInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Media/Interfaces/MediaManipulationInterface.php b/system/src/Grav/Framework/Media/Interfaces/MediaManipulationInterface.php index fef475f..bca9a22 100644 --- a/system/src/Grav/Framework/Media/Interfaces/MediaManipulationInterface.php +++ b/system/src/Grav/Framework/Media/Interfaces/MediaManipulationInterface.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Media/Interfaces/MediaObjectInterface.php b/system/src/Grav/Framework/Media/Interfaces/MediaObjectInterface.php index dc7f148..f4409c5 100644 --- a/system/src/Grav/Framework/Media/Interfaces/MediaObjectInterface.php +++ b/system/src/Grav/Framework/Media/Interfaces/MediaObjectInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Media * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Mime/MimeTypes.php b/system/src/Grav/Framework/Mime/MimeTypes.php index dadcddf..e3a5ea8 100644 --- a/system/src/Grav/Framework/Mime/MimeTypes.php +++ b/system/src/Grav/Framework/Mime/MimeTypes.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Mime * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Object/Access/ArrayAccessTrait.php b/system/src/Grav/Framework/Object/Access/ArrayAccessTrait.php index affff03..4b67599 100644 --- a/system/src/Grav/Framework/Object/Access/ArrayAccessTrait.php +++ b/system/src/Grav/Framework/Object/Access/ArrayAccessTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Object/Access/NestedArrayAccessTrait.php b/system/src/Grav/Framework/Object/Access/NestedArrayAccessTrait.php index 8365875..d9acb10 100644 --- a/system/src/Grav/Framework/Object/Access/NestedArrayAccessTrait.php +++ b/system/src/Grav/Framework/Object/Access/NestedArrayAccessTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Object/Access/NestedPropertyCollectionTrait.php b/system/src/Grav/Framework/Object/Access/NestedPropertyCollectionTrait.php index 120c1a4..561b6fe 100644 --- a/system/src/Grav/Framework/Object/Access/NestedPropertyCollectionTrait.php +++ b/system/src/Grav/Framework/Object/Access/NestedPropertyCollectionTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php b/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php index 7409f4c..64107e0 100644 --- a/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Access/NestedPropertyTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -42,8 +42,8 @@ trait NestedPropertyTrait public function getNestedProperty($property, $default = null, $separator = null) { $separator = $separator ?: '.'; - $path = explode($separator, $property) ?: []; - $offset = array_shift($path) ?? ''; + $path = explode($separator, $property); + $offset = array_shift($path); if (!$this->hasProperty($offset)) { return $default; @@ -85,8 +85,8 @@ trait NestedPropertyTrait public function setNestedProperty($property, $value, $separator = null) { $separator = $separator ?: '.'; - $path = explode($separator, $property) ?: []; - $offset = array_shift($path) ?? ''; + $path = explode($separator, $property); + $offset = array_shift($path); if (!$path) { $this->setProperty($offset, $value); @@ -127,8 +127,8 @@ trait NestedPropertyTrait public function unsetNestedProperty($property, $separator = null) { $separator = $separator ?: '.'; - $path = explode($separator, $property) ?: []; - $offset = array_shift($path) ?? ''; + $path = explode($separator, $property); + $offset = array_shift($path); if (!$path) { $this->unsetProperty($offset); diff --git a/system/src/Grav/Framework/Object/Access/OverloadedPropertyTrait.php b/system/src/Grav/Framework/Object/Access/OverloadedPropertyTrait.php index 0f0f89f..f417fba 100644 --- a/system/src/Grav/Framework/Object/Access/OverloadedPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Access/OverloadedPropertyTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -21,6 +21,7 @@ trait OverloadedPropertyTrait * @param mixed $offset An offset to check for. * @return bool Returns TRUE on success or FALSE on failure. */ + #[\ReturnTypeWillChange] public function __isset($offset) { return $this->hasProperty($offset); @@ -32,6 +33,7 @@ trait OverloadedPropertyTrait * @param mixed $offset The offset to retrieve. * @return mixed Can return all value types. */ + #[\ReturnTypeWillChange] public function __get($offset) { return $this->getProperty($offset); @@ -44,6 +46,7 @@ trait OverloadedPropertyTrait * @param mixed $value The value to set. * @return void */ + #[\ReturnTypeWillChange] public function __set($offset, $value) { $this->setProperty($offset, $value); @@ -55,6 +58,7 @@ trait OverloadedPropertyTrait * @param mixed $offset The name value to unset * @return void */ + #[\ReturnTypeWillChange] public function __unset($offset) { $this->unsetProperty($offset); diff --git a/system/src/Grav/Framework/Object/ArrayObject.php b/system/src/Grav/Framework/Object/ArrayObject.php index 2bbe937..a38864c 100644 --- a/system/src/Grav/Framework/Object/ArrayObject.php +++ b/system/src/Grav/Framework/Object/ArrayObject.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -19,6 +19,7 @@ use Grav\Framework\Object\Property\ArrayPropertyTrait; /** * Array Objects keep the data in private array property. + * @implements ArrayAccess */ class ArrayObject implements NestedObjectInterface, ArrayAccess { diff --git a/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php b/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php index 3c172fe..e29370a 100644 --- a/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php +++ b/system/src/Grav/Framework/Object/Base/ObjectCollectionTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -11,6 +11,7 @@ namespace Grav\Framework\Object\Base; use Grav\Framework\Compat\Serializable; use Grav\Framework\Object\Interfaces\ObjectInterface; +use InvalidArgumentException; use function call_user_func_array; use function get_class; use function is_callable; @@ -19,6 +20,9 @@ use function is_object; /** * ObjectCollection Trait * @package Grav\Framework\Object + * + * @template TKey as array-key + * @template T as ObjectInterface */ trait ObjectCollectionTrait { @@ -51,6 +55,7 @@ trait ObjectCollectionTrait } $class = get_class($this); + return $type . strtolower(substr($class, strrpos($class, '\\') + 1)); } @@ -167,7 +172,7 @@ trait ObjectCollectionTrait protected function doUnserialize(array $data) { if (!isset($data['key'], $data['type'], $data['elements']) || $data['type'] !== $this->getType()) { - throw new \InvalidArgumentException("Cannot unserialize '{$this->getType()}': Bad data"); + throw new InvalidArgumentException("Cannot unserialize '{$this->getType()}': Bad data"); } $this->setKey($data['key']); @@ -179,6 +184,7 @@ trait ObjectCollectionTrait * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->doSerialize(); @@ -189,6 +195,7 @@ trait ObjectCollectionTrait * * @return string */ + #[\ReturnTypeWillChange] public function __toString() { return $this->getKey(); @@ -207,14 +214,18 @@ trait ObjectCollectionTrait /** * Create a copy from this collection by cloning all objects in the collection. + * + * @return static */ public function copy() { $list = []; foreach ($this->getIterator() as $key => $value) { + /** @phpstan-ignore-next-line */ $list[$key] = is_object($value) ? clone $value : $value; } + /** @phpstan-var static */ return $this->createFrom($list); } @@ -330,6 +341,7 @@ trait ObjectCollectionTrait * * @param string $property * @return array + * @phpstan-return array */ public function group($property) { @@ -348,12 +360,13 @@ trait ObjectCollectionTrait * * @param string $property * @return static[] + * @phpstan-return array> */ public function collectionGroup($property) { $collections = []; foreach ($this->group($property) as $id => $elements) { - /** @var static $collection */ + /** @phpstan-var static $collection */ $collection = $this->createFrom($elements); $collections[$id] = $collection; diff --git a/system/src/Grav/Framework/Object/Base/ObjectTrait.php b/system/src/Grav/Framework/Object/Base/ObjectTrait.php index d4e324b..86df8c7 100644 --- a/system/src/Grav/Framework/Object/Base/ObjectTrait.php +++ b/system/src/Grav/Framework/Object/Base/ObjectTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -172,6 +172,7 @@ trait ObjectTrait * * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->doSerialize(); @@ -182,6 +183,7 @@ trait ObjectTrait * * @return string */ + #[\ReturnTypeWillChange] public function __toString() { return $this->getKey(); diff --git a/system/src/Grav/Framework/Object/Collection/ObjectExpressionVisitor.php b/system/src/Grav/Framework/Object/Collection/ObjectExpressionVisitor.php index d8f1524..e8b12b7 100644 --- a/system/src/Grav/Framework/Object/Collection/ObjectExpressionVisitor.php +++ b/system/src/Grav/Framework/Object/Collection/ObjectExpressionVisitor.php @@ -3,12 +3,13 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Framework\Object\Collection; +use ArrayAccess; use Closure; use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor; use Doctrine\Common\Collections\Expr\Comparison; @@ -42,7 +43,7 @@ class ObjectExpressionVisitor extends ClosureExpressionVisitor $field = rtrim($field, ')'); } - if (isset($object[$field])) { + if ($object instanceof ArrayAccess && isset($object[$field])) { $value = $object[$field]; } else { $accessors = array('', 'get', 'is'); @@ -233,7 +234,7 @@ class ObjectExpressionVisitor extends ClosureExpressionVisitor }; default: - throw new RuntimeException("Unknown comparison operator: " . $comparison->getOperator()); + throw new RuntimeException('Unknown comparison operator: ' . $comparison->getOperator()); } } } diff --git a/system/src/Grav/Framework/Object/Interfaces/NestedObjectCollectionInterface.php b/system/src/Grav/Framework/Object/Interfaces/NestedObjectCollectionInterface.php index a2431be..9f00bab 100644 --- a/system/src/Grav/Framework/Object/Interfaces/NestedObjectCollectionInterface.php +++ b/system/src/Grav/Framework/Object/Interfaces/NestedObjectCollectionInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Object/Interfaces/NestedObjectInterface.php b/system/src/Grav/Framework/Object/Interfaces/NestedObjectInterface.php index 4d7a880..c144d8e 100644 --- a/system/src/Grav/Framework/Object/Interfaces/NestedObjectInterface.php +++ b/system/src/Grav/Framework/Object/Interfaces/NestedObjectInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Object/Interfaces/ObjectCollectionInterface.php b/system/src/Grav/Framework/Object/Interfaces/ObjectCollectionInterface.php index 8169c24..bd25f61 100644 --- a/system/src/Grav/Framework/Object/Interfaces/ObjectCollectionInterface.php +++ b/system/src/Grav/Framework/Object/Interfaces/ObjectCollectionInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Object/Interfaces/ObjectInterface.php b/system/src/Grav/Framework/Object/Interfaces/ObjectInterface.php index e8ec2c1..bc4d45d 100644 --- a/system/src/Grav/Framework/Object/Interfaces/ObjectInterface.php +++ b/system/src/Grav/Framework/Object/Interfaces/ObjectInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Object/LazyObject.php b/system/src/Grav/Framework/Object/LazyObject.php index 309c0d6..6be2558 100644 --- a/system/src/Grav/Framework/Object/LazyObject.php +++ b/system/src/Grav/Framework/Object/LazyObject.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -22,6 +22,7 @@ use Grav\Framework\Object\Property\LazyPropertyTrait; * not exist or is not initialized. * * @package Grav\Framework\Object + * @implements ArrayAccess */ class LazyObject implements NestedObjectInterface, ArrayAccess { diff --git a/system/src/Grav/Framework/Object/ObjectCollection.php b/system/src/Grav/Framework/Object/ObjectCollection.php index 3fdebce..94392af 100644 --- a/system/src/Grav/Framework/Object/ObjectCollection.php +++ b/system/src/Grav/Framework/Object/ObjectCollection.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -22,12 +22,13 @@ use function array_slice; * Class contains a collection of objects. * * @template TKey of array-key - * @template T + * @template T of \Grav\Framework\Object\Interfaces\ObjectInterface * @extends ArrayCollection * @implements NestedObjectCollectionInterface */ class ObjectCollection extends ArrayCollection implements NestedObjectCollectionInterface { + /** @phpstan-use ObjectCollectionTrait */ use ObjectCollectionTrait; use NestedPropertyCollectionTrait { NestedPropertyCollectionTrait::group insteadof ObjectCollectionTrait; @@ -65,6 +66,7 @@ class ObjectCollection extends ArrayCollection implements NestedObjectCollection */ public function limit($start, $limit = null) { + /** @phpstan-var static */ return $this->createFrom($this->slice($start, $limit)); } @@ -86,14 +88,11 @@ class ObjectCollection extends ArrayCollection implements NestedObjectCollection if ($orderings = $criteria->getOrderings()) { $next = null; - /** - * @var string $field - * @var string $ordering - */ foreach (array_reverse($orderings) as $field => $ordering) { $next = ObjectExpressionVisitor::sortByField($field, $ordering === Criteria::DESC ? -1 : 1, $next); } + /** @phpstan-ignore-next-line */ if ($next) { uasort($filtered, $next); } @@ -106,11 +105,13 @@ class ObjectCollection extends ArrayCollection implements NestedObjectCollection $filtered = array_slice($filtered, (int)$offset, $length); } + /** @phpstan-var static */ return $this->createFrom($filtered); } /** * @return array + * @phpstan-return array */ protected function getElements() { @@ -120,9 +121,11 @@ class ObjectCollection extends ArrayCollection implements NestedObjectCollection /** * @param array $elements * @return array + * @phpstan-return array */ protected function setElements(array $elements) { + /** @phpstan-var array $elements */ return $elements; } } diff --git a/system/src/Grav/Framework/Object/ObjectIndex.php b/system/src/Grav/Framework/Object/ObjectIndex.php index 50ac427..ab495bd 100644 --- a/system/src/Grav/Framework/Object/ObjectIndex.php +++ b/system/src/Grav/Framework/Object/ObjectIndex.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -25,7 +25,7 @@ use function is_object; * * @template TKey of array-key * @template T of \Grav\Framework\Object\Interfaces\ObjectInterface - * @template C of \Grav\Framework\Collection\CollectionInterface + * @template C of ObjectCollectionInterface * @extends AbstractIndexCollection * @implements NestedObjectCollectionInterface */ @@ -35,7 +35,7 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje protected static $type; /** @var string */ - private $_key; + protected $_key; /** * @param bool $prefix @@ -95,6 +95,7 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje * @param string $property Object property to be updated. * @param string $value New value. * @return ObjectCollectionInterface + * @phpstan-return C */ public function setProperty($property, $value) { @@ -105,6 +106,7 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje * @param string $property Object property to be defined. * @param mixed $default Default value. * @return ObjectCollectionInterface + * @phpstan-return C */ public function defProperty($property, $default) { @@ -114,6 +116,7 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje /** * @param string $property Object property to be unset. * @return ObjectCollectionInterface + * @phpstan-return C */ public function unsetProperty($property) { @@ -146,6 +149,7 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje * @param mixed $value New value. * @param string|null $separator Separator, defaults to '.' * @return ObjectCollectionInterface + * @phpstan-return C */ public function setNestedProperty($property, $value, $separator = null) { @@ -157,6 +161,7 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje * @param mixed $default Default value. * @param string|null $separator Separator, defaults to '.' * @return ObjectCollectionInterface + * @phpstan-return C */ public function defNestedProperty($property, $default, $separator = null) { @@ -167,6 +172,7 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje * @param string $property Object property to be unset. * @param string|null $separator Separator, defaults to '.' * @return ObjectCollectionInterface + * @phpstan-return C */ public function unsetNestedProperty($property, $separator = null) { @@ -183,9 +189,11 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje { $list = []; foreach ($this->getIterator() as $key => $value) { + /** @phpstan-ignore-next-line */ $list[$key] = is_object($value) ? clone $value : $value; } + /** @phpstan-var static */ return $this->createFrom($list); } @@ -200,6 +208,7 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje /** * @param array $ordering * @return ObjectCollectionInterface + * @phpstan-return C */ public function orderBy(array $ordering) { @@ -232,6 +241,7 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje * * @param string $property * @return ObjectCollectionInterface[] + * @phpstan-return C[] */ public function collectionGroup($property) { @@ -239,14 +249,18 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje } /** - * {@inheritDoc} + * @param Criteria $criteria + * @return ObjectCollectionInterface + * @phpstan-return C */ public function matching(Criteria $criteria) { - /** @var ObjectCollectionInterface $collection */ $collection = $this->loadCollection($this->getEntries()); - return $collection->matching($criteria); + /** @phpstan-var C $matching */ + $matching = $collection->matching($criteria); + + return $matching; } /** @@ -254,6 +268,7 @@ abstract class ObjectIndex extends AbstractIndexCollection implements NestedObje * @param array $arguments * @return mixed */ + #[\ReturnTypeWillChange] abstract public function __call($name, $arguments); /** diff --git a/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php b/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php index fa3fed1..8ab4c41 100644 --- a/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Property/ArrayPropertyTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -97,7 +97,7 @@ trait ArrayPropertyTrait */ protected function getElements() { - return array_filter($this->_elements, function ($val) { + return array_filter($this->_elements, static function ($val) { return $val !== null; }); } diff --git a/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php b/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php index d5baddb..e689259 100644 --- a/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Property/LazyPropertyTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -87,8 +87,7 @@ trait LazyPropertyTrait */ protected function doUnsetProperty($property) { - $this->hasObjectProperty($property) ? - $this->unsetObjectProperty($property) : $this->unsetArrayProperty($property); + $this->hasObjectProperty($property) ? $this->unsetObjectProperty($property) : $this->unsetArrayProperty($property); } /** diff --git a/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php b/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php index 584e812..1b57aab 100644 --- a/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Property/MixedPropertyTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php b/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php index 435220a..bb0195d 100644 --- a/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php +++ b/system/src/Grav/Framework/Object/Property/ObjectPropertyTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Object/PropertyObject.php b/system/src/Grav/Framework/Object/PropertyObject.php index dbeb5c4..d9cdde8 100644 --- a/system/src/Grav/Framework/Object/PropertyObject.php +++ b/system/src/Grav/Framework/Object/PropertyObject.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Object * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -19,6 +19,8 @@ use Grav\Framework\Object\Property\ObjectPropertyTrait; /** * Property Objects keep their data in protected object properties. + * + * @implements ArrayAccess */ class PropertyObject implements NestedObjectInterface, ArrayAccess { diff --git a/system/src/Grav/Framework/Pagination/AbstractPagination.php b/system/src/Grav/Framework/Pagination/AbstractPagination.php index 0be21ec..a4d902a 100644 --- a/system/src/Grav/Framework/Pagination/AbstractPagination.php +++ b/system/src/Grav/Framework/Pagination/AbstractPagination.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Pagination * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -234,7 +234,9 @@ class AbstractPagination implements PaginationInterface /** * @return ArrayIterator + * @phpstan-return ArrayIterator */ + #[\ReturnTypeWillChange] public function getIterator() { $this->loadItems(); diff --git a/system/src/Grav/Framework/Pagination/AbstractPaginationPage.php b/system/src/Grav/Framework/Pagination/AbstractPaginationPage.php index 95ff8af..072fea7 100644 --- a/system/src/Grav/Framework/Pagination/AbstractPaginationPage.php +++ b/system/src/Grav/Framework/Pagination/AbstractPaginationPage.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Pagination * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -41,7 +41,7 @@ abstract class AbstractPaginationPage implements PaginationPageInterface */ public function getOptions(): array { - return $this->options ?? []; + return $this->options; } /** diff --git a/system/src/Grav/Framework/Pagination/Interfaces/PaginationInterface.php b/system/src/Grav/Framework/Pagination/Interfaces/PaginationInterface.php index 56d3361..1a82147 100644 --- a/system/src/Grav/Framework/Pagination/Interfaces/PaginationInterface.php +++ b/system/src/Grav/Framework/Pagination/Interfaces/PaginationInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Pagination * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -16,6 +16,7 @@ use IteratorAggregate; /** * Interface PaginationInterface * @package Grav\Framework\Pagination\Interfaces + * @extends IteratorAggregate */ interface PaginationInterface extends Countable, IteratorAggregate { diff --git a/system/src/Grav/Framework/Pagination/Interfaces/PaginationPageInterface.php b/system/src/Grav/Framework/Pagination/Interfaces/PaginationPageInterface.php index b90594d..26c0692 100644 --- a/system/src/Grav/Framework/Pagination/Interfaces/PaginationPageInterface.php +++ b/system/src/Grav/Framework/Pagination/Interfaces/PaginationPageInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Pagination * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Pagination/Pagination.php b/system/src/Grav/Framework/Pagination/Pagination.php index e602872..8f2fa20 100644 --- a/system/src/Grav/Framework/Pagination/Pagination.php +++ b/system/src/Grav/Framework/Pagination/Pagination.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Pagination * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Pagination/PaginationPage.php b/system/src/Grav/Framework/Pagination/PaginationPage.php index 63ceb5f..e64abe9 100644 --- a/system/src/Grav/Framework/Pagination/PaginationPage.php +++ b/system/src/Grav/Framework/Pagination/PaginationPage.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Pagination * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Psr7/AbstractUri.php b/system/src/Grav/Framework/Psr7/AbstractUri.php index 85d802f..145437a 100644 --- a/system/src/Grav/Framework/Psr7/AbstractUri.php +++ b/system/src/Grav/Framework/Psr7/AbstractUri.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -263,6 +263,7 @@ abstract class AbstractUri implements UriInterface /** * @return string */ + #[\ReturnTypeWillChange] public function __toString() { return $this->getUrl(); diff --git a/system/src/Grav/Framework/Psr7/Request.php b/system/src/Grav/Framework/Psr7/Request.php index cd65fd9..795a1a4 100644 --- a/system/src/Grav/Framework/Psr7/Request.php +++ b/system/src/Grav/Framework/Psr7/Request.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Psr7/Response.php b/system/src/Grav/Framework/Psr7/Response.php index 6cb67e0..6189c4a 100644 --- a/system/src/Grav/Framework/Psr7/Response.php +++ b/system/src/Grav/Framework/Psr7/Response.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -53,6 +53,7 @@ class Response implements ResponseInterface * @param int $options Json encoding options * @param int $depth Json encoding max depth * @return static + * @phpstan-param positive-int $depth */ public function withJson($data, int $status = null, int $options = 0, int $depth = 512): ResponseInterface { @@ -257,7 +258,7 @@ class Response implements ResponseInterface } $output .= self::EOL; - $output .= (string) $response->getBody(); + $output .= $response->getBody(); return $output; } diff --git a/system/src/Grav/Framework/Psr7/ServerRequest.php b/system/src/Grav/Framework/Psr7/ServerRequest.php index 4084834..cb5bcbb 100644 --- a/system/src/Grav/Framework/Psr7/ServerRequest.php +++ b/system/src/Grav/Framework/Psr7/ServerRequest.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -98,13 +98,8 @@ class ServerRequest implements ServerRequestInterface public function getCookieParam($key, $default = null) { $cookies = $this->getRequest()->getCookieParams(); - $result = $default; - if (isset($cookies[$key])) { - $result = $cookies[$key]; - } - - return $result; + return $cookies[$key] ?? $default; } /** @@ -238,13 +233,8 @@ class ServerRequest implements ServerRequestInterface public function getQueryParam($key, $default = null) { $getParams = $this->getQueryParams(); - $result = $default; - if (isset($getParams[$key])) { - $result = $getParams[$key]; - } - - return $result; + return $getParams[$key] ?? $default; } /** diff --git a/system/src/Grav/Framework/Psr7/Stream.php b/system/src/Grav/Framework/Psr7/Stream.php index a5a1043..6546bdc 100644 --- a/system/src/Grav/Framework/Psr7/Stream.php +++ b/system/src/Grav/Framework/Psr7/Stream.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Psr7/Traits/MessageDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/MessageDecoratorTrait.php index 39e3818..c09a03c 100644 --- a/system/src/Grav/Framework/Psr7/Traits/MessageDecoratorTrait.php +++ b/system/src/Grav/Framework/Psr7/Traits/MessageDecoratorTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Psr7/Traits/RequestDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/RequestDecoratorTrait.php index 13f4c6f..49f2a92 100644 --- a/system/src/Grav/Framework/Psr7/Traits/RequestDecoratorTrait.php +++ b/system/src/Grav/Framework/Psr7/Traits/RequestDecoratorTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Psr7/Traits/ResponseDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/ResponseDecoratorTrait.php index 7b62c3c..4bbc736 100644 --- a/system/src/Grav/Framework/Psr7/Traits/ResponseDecoratorTrait.php +++ b/system/src/Grav/Framework/Psr7/Traits/ResponseDecoratorTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Psr7/Traits/ServerRequestDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/ServerRequestDecoratorTrait.php index 33c26e0..9222219 100644 --- a/system/src/Grav/Framework/Psr7/Traits/ServerRequestDecoratorTrait.php +++ b/system/src/Grav/Framework/Psr7/Traits/ServerRequestDecoratorTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Psr7/Traits/StreamDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/StreamDecoratorTrait.php index db1e746..448323f 100644 --- a/system/src/Grav/Framework/Psr7/Traits/StreamDecoratorTrait.php +++ b/system/src/Grav/Framework/Psr7/Traits/StreamDecoratorTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -33,6 +33,7 @@ trait StreamDecoratorTrait /** * @return void */ + #[\ReturnTypeWillChange] public function __destruct() { $this->stream->close(); diff --git a/system/src/Grav/Framework/Psr7/Traits/UploadedFileDecoratorTrait.php b/system/src/Grav/Framework/Psr7/Traits/UploadedFileDecoratorTrait.php index e0c65bd..eec3add 100644 --- a/system/src/Grav/Framework/Psr7/Traits/UploadedFileDecoratorTrait.php +++ b/system/src/Grav/Framework/Psr7/Traits/UploadedFileDecoratorTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Psr7/Traits/UriDecorationTrait.php b/system/src/Grav/Framework/Psr7/Traits/UriDecorationTrait.php index 607d757..73adb64 100644 --- a/system/src/Grav/Framework/Psr7/Traits/UriDecorationTrait.php +++ b/system/src/Grav/Framework/Psr7/Traits/UriDecorationTrait.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Psr7/UploadedFile.php b/system/src/Grav/Framework/Psr7/UploadedFile.php index bfa63cd..c3ed62e 100644 --- a/system/src/Grav/Framework/Psr7/UploadedFile.php +++ b/system/src/Grav/Framework/Psr7/UploadedFile.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Psr7/Uri.php b/system/src/Grav/Framework/Psr7/Uri.php index c920b33..63fe04e 100644 --- a/system/src/Grav/Framework/Psr7/Uri.php +++ b/system/src/Grav/Framework/Psr7/Uri.php @@ -5,7 +5,7 @@ declare(strict_types=1); /** * @package Grav\Framework\Psr7 * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -24,9 +24,6 @@ class Uri implements UriInterface { use UriDecorationTrait; - /** @var array Array of Uri query. */ - private $queryParams; - public function __construct(string $uri = '') { $this->uri = new \Nyholm\Psr7\Uri($uri); diff --git a/system/src/Grav/Framework/RequestHandler/Exception/InvalidArgumentException.php b/system/src/Grav/Framework/RequestHandler/Exception/InvalidArgumentException.php index 451e586..2456ea1 100644 --- a/system/src/Grav/Framework/RequestHandler/Exception/InvalidArgumentException.php +++ b/system/src/Grav/Framework/RequestHandler/Exception/InvalidArgumentException.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\RequestHandler * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/RequestHandler/Exception/NotFoundException.php b/system/src/Grav/Framework/RequestHandler/Exception/NotFoundException.php index 28a226a..ce79ab2 100644 --- a/system/src/Grav/Framework/RequestHandler/Exception/NotFoundException.php +++ b/system/src/Grav/Framework/RequestHandler/Exception/NotFoundException.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\RequestHandler * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -21,9 +21,6 @@ use function in_array; */ class NotFoundException extends RequestException { - /** @var ServerRequestInterface */ - private $request; - /** * NotFoundException constructor. * @param ServerRequestInterface $request @@ -37,9 +34,4 @@ class NotFoundException extends RequestException parent::__construct($request, 'Not Found', 404, $previous); } } - - public function getRequest(): ServerRequestInterface - { - return $this->request; - } } diff --git a/system/src/Grav/Framework/RequestHandler/Exception/NotHandledException.php b/system/src/Grav/Framework/RequestHandler/Exception/NotHandledException.php index 1b18473..7b4a0e7 100644 --- a/system/src/Grav/Framework/RequestHandler/Exception/NotHandledException.php +++ b/system/src/Grav/Framework/RequestHandler/Exception/NotHandledException.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\RequestHandler * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/RequestHandler/Exception/PageExpiredException.php b/system/src/Grav/Framework/RequestHandler/Exception/PageExpiredException.php index 747c0ca..f752167 100644 --- a/system/src/Grav/Framework/RequestHandler/Exception/PageExpiredException.php +++ b/system/src/Grav/Framework/RequestHandler/Exception/PageExpiredException.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\RequestHandler * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/RequestHandler/Exception/RequestException.php b/system/src/Grav/Framework/RequestHandler/Exception/RequestException.php index 6079964..678b267 100644 --- a/system/src/Grav/Framework/RequestHandler/Exception/RequestException.php +++ b/system/src/Grav/Framework/RequestHandler/Exception/RequestException.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\RequestHandler * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/RequestHandler/Middlewares/Exceptions.php b/system/src/Grav/Framework/RequestHandler/Middlewares/Exceptions.php index 9eadf72..36ef3a5 100644 --- a/system/src/Grav/Framework/RequestHandler/Middlewares/Exceptions.php +++ b/system/src/Grav/Framework/RequestHandler/Middlewares/Exceptions.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\RequestHandler * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/RequestHandler/RequestHandler.php b/system/src/Grav/Framework/RequestHandler/RequestHandler.php index 5b03805..2ce2427 100644 --- a/system/src/Grav/Framework/RequestHandler/RequestHandler.php +++ b/system/src/Grav/Framework/RequestHandler/RequestHandler.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\RequestHandler * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -12,9 +12,11 @@ declare(strict_types=1); namespace Grav\Framework\RequestHandler; use Grav\Framework\RequestHandler\Traits\RequestHandlerTrait; +use Pimple\Container; use Psr\Container\ContainerInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use function assert; /** * Class RequestHandler @@ -47,7 +49,11 @@ class RequestHandler implements RequestHandlerInterface */ public function addCallable(string $name, callable $callable): self { - $this->container[$name] = $callable; + if (null !== $this->container) { + assert($this->container instanceof Container); + $this->container[$name] = $callable; + } + array_unshift($this->middleware, $name); return $this; @@ -62,7 +68,11 @@ class RequestHandler implements RequestHandlerInterface */ public function addMiddleware(string $name, MiddlewareInterface $middleware): self { - $this->container[$name] = $middleware; + if (null !== $this->container) { + assert($this->container instanceof Container); + $this->container[$name] = $middleware; + } + array_unshift($this->middleware, $name); return $this; diff --git a/system/src/Grav/Framework/RequestHandler/Traits/RequestHandlerTrait.php b/system/src/Grav/Framework/RequestHandler/Traits/RequestHandlerTrait.php index 1b5a79e..ff82889 100644 --- a/system/src/Grav/Framework/RequestHandler/Traits/RequestHandlerTrait.php +++ b/system/src/Grav/Framework/RequestHandler/Traits/RequestHandlerTrait.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\RequestHandler * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Route/Route.php b/system/src/Grav/Framework/Route/Route.php index f9a7fa7..d4d9078 100644 --- a/system/src/Grav/Framework/Route/Route.php +++ b/system/src/Grav/Framework/Route/Route.php @@ -3,12 +3,13 @@ /** * @package Grav\Framework\Route * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Framework\Route; +use Grav\Framework\Uri\Uri; use Grav\Framework\Uri\UriFactory; use InvalidArgumentException; use function array_slice; @@ -318,7 +319,7 @@ class Route } /** - * @return \Grav\Framework\Uri\Uri + * @return Uri */ public function getUri() { @@ -344,6 +345,7 @@ class Route * @return string * @deprecated 1.6 Use ->toString(true) or ->getUri() instead. */ + #[\ReturnTypeWillChange] public function __toString() { user_error(__CLASS__ . '::' . __FUNCTION__ . '() will change in the future to return route, not relative url: use ->toString(true) or ->getUri() instead.', E_USER_DEPRECATED); diff --git a/system/src/Grav/Framework/Route/RouteFactory.php b/system/src/Grav/Framework/Route/RouteFactory.php index 68baf55..fa1a76c 100644 --- a/system/src/Grav/Framework/Route/RouteFactory.php +++ b/system/src/Grav/Framework/Route/RouteFactory.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Route * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Session/Exceptions/SessionException.php b/system/src/Grav/Framework/Session/Exceptions/SessionException.php index 5ad948b..a07e87d 100644 --- a/system/src/Grav/Framework/Session/Exceptions/SessionException.php +++ b/system/src/Grav/Framework/Session/Exceptions/SessionException.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Session * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Session/Messages.php b/system/src/Grav/Framework/Session/Messages.php index 5d854a2..37c62a9 100644 --- a/system/src/Grav/Framework/Session/Messages.php +++ b/system/src/Grav/Framework/Session/Messages.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Session * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Session/Session.php b/system/src/Grav/Framework/Session/Session.php index 3feae5a..108563e 100644 --- a/system/src/Grav/Framework/Session/Session.php +++ b/system/src/Grav/Framework/Session/Session.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Session * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -189,7 +189,11 @@ class Session implements SessionInterface return $this; } - $sessionName = session_name(); + $sessionName = $this->getName(); + if (null === $sessionName) { + return $this; + } + $sessionExists = isset($_COOKIE[$sessionName]); // Protection against invalid session cookie names throwing exception: http://php.net/manual/en/function.session-id.php#116836 @@ -341,7 +345,7 @@ class Session implements SessionInterface $this->removeCookie(); setcookie( - session_name(), + $name, '', $this->getCookieOptions(-42000) ); @@ -392,6 +396,7 @@ class Session implements SessionInterface /** * @inheritdoc */ + #[\ReturnTypeWillChange] public function getIterator() { return new ArrayIterator($_SESSION); @@ -408,6 +413,7 @@ class Session implements SessionInterface /** * @inheritdoc */ + #[\ReturnTypeWillChange] public function __isset($name) { return isset($_SESSION[$name]); @@ -416,6 +422,7 @@ class Session implements SessionInterface /** * @inheritdoc */ + #[\ReturnTypeWillChange] public function __get($name) { return $_SESSION[$name] ?? null; @@ -424,6 +431,7 @@ class Session implements SessionInterface /** * @inheritdoc */ + #[\ReturnTypeWillChange] public function __set($name, $value) { $_SESSION[$name] = $value; @@ -432,6 +440,7 @@ class Session implements SessionInterface /** * @inheritdoc */ + #[\ReturnTypeWillChange] public function __unset($name) { unset($_SESSION[$name]); @@ -478,9 +487,15 @@ class Session implements SessionInterface { $this->removeCookie(); + $sessionName = $this->getName(); + $sessionId = $this->getId(); + if (null === $sessionName || null === $sessionId) { + return; + } + setcookie( - session_name(), - session_id(), + $sessionName, + $sessionId, $this->getCookieOptions() ); } diff --git a/system/src/Grav/Framework/Session/SessionInterface.php b/system/src/Grav/Framework/Session/SessionInterface.php index 43ca40f..fa2873d 100644 --- a/system/src/Grav/Framework/Session/SessionInterface.php +++ b/system/src/Grav/Framework/Session/SessionInterface.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Session * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -16,6 +16,7 @@ use RuntimeException; /** * Class Session * @package Grav\Framework\Session + * @extends IteratorAggregate */ interface SessionInterface extends IteratorAggregate { @@ -107,7 +108,9 @@ interface SessionInterface extends IteratorAggregate * Retrieve an external iterator * * @return ArrayIterator Return an ArrayIterator of $_SESSION + * @phpstan-return ArrayIterator */ + #[\ReturnTypeWillChange] public function getIterator(); /** @@ -123,6 +126,7 @@ interface SessionInterface extends IteratorAggregate * @param string $name * @return bool */ + #[\ReturnTypeWillChange] public function __isset($name); /** @@ -131,6 +135,7 @@ interface SessionInterface extends IteratorAggregate * @param string $name * @return mixed */ + #[\ReturnTypeWillChange] public function __get($name); /** @@ -140,6 +145,7 @@ interface SessionInterface extends IteratorAggregate * @param mixed $value * @return void */ + #[\ReturnTypeWillChange] public function __set($name, $value); /** @@ -148,5 +154,6 @@ interface SessionInterface extends IteratorAggregate * @param string $name * @return void */ + #[\ReturnTypeWillChange] public function __unset($name); } diff --git a/system/src/Grav/Framework/Uri/Uri.php b/system/src/Grav/Framework/Uri/Uri.php index c43496e..6355a1f 100644 --- a/system/src/Grav/Framework/Uri/Uri.php +++ b/system/src/Grav/Framework/Uri/Uri.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Uri * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Framework/Uri/UriFactory.php b/system/src/Grav/Framework/Uri/UriFactory.php index f7724b7..ebfec03 100644 --- a/system/src/Grav/Framework/Uri/UriFactory.php +++ b/system/src/Grav/Framework/Uri/UriFactory.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Uri * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -125,7 +125,7 @@ class UriFactory $encodedUrl = preg_replace_callback( '%[^:/@?&=#]+%u', - function ($matches) { + static function ($matches) { return rawurlencode($matches[0]); }, $url diff --git a/system/src/Grav/Framework/Uri/UriPartsFilter.php b/system/src/Grav/Framework/Uri/UriPartsFilter.php index 71a5135..260711b 100644 --- a/system/src/Grav/Framework/Uri/UriPartsFilter.php +++ b/system/src/Grav/Framework/Uri/UriPartsFilter.php @@ -3,7 +3,7 @@ /** * @package Grav\Framework\Uri * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Installer/Install.php b/system/src/Grav/Installer/Install.php index 4df9dcd..0f23e89 100644 --- a/system/src/Grav/Installer/Install.php +++ b/system/src/Grav/Installer/Install.php @@ -3,7 +3,7 @@ /** * @package Grav\Installer * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ @@ -36,9 +36,11 @@ final class Install 'php' => [ 'name' => 'PHP', 'versions' => [ - '7.4' => '7.4.0', + '8.1' => '8.1.0', + '8.0' => '8.0.0', + '7.4' => '7.4.1', '7.3' => '7.3.6', - '' => '7.4.12' + '' => '8.0.13' ] ], 'grav' => [ @@ -114,7 +116,7 @@ final class Install /** @var string|null */ private $location; - /** @var VersionUpdater */ + /** @var VersionUpdater|null */ private $updater; /** @var static */ @@ -151,6 +153,7 @@ final class Install * @param string|null $zip * @return void */ + #[\ReturnTypeWillChange] public function __invoke(?string $zip) { $this->zip = $zip; @@ -249,6 +252,11 @@ ERR; } try { + if (null === $this->updater) { + $versions = Versions::instance(USER_DIR . 'config/versions.yaml'); + $this->updater = new VersionUpdater('core/grav', __DIR__ . '/updates', $this->getVersion(), $versions); + } + // Update user/config/version.yaml before copying the files to avoid frontend from setting the version schema. $this->updater->install(); @@ -279,7 +287,7 @@ ERR; public function finalize(): void { // Finalize can be run without installing Grav first. - if (!$this->updater) { + if (null === $this->updater) { $versions = Versions::instance(USER_DIR . 'config/versions.yaml'); $this->updater = new VersionUpdater('core/grav', __DIR__ . '/updates', GRAV_VERSION, $versions); $this->updater->install(); diff --git a/system/src/Grav/Installer/InstallException.php b/system/src/Grav/Installer/InstallException.php index 145b7c9..cdd5b7a 100644 --- a/system/src/Grav/Installer/InstallException.php +++ b/system/src/Grav/Installer/InstallException.php @@ -3,7 +3,7 @@ /** * @package Grav\Installer * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Installer/VersionUpdate.php b/system/src/Grav/Installer/VersionUpdate.php index faaf2a2..1fde783 100644 --- a/system/src/Grav/Installer/VersionUpdate.php +++ b/system/src/Grav/Installer/VersionUpdate.php @@ -3,6 +3,7 @@ namespace Grav\Installer; use Closure; +use Grav\Common\Utils; /** * Class VersionUpdate @@ -50,7 +51,7 @@ final class VersionUpdate public function getPatch(): string { - return $this->date; + return $this->patch; } public function getUpdater(): VersionUpdater diff --git a/system/src/Grav/Installer/Versions.php b/system/src/Grav/Installer/Versions.php index 03f3b0b..92a64ce 100644 --- a/system/src/Grav/Installer/Versions.php +++ b/system/src/Grav/Installer/Versions.php @@ -3,7 +3,7 @@ /** * @package Grav\Installer * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ diff --git a/system/src/Grav/Installer/YamlUpdater.php b/system/src/Grav/Installer/YamlUpdater.php index 9af2055..fe1c7f1 100644 --- a/system/src/Grav/Installer/YamlUpdater.php +++ b/system/src/Grav/Installer/YamlUpdater.php @@ -3,12 +3,13 @@ /** * @package Grav\Installer * - * @copyright Copyright (c) 2015 - 2021 Trilby Media, LLC. All rights reserved. + * @copyright Copyright (c) 2015 - 2022 Trilby Media, LLC. All rights reserved. * @license MIT License; see LICENSE file for details. */ namespace Grav\Installer; +use Grav\Common\Utils; use Symfony\Component\Yaml\Yaml; use function assert; use function count; diff --git a/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php b/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php index 8c441bb..1ff7fd4 100644 --- a/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php +++ b/system/src/Twig/DeferredExtension/DeferredNodeVisitorCompat.php @@ -22,16 +22,28 @@ final class DeferredNodeVisitorCompat implements NodeVisitorInterface { private $hasDeferred = false; - public function enterNode(\Twig_NodeInterface $node, Environment $env) : Node + /** + * @param \Twig_NodeInterface $node + * @param Environment $env + * @return Node + */ + public function enterNode(\Twig_NodeInterface $node, Environment $env): Node { if (!$this->hasDeferred && $node instanceof DeferredBlockNode) { $this->hasDeferred = true; } + \assert($node instanceof Node); + return $node; } - public function leaveNode(\Twig_NodeInterface $node, Environment $env) : ?Node + /** + * @param \Twig_NodeInterface $node + * @param Environment $env + * @return Node|null + */ + public function leaveNode(\Twig_NodeInterface $node, Environment $env): ?Node { if ($this->hasDeferred && $node instanceof ModuleNode) { $node->setNode('constructor_end', new Node([new DeferredExtensionNode(), $node->getNode('constructor_end')])); @@ -39,9 +51,14 @@ final class DeferredNodeVisitorCompat implements NodeVisitorInterface $this->hasDeferred = false; } + \assert($node instanceof Node); + return $node; } + /** + * @return int + */ public function getPriority() : int { return 0; diff --git a/user/config/versions.yaml b/user/config/versions.yaml index 9480e4c..092f378 100644 --- a/user/config/versions.yaml +++ b/user/config/versions.yaml @@ -1,8 +1,9 @@ core: grav: - version: 1.7.25 + version: 1.7.31 schema: 1.7.0_2020-11-20_1 history: - { version: 1.7.16, date: '2021-06-10 14:03:35' } - { version: 1.7.21, date: '2021-09-16 12:41:14' } - { version: 1.7.25, date: '2021-12-06 12:22:00' } + - { version: 1.7.31, date: '2022-03-15 08:48:47' } diff --git a/user/pages_offline/05.demande-de-devis/form.fr.md b/user/pages_offline/05.demande-de-devis/form.fr.md new file mode 100644 index 0000000..3849630 --- /dev/null +++ b/user/pages_offline/05.demande-de-devis/form.fr.md @@ -0,0 +1,169 @@ +--- +title: 'Le Campus, au cœur du Val de Drôme, un site tout équipé pour vos événements.' +media_order: vue_ext.jpg +entete: + text: 'Vous souhaitez organiser un événement, une rencontre professionnelle, une formation, un séjour ? Décrivez-nous votre projet en quelques clics, nous sommes à votre écoute !' +metadata: + description: 'Le Campus, au cœur du Val de Drôme, un site tout équipé pour vos événements.' +visible: false +form: + name: ajax-test-form + action: /demande-de-devis + template: form-messages + refresh_prevention: true + fields: + - + name: 'Quelle est la nature de votre évènement ?' + placeholder: 'Choisissez votre évènement ?' + autofocus: 'on' + autocomplete: 'on' + type: radio + label: 'Quelle est la nature de votre évènement ?' + options: + reunion: Réunion + seminaire: Séminaire + convention: Convention + vœux: Vœux + web_conference: 'Web conférence' + salon_forum_exposition: 'Salon, Forum, Exposition' + conference: Conférence + evenement_culturel: 'Evènement culturel' + autre: Autres + size: long + classes: fancy + validate: + required: true + - + name: 'Quelle sera l''envergure de votre évènement ?' + placeholder: 'Nombre de personnes' + autofocus: 'on' + autocomplete: 'on' + type: radio + size: long + classes: fancy + options: + 25: 'Inférieure ou égal à 25 personnes' + 50: 'Inférieure ou égal à 50 personnes' + 100: 'Inférieure ou égal à 100 personnes' + 150: 'Supérieure à 150 personnes' + validate: + required: true + - + name: 'Quand se déroulera votre événement ?' + placeholder: 'jj/mm/yy' + type: text + size: long + classes: fancy + validate: + required: true + + name: 'Date de lévenement' + placeholder: 'Choisissez vos date ?' + autocomplete: 'on' + type: date + label: 'Quand se déroulera votre événement ?' + - + name: 'Durée prévue' + placeholder: 'Choisissez vos date ?' + autofocus: 'on' + autocomplete: 'on' + type: radio + size: long + classes: fancy + options: + 1/2j: 'Une demi journée' + 1j: 'Une journée' + 1s: 'Une soirée' + 2j: 'Deux jours' + 3j: 'Trois jours' + +3j: 'Plus de trois jours' + validate: + required: true + - + name: Prénom + placeholder: Prénom + type: text + size: long + classes: fancy + validate: + required: true + - + name: Nom + placeholder: Nom + type: text + size: long + classes: fancy + validate: + required: true + - + name: 'Adresse mail' + placeholder: 'Adresse mail' + type: email + size: long + classes: fancy + validate: + required: true + - + name: Téléphone + placeholder: Téléphone + type: text + size: long + classes: fancy + validate: + required: true + - + name: Fonction + placeholder: Fonction + type: text + size: long + classes: fancy + validate: + required: true + - + name: Société + placeholder: Société + type: text + size: long + classes: fancy + validate: + required: true + - + name: 'Votre profil' + placeholder: 'quel est votre profil' + autofocus: 'on' + autocomplete: 'on' + type: radio + size: long + classes: fancy + options: + Agence_evenementielle: 'Agence évènementielle' + associations: 'Associations (sociétés savantes, fédérations, syndicats) ' + societes_entreprises: 'Sociétés / Entreprises' + Organismes_professionnels: 'Organismes professionnels' + validate: + required: true + buttons: + - + type: submit + value: Envoyer + process: + - + email: + from: '{{ config.plugins.email.from }}' + to: + - '{{ config.plugins.email.to }}' + - '{{ form.value.email }}' + subject: '[Feedback] {{ form.value.name|e }}' + body: '{% include ''forms/data.html.twig'' %}' + - + save: + fileprefix: feedback- + dateformat: Ymd-His-u + extension: txt + body: '{% include ''forms/data.txt.twig'' %}' + - + message: 'Merci, votre demande de devis à bien été envoyé ! Elle sera traité dans les prochains jours.' +--- + +Location de salles polyvalentes, amphitéâtre de 200 places, matériel performant dans toutes les salles, restauration de qualité bio ou locale sur demande... +**Le Campus et son équipe à taille humaine vous garantit la réussite de votre séjour, de votre séminaire ou de votre événement.** diff --git a/user/pages_offline/05.demande-de-devis/form.md b/user/pages_offline/05.demande-de-devis/form.md new file mode 100644 index 0000000..37dc62a --- /dev/null +++ b/user/pages_offline/05.demande-de-devis/form.md @@ -0,0 +1,169 @@ +--- +title: 'Le Campus, au cœur du Val de Drôme, un site tout équipé pour vos événements.' +media_order: vue_ext.jpg +entete: + text: 'Vous souhaitez organiser un événement, une rencontre professionnelle, une formation, un séjour ? Décrivez-nous votre projet en quelques clics, nous sommes à votre écoute !' +metadata: + description: 'Le Campus, au cœur du Val de Drôme, un site tout équipé pour vos événements.' +visible: false +form: + name: ajax-test-form + action: /demande-de-devis + template: form-messages + refresh_prevention: true + fields: + - + name: 'Quelle est la nature de votre évènement ?' + placeholder: 'Choisissez votre évènement ?' + autofocus: 'on' + autocomplete: 'on' + type: radio + label: 'Quelle est la nature de votre évènement ?' + options: + reunion: Réunion + seminaire: Séminaire + convention: Convention + vœux: Vœux + web_conference: 'Web conférence' + salon_forum_exposition: 'Salon, Forum, Exposition' + conference: Conférence + evenement_culturel: 'Evènement culturel' + autre: Autres + size: long + classes: fancy + validate: + required: true + - + name: 'Quelle sera l''envergure de votre évènement ?' + placeholder: 'Nombre de personnes' + autofocus: 'on' + autocomplete: 'on' + type: radio + size: long + classes: fancy + options: + 25: 'Inférieure ou égal à 25 personnes' + 50: 'Inférieure ou égal à 50 personnes' + 100: 'Inférieure ou égal à 100 personnes' + 150: 'Supérieure à 150 personnes' + validate: + required: true + - + name: 'Quand se déroulera votre événement ?' + placeholder: 'jj/mm/yy' + type: text + size: long + classes: fancy + validate: + required: true + + name: 'Date de lévenement' + placeholder: 'Choisissez vos date ?' + autocomplete: 'on' + type: date + label: 'Quand se déroulera votre événement ?' + - + name: 'Durée prévue' + placeholder: 'Choisissez vos date ?' + autofocus: 'on' + autocomplete: 'on' + type: radio + size: long + classes: fancy + options: + 1/2j: 'Une demi journée' + 1j: 'Une journée' + 1s: 'Une soirée' + 2j: 'Deux jours' + 3j: 'Trois jours' + +3j: 'Plus de trois jours' + validate: + required: true + - + name: Prénom + placeholder: Prénom + type: text + size: long + classes: fancy + validate: + required: true + - + name: Nom + placeholder: Nom + type: text + size: long + classes: fancy + validate: + required: true + - + name: 'Adresse mail' + placeholder: 'Adresse mail' + type: email + size: long + classes: fancy + validate: + required: true + - + name: Téléphone + placeholder: Téléphone + type: text + size: long + classes: fancy + validate: + required: true + - + name: Fonction + placeholder: Fonction + type: text + size: long + classes: fancy + validate: + required: true + - + name: Société + placeholder: Société + type: text + size: long + classes: fancy + validate: + required: true + - + name: 'Votre profil' + placeholder: 'quel est votre profil' + autofocus: 'on' + autocomplete: 'on' + type: radio + size: long + classes: fancy + options: + Agence_evenementielle: 'Agence évènementielle' + associations: 'Associations (sociétés savantes, fédérations, syndicats) ' + societes_entreprises: 'Sociétés / Entreprises' + Organismes_professionnels: 'Organismes professionnels' + validate: + required: true + buttons: + - + type: submit + value: Envoyer + process: + - + email: + from: '{{ config.plugins.email.from }}' + to: + - '{{ config.plugins.email.to }}' + - '{{ form.value.email }}' + subject: '[Feedback] {{ form.value.name|e }}' + body: '{% include ''forms/data.html.twig'' %}' + - + save: + fileprefix: feedback- + dateformat: Ymd-His-u + extension: txt + body: '{% include 'forms/data.txt.twig' %}' + - + message: Merci, votre demande de devis à bien été envoyé ! Elle sera traité dans les prochains jours. +--- + +Location de salles polyvalentes, amphitéâtre de 200 places, matériel performant dans toutes les salles, restauration de qualité bio ou locale sur demande... +**Le Campus et son équipe à taille humaine vous garantit la réussite de votre séjour, de votre séminaire ou de votre événement.** diff --git a/user/pages_offline/05.demande-de-devis/vue_ext.jpg b/user/pages_offline/05.demande-de-devis/vue_ext.jpg new file mode 100644 index 0000000000000000000000000000000000000000..413cd8d002f96d0b4e2e12dbda5186c078d80887 GIT binary patch literal 407754 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
    d#E;^19i& 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 z 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 z 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

    svSF{7Ax;WdH5Ng9#mmEpYa`}c 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 T59G>OE279`1x .form-columns{ + width: 100%; + margin: 20px 0; + & > .form-column.w-100{ + & > .form-group{ + width: 100%; + & > .form-data{ + width: 100%; + & > .form-textarea-wrapper { + width: 100%; + textarea{ + width: 100%; + resize: none; + border: none; + } + } + } + } + } + & > .form-column { + padding: 20px 0; + display: flex; + width: 100%; + &:not(:nth-last-child(1)){ + border-bottom: 1px solid $red; + } + & > .form-group{ + width: auto; + .form-data{ + @include inlineflex(); + margin: 0px 0px; + &> div{ + overflow: hidden; + margin: 10px 10px; + min-width: 100px; + border: 2px solid $red; + border-radius: 30px; + padding: 10px 20px; + &.check{ + background: $red; + color: white; + } + input{ + border: none; + } + input[type='radio'] { + visibility: hidden; + position: absolute; + } + label{ + cursor: pointer; + } + } + } + + } + } + } + .button-wrapper{ + background: $red; + height: 100px; + position: absolute; + left: 0; + width: 100%; + button{ + margin-right: 25%; + position: absolute; + right: 0; + top: 50%; + -webkit-transform: translateY(-50%); + transform: translateY(-50%); + background: white; + border-radius: 30px; + padding: 10px 35px; + box-shadow:none; + border:0; + } + } + } + #send-valide{ + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); + background: $red; + border-radius: 20px; + position: fixed; + width: 30%; + min-height: 30%; + left: 50%; + top: 50%; + padding: 50px; + .toast{ + position: relative; + text-align: center; + color: white; + } + .ok{ + color: white; + position: absolute; + right: 20px; + bottom: 20px; + } + } + } +} diff --git a/webserver-configs/htaccess.txt b/webserver-configs/htaccess.txt index 83063ae..098c582 100644 --- a/webserver-configs/htaccess.txt +++ b/webserver-configs/htaccess.txt @@ -59,9 +59,9 @@ RewriteRule .* index.php [L] # Block all direct access for these folders RewriteRule ^(\.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F] # Block access to specific file types for these system folders -RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F] +RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F] # Block access to specific file types for these user folders -RewriteRule ^(user)/(.*)\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F] +RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ error [F] # Block all direct access to .md files: RewriteRule \.md$ error [F] # Block all direct access to files and folders beginning with a dot diff --git a/webserver-configs/lighttpd.conf b/webserver-configs/lighttpd.conf index 512362f..f14c5a8 100644 --- a/webserver-configs/lighttpd.conf +++ b/webserver-configs/lighttpd.conf @@ -33,7 +33,7 @@ $HTTP["url"] =~ "^/grav_path/(LICENSE\.txt|composer\.json|composer\.lock|nginx\. $HTTP["url"] =~ "^/grav_path/(\.git|cache|bin|logs|backup|tests)/(.*)" { url.access-deny = ("") } -$HTTP["url"] =~ "^/grav_path/(system|user|vendor)/(.*)\.(txt|md|html|yaml|yml|php|twig|sh|bat)$" { +$HTTP["url"] =~ "^/grav_path/(system|user|vendor)/(.*)\.(txt|md|html|json|yaml|yml|php|twig|sh|bat)$" { url.access-deny = ("") } $HTTP["url"] =~ "^/grav_path/(\.(.*))" { diff --git a/webserver-configs/nginx.conf b/webserver-configs/nginx.conf index bbca7d3..fc7d06b 100644 --- a/webserver-configs/nginx.conf +++ b/webserver-configs/nginx.conf @@ -20,9 +20,9 @@ server { # deny all direct access for these folders location ~* /(\.git|cache|bin|logs|backup|tests)/.*$ { return 403; } # deny running scripts inside core system folders - location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; } + location ~* /(system|vendor)/.*\.(txt|xml|md|html|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; } # deny running scripts inside user folder - location ~* /user/.*\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; } + location ~* /user/.*\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; } # deny access to specific files in the root folder location ~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) { return 403; } ## End - Security diff --git a/webserver-configs/web.config b/webserver-configs/web.config index 892ce92..1c351a3 100644 --- a/webserver-configs/web.config +++ b/webserver-configs/web.config @@ -18,7 +18,7 @@ - + @@ -26,11 +26,11 @@ - + - +