├── tests
├── Pest
│ └── .gitkeep
├── Unit
│ └── .gitkeep
└── Playwright
│ ├── fixtures
│ ├── frontend
│ │ ├── guest.js
│ │ └── customer.js
│ ├── adminhtml
│ │ └── admin.js
│ └── webapi_rest
│ │ ├── self.js
│ │ └── anonymous.js
│ ├── .gitignore
│ ├── playwright.config.js
│ ├── helpers
│ └── messages.js
│ ├── README.md
│ └── tests
│ └── directives.spec.js
├── src
├── view
│ ├── base
│ │ ├── templates
│ │ │ ├── magewire
│ │ │ │ ├── flakes
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── features
│ │ │ │ │ └── .gitkeep
│ │ │ │ ├── utils
│ │ │ │ │ └── icons
│ │ │ │ │ │ └── loading.phtml
│ │ │ │ └── ui-components
│ │ │ │ │ └── notifier
│ │ │ │ │ └── activity-state.phtml
│ │ │ └── js
│ │ │ │ ├── alpinejs
│ │ │ │ ├── directives
│ │ │ │ │ └── .gitkeep
│ │ │ │ └── magewire.phtml
│ │ │ │ └── magewire
│ │ │ │ ├── state.phtml
│ │ │ │ └── script.phtml
│ │ └── web
│ │ │ └── js
│ │ │ └── manifest.json
│ └── frontend
│ │ ├── templates
│ │ ├── magewire
│ │ │ ├── utils
│ │ │ │ └── .gitkeep
│ │ │ ├── ui-components
│ │ │ │ └── .gitkeep
│ │ │ └── tests
│ │ │ │ └── playwright
│ │ │ │ └── directives
│ │ │ │ ├── area
│ │ │ │ ├── escape.phtml
│ │ │ │ ├── render
│ │ │ │ │ ├── child-child.phtml
│ │ │ │ │ └── child.phtml
│ │ │ │ └── render.phtml
│ │ │ │ ├── scope.phtml
│ │ │ │ └── base.phtml
│ │ └── js
│ │ │ ├── magewire
│ │ │ ├── features
│ │ │ │ └── .gitkeep
│ │ │ └── directives
│ │ │ │ └── .gitkeep
│ │ │ ├── alpinejs
│ │ │ └── directives
│ │ │ │ └── .gitkeep
│ │ │ └── alpinejs.phtml
│ │ ├── tailwind
│ │ └── tailwind.config.js
│ │ └── layout
│ │ └── default.xml
├── etc
│ ├── module.xml
│ ├── adminhtml
│ │ ├── system.xml
│ │ └── system
│ │ │ ├── magewire
│ │ │ ├── features.xml
│ │ │ └── debug.xml
│ │ │ └── magewire.xml
│ ├── frontend
│ │ ├── routes.xml
│ │ └── events.xml
│ ├── cache.xml
│ ├── acl.xml
│ ├── config.xml
│ └── events.xml
├── Model
│ ├── View
│ │ ├── UtilsInterface.php
│ │ ├── Fragment
│ │ │ ├── Style.php
│ │ │ ├── Javascript.php
│ │ │ ├── Exceptions
│ │ │ │ ├── EmptyFragmentException.php
│ │ │ │ └── FragmentValidationException.php
│ │ │ ├── Modifier
│ │ │ │ └── Developer.php
│ │ │ └── Script.php
│ │ ├── Utils
│ │ │ ├── Tailwind.php
│ │ │ ├── Alpine.php
│ │ │ ├── Application.php
│ │ │ ├── Environment.php
│ │ │ ├── Magewire
│ │ │ │ ├── Builder.php
│ │ │ │ └── Features.php
│ │ │ ├── Security.php
│ │ │ ├── Csp.php
│ │ │ └── Fragment.php
│ │ └── FragmentModifier.php
│ ├── Magento
│ │ └── System
│ │ │ └── ConfigMagewireGroup.php
│ ├── Magewire
│ │ └── Notifier
│ │ │ ├── NotificationTypeEnum.php
│ │ │ └── NotificationStateEnum.php
│ └── App
│ │ ├── ExceptionHandler.php
│ │ └── AbstractExceptionHandler.php
├── i18n
│ └── en_US.csv
├── Exceptions
│ ├── AcceptableException.php
│ ├── RequestException.php
│ ├── SilentException.php
│ ├── BuilderException.php
│ └── MagewirePageExpiredBecauseNewDeploymentHasSignificantEnoughChanges.php
├── Magewire
│ └── Playwright
│ │ └── Directives
│ │ ├── Base.php
│ │ ├── Scope.php
│ │ └── Render.php
├── Controller
│ ├── Playwright
│ │ ├── Directives.php
│ │ └── Resolvers.php
│ ├── MagewireUpdateRouteFrontend.php
│ └── Router.php
├── Observer
│ └── ControllerActionPredispatch.php
├── registration.php
└── Setup
│ └── Patch
│ └── Data
│ └── EnableCache.php
├── .release-please-manifest.json
├── themes
├── Hyva
│ ├── view
│ │ └── frontend
│ │ │ ├── tailwind
│ │ │ ├── ui-components
│ │ │ │ └── notifier.css
│ │ │ ├── tailwind-source.css
│ │ │ └── tailwind.config.js
│ │ │ └── templates
│ │ │ └── js
│ │ │ ├── magewire
│ │ │ ├── script.phtml
│ │ │ └── features
│ │ │ │ └── support-magento-flash-messages
│ │ │ │ └── support-magento-flash-messages.phtml
│ │ │ └── disable-alpinejs.phtml
│ ├── etc
│ │ ├── module.xml
│ │ └── frontend
│ │ │ └── events.xml
│ ├── registration.php
│ └── Magewire
│ │ └── Features
│ │ └── SupportMagewireCompiling
│ │ └── View
│ │ ├── Directive
│ │ └── Hyva
│ │ │ ├── Dialog.php
│ │ │ └── SvgHeroIcon.php
│ │ └── Action
│ │ └── Hyva
│ │ └── SvgIconViewAction.php
├── Luma
│ ├── etc
│ │ └── module.xml
│ └── registration.php
├── Backend
│ ├── etc
│ │ └── module.xml
│ └── registration.php
└── Breeze
│ ├── etc
│ └── module.xml
│ └── registration.php
├── .github
├── FUNDING.yml
├── workflows
│ ├── release-please.yml
│ └── portman.yml
└── dependabot.yml
├── package.json
├── portman
└── Livewire
│ ├── Features
│ ├── SupportRedirects
│ │ ├── HandlesRedirects.php
│ │ ├── Redirector.php
│ │ └── SupportRedirects.php
│ ├── SupportStreaming
│ │ └── HandlesStreaming.php
│ ├── SupportEvents
│ │ └── Event.php
│ └── SupportLocales
│ │ └── SupportLocales.php
│ ├── ComponentHook.php
│ ├── Mechanisms
│ └── ComponentRegistry.php
│ ├── Drawer
│ └── BaseUtils.php
│ └── Concerns
│ └── InteractsWithProperties.php
├── CHANGELOG.md
├── .gitignore
├── styles
├── magewire.css
└── ui-component
│ └── notifier.css
├── captainhook.json
├── lib
├── Magewire
│ ├── Containers.php
│ ├── Support
│ │ ├── Str.php
│ │ ├── Contracts
│ │ │ └── DataTransferObjectInterface.php
│ │ ├── Conditions
│ │ │ └── ConditionEnum.php
│ │ ├── DataScope
│ │ │ ├── InvalidDataScopeException.php
│ │ │ └── Compiler.php
│ │ ├── Parser.php
│ │ ├── Random.php
│ │ ├── Concerns
│ │ │ └── WithFactory.php
│ │ └── Parser
│ │ │ └── DomElementParser.php
│ ├── Features
│ │ ├── SupportMagewireRateLimiting
│ │ │ ├── HandlesRateLimiting.php
│ │ │ ├── Exceptions
│ │ │ │ └── TooManyRequestsException.php
│ │ │ ├── RateLimiterCache.php
│ │ │ ├── RateLimiterStorageInterface.php
│ │ │ ├── Config
│ │ │ │ └── Source
│ │ │ │ │ ├── RequestsScope.php
│ │ │ │ │ └── RateLimitingVariant.php
│ │ │ ├── RateLimiterExceptionHandler.php
│ │ │ └── Storage
│ │ │ │ └── RateLimiterCacheStorage.php
│ │ ├── SupportMagewireCompiling
│ │ │ ├── View
│ │ │ │ ├── ViewAction.php
│ │ │ │ ├── Precompiler.php
│ │ │ │ ├── Action
│ │ │ │ │ ├── Magewire.php
│ │ │ │ │ └── Magento
│ │ │ │ │ │ └── Auth.php
│ │ │ │ ├── Directive
│ │ │ │ │ ├── Parser
│ │ │ │ │ │ ├── ConditionExpressionParser.php
│ │ │ │ │ │ ├── IterationClauseExpressionParser.php
│ │ │ │ │ │ └── ExpressionParser.php
│ │ │ │ │ ├── Magento
│ │ │ │ │ │ ├── Escape.php
│ │ │ │ │ │ ├── Block.php
│ │ │ │ │ │ └── Auth.php
│ │ │ │ │ ├── Script.php
│ │ │ │ │ ├── Base.php
│ │ │ │ │ ├── Json.php
│ │ │ │ │ └── Fragment.php
│ │ │ │ ├── ScopeDirectiveChain.php
│ │ │ │ ├── Management
│ │ │ │ │ ├── CompileManager.php
│ │ │ │ │ └── StubsManager.php
│ │ │ │ ├── ScopeDirectiveParser.php
│ │ │ │ ├── ViewStub.php
│ │ │ │ ├── FunctionDirective.php
│ │ │ │ └── ScopeDirective.php
│ │ │ ├── Exception
│ │ │ │ └── DirectiveExpressionParseException.php
│ │ │ ├── HandlesMagewireCompiling.php
│ │ │ └── MagewireUnderscoreViewModel.php
│ │ ├── SupportMagewireViewInstructions
│ │ │ ├── Handler
│ │ │ │ ├── Type
│ │ │ │ │ ├── FormHandler.php
│ │ │ │ │ ├── FormInputHandler.php
│ │ │ │ │ ├── DispatchHandler.php
│ │ │ │ │ ├── DocumentHandler.php
│ │ │ │ │ └── DomNodeHandler.php
│ │ │ │ ├── TypeContext
│ │ │ │ │ ├── HandlerTypeListeners.php
│ │ │ │ │ ├── HandlerTypeMetaData.php
│ │ │ │ │ ├── HandlerTypeTargets.php
│ │ │ │ │ └── HandlerTypeInteractions.php
│ │ │ │ └── HandlerTypeContext.php
│ │ │ ├── ViewInstructionDoesNotExistException.php
│ │ │ ├── Concern
│ │ │ │ ├── WithNaming.php
│ │ │ │ └── WithStacking.php
│ │ │ ├── HandlesMagewireViewInstructions.php
│ │ │ ├── Instructions
│ │ │ │ ├── Action.php
│ │ │ │ ├── Magento
│ │ │ │ │ └── FlashMessage.php
│ │ │ │ └── Notification.php
│ │ │ └── ViewInstructionFactory.php
│ │ ├── SupportMagentoLayouts
│ │ │ └── SupportMagentoLayouts.php
│ │ ├── SupportMagewireNotifications
│ │ │ ├── SupportMagewireNotifications.php
│ │ │ └── MagewireNotificationsFacade.php
│ │ ├── SupportMagentoFlashMessages
│ │ │ ├── FlashMessageType.php
│ │ │ ├── FlashMessage.php
│ │ │ └── SupportMagentoFlashMessages.php
│ │ ├── SupportMagewireFlakes
│ │ │ └── View
│ │ │ │ ├── Fragment
│ │ │ │ └── FlakeFragment.php
│ │ │ │ └── Directive
│ │ │ │ └── FlakeDirective.php
│ │ ├── SupportMagewireLoaders
│ │ │ ├── HandlesMagewireLoaders.php
│ │ │ └── SupportMagewireLoaders.php
│ │ ├── SupportMagewireViewModel
│ │ │ ├── HandlesMagewireViewModel.php
│ │ │ └── MagewireViewModel.php
│ │ ├── SupportMagewireExceptionHandling
│ │ │ └── SupportMagewireExceptionHandling.php
│ │ └── SupportMagentoObserverEvents
│ │ │ └── DTO
│ │ │ └── ListenerDataTransferObject.php
│ ├── Mechanisms
│ │ ├── ResolveComponents
│ │ │ ├── ComponentArguments
│ │ │ │ ├── BlockMagewireArguments.php
│ │ │ │ └── LayoutBlockArguments.php
│ │ │ ├── ComponentResolverNotFoundException.php
│ │ │ ├── ResolversCache.php
│ │ │ └── ResolveComponentsViewModel.php
│ │ ├── HandleComponents
│ │ │ ├── DynamicPropertyProviderInterface.php
│ │ │ ├── ComponentContext
│ │ │ │ ├── Memo.php
│ │ │ │ └── Effects.php
│ │ │ └── CorruptComponentPayloadException.php
│ │ ├── HandleRequests
│ │ │ ├── ComponentContext
│ │ │ │ └── EffectsInterface.php
│ │ │ └── HandleRequestFacade.php
│ │ └── FrontendAssets
│ │ │ ├── FrontendAssetsFacade.php
│ │ │ └── FrontendAssetsViewModel.php
│ ├── Exceptions
│ │ ├── ComponentNotFoundException.php
│ │ └── RootTagMissingFromViewException.php
│ ├── Mechanisms.php
│ ├── Containers
│ │ ├── Livewire.php
│ │ └── Redirect.php
│ ├── Features.php
│ └── Concerns
│ │ └── WithTagging.php
├── MagewireBc
│ ├── Exception
│ │ ├── ValidationException.php
│ │ ├── AcceptableException.php
│ │ └── MagewireException.php
│ ├── Features
│ │ └── SupportMagewireBackwardsCompatibility
│ │ │ ├── HandlesFormComponentBackwardsCompatibility.php
│ │ │ ├── SupportMagewireBackwardsCompatibility.php
│ │ │ └── HandlesComponentBackwardsCompatibility.php
│ └── Model
│ │ ├── Concern
│ │ └── BrowserEvent.php
│ │ └── HydratorInterface.php
├── Symfony
│ └── Component
│ │ └── Console
│ │ └── Command
│ │ └── MagewireCommand.php
└── Magento
│ ├── Framework
│ ├── Reflection
│ │ └── TypeProcessor.php
│ └── View
│ │ └── BlockRenderingRegistry.php
│ └── App
│ └── Cache
│ ├── Type
│ └── Magewire.php
│ └── MagewireCacheSection.php
├── release-please-config.json
├── dist
├── Exceptions
│ ├── BypassViewHandler.php
│ ├── ComponentNotFoundException.php
│ ├── NonPublicComponentMethodCall.php
│ ├── MethodNotFoundException.php
│ ├── PropertyNotFoundException.php
│ ├── MissingRulesException.php
│ ├── ComponentAttributeMissingOnDynamicComponentException.php
│ └── PublicPropertyNotFoundException.php
├── Features
│ ├── SupportAttributes
│ │ ├── AttributeLevel.php
│ │ └── HandlesAttributes.php
│ ├── SupportValidation
│ │ └── BaseRule.php
│ ├── SupportLockedProperties
│ │ ├── CannotUpdateLockedPropertyException.php
│ │ └── BaseLocked.php
│ ├── SupportFormObjects
│ │ └── HandlesFormObjects.php
│ ├── SupportStreaming
│ │ └── HandlesStreaming.php
│ ├── SupportEvents
│ │ ├── HandlesEvents.php
│ │ ├── BaseOn.php
│ │ └── Event.php
│ ├── SupportLifecycleHooks
│ │ └── DirectlyCallingLifecycleHooksNotAllowedException.php
│ ├── SupportRedirects
│ │ ├── HandlesRedirects.php
│ │ └── Redirector.php
│ └── SupportLocales
│ │ └── SupportLocales.php
├── Attributes
│ ├── Locked.php
│ └── On.php
├── Mechanisms
│ ├── Mechanism.php
│ └── HandleComponents
│ │ └── Synthesizers
│ │ ├── IntSynth.php
│ │ ├── FloatSynth.php
│ │ ├── StdClassSynth.php
│ │ └── EnumSynth.php
├── Transparency.php
└── Pipe.php
├── SECURITY.md
├── rector.php
└── LICENSE.md
/tests/Pest/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/Unit/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/Playwright/fixtures/frontend/guest.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/view/base/templates/magewire/flakes/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/Playwright/fixtures/adminhtml/admin.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/Playwright/fixtures/webapi_rest/self.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/view/base/templates/magewire/features/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/view/frontend/templates/magewire/utils/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/Playwright/fixtures/webapi_rest/anonymous.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/view/base/templates/js/alpinejs/directives/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/view/frontend/templates/js/magewire/features/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.release-please-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | ".": "3.0.0-beta1"
3 | }
--------------------------------------------------------------------------------
/src/view/frontend/templates/js/alpinejs/directives/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/view/frontend/templates/js/magewire/directives/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/view/frontend/templates/magewire/ui-components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/themes/Hyva/view/frontend/tailwind/ui-components/notifier.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/view/base/web/js/manifest.json:
--------------------------------------------------------------------------------
1 |
2 | {"/magewire.js":"df3a17f2"}
3 |
--------------------------------------------------------------------------------
/tests/Playwright/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | test-results/
3 | .env
4 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: wpoortman
4 |
--------------------------------------------------------------------------------
/src/view/frontend/templates/magewire/tests/playwright/directives/area/escape.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/themes/Hyva/view/frontend/tailwind/tailwind-source.css:
--------------------------------------------------------------------------------
1 | @import url(ui-components/notifier.css);
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@tailwindcss/cli": "^4.1.8",
4 | "tailwindcss": "^4.1.8"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/portman/Livewire/Features/SupportRedirects/HandlesRedirects.php:
--------------------------------------------------------------------------------
1 |
2 | Child's Child
3 |
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## [3.0.0-beta1](https://github.com/magewirephp/magewire/compare/main...v3.0.0-beta1) (2025-06-02)
4 |
5 |
--------------------------------------------------------------------------------
/src/view/frontend/templates/magewire/tests/playwright/directives/area/render.phtml:
--------------------------------------------------------------------------------
1 |
2 | Parent
3 |
4 | @renderChild(alias: 'child')
5 |
6 |
--------------------------------------------------------------------------------
/src/view/frontend/templates/magewire/tests/playwright/directives/area/render/child.phtml:
--------------------------------------------------------------------------------
1 |
2 | Child
3 |
4 | @renderChild(alias: 'child-child')
5 |
6 |
--------------------------------------------------------------------------------
/themes/Hyva/view/frontend/tailwind/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | content: [
3 | '../../../../themes/Hyva/view/frontend/templates/**/*.phtml'
4 | ]
5 | };
6 |
--------------------------------------------------------------------------------
/portman/Livewire/Features/SupportRedirects/Redirector.php:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/etc/adminhtml/system.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/styles/magewire.css:
--------------------------------------------------------------------------------
1 | /* Minimal Tailwind CSS layers */
2 | @import "tailwindcss" layer(utilities);
3 |
4 | /* UI Components */
5 | @import "./ui-component/notifier.css";
6 |
7 | /* Purge Sources */
8 | @source "../src/view/base/templates/**/*.{phtml,js}";
9 | @source "../src/view/frontend/templates/**/*.{phtml,js}";
10 |
--------------------------------------------------------------------------------
/src/view/frontend/tailwind/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | content: [
3 | '../../../../src/view/base/layout/**/*.xml',
4 | '../../../../src/view/base/templates/**/*.phtml',
5 | '../../../../src/view/frontend/layout/**/*.xml',
6 | '../../../../src/view/frontend/templates/**/*.phtml',
7 | ]
8 | };
9 |
--------------------------------------------------------------------------------
/captainhook.json:
--------------------------------------------------------------------------------
1 | {
2 | "commit-msg": {
3 | "enabled": true,
4 | "actions": [
5 | {
6 | "action": "\\Ramsey\\CaptainHook\\ValidateConventionalCommit"
7 | }
8 | ]
9 | },
10 | "pre-commit": {
11 | "enabled": true,
12 | "actions": [
13 | {
14 | "action": "vendor/bin/portman build"
15 | }
16 | ]
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/lib/Magewire/Containers.php:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/etc/cache.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | Magewire cache
8 |
9 |
10 |
--------------------------------------------------------------------------------
/themes/Luma/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/lib/MagewireBc/Exception/ValidationException.php:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/themes/Breeze/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/release-please-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "packages": {
3 | ".": {
4 | "changelog-path": "CHANGELOG.md",
5 | "bump-minor-pre-major": true,
6 | "release-type": "php",
7 | "bump-patch-for-minor-pre-major": false,
8 | "draft": false,
9 | "prerelease": true
10 | }
11 | },
12 | "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
13 | }
14 |
--------------------------------------------------------------------------------
/src/Exceptions/AcceptableException.php:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/ViewAction.php:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewInstructions/Handler/Type/FormHandler.php:
--------------------------------------------------------------------------------
1 | stream($to, $content, $replace);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireRateLimiting/Exceptions/TooManyRequestsException.php:
--------------------------------------------------------------------------------
1 |
13 |
18 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireNotifications/SupportMagewireNotifications.php:
--------------------------------------------------------------------------------
1 | instance(static::class, $this);
17 | }
18 | function boot()
19 | {
20 | //
21 | }
22 | }
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireRateLimiting/RateLimiterCache.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireNotifications/MagewireNotificationsFacade.php:
--------------------------------------------------------------------------------
1 | items as $accessor => $mechanism) {
20 | $this->items[$accessor]['type']->boot();
21 | }
22 |
23 | return $this;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/etc/adminhtml/system/magewire/features.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/etc/frontend/events.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/dist/Exceptions/NonPublicComponentMethodCall.php:
--------------------------------------------------------------------------------
1 | config;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Directive/Parser/ConditionExpressionParser.php:
--------------------------------------------------------------------------------
1 | $expression];
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireLoaders/HandlesMagewireLoaders.php:
--------------------------------------------------------------------------------
1 | loader;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Controller/Playwright/Directives.php:
--------------------------------------------------------------------------------
1 | $expression];
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/ScopeDirectiveChain.php:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/dist/Exceptions/ComponentAttributeMissingOnDynamicComponentException.php:
--------------------------------------------------------------------------------
1 | property . ']');
17 | }
18 | }
--------------------------------------------------------------------------------
/lib/MagewireBc/Model/Concern/BrowserEvent.php:
--------------------------------------------------------------------------------
1 | dispatchQueue;
20 | }
21 |
22 | public function dispatchBrowserEvent($event, $data = null): void
23 | {
24 | $this->dispatchQueue[] = compact('event', 'data');
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 | 0
10 |
11 |
12 | 0
13 | 4
14 | 5
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/dist/Exceptions/PublicPropertyNotFoundException.php:
--------------------------------------------------------------------------------
1 | getName());
19 | }
20 | }
--------------------------------------------------------------------------------
/lib/Magewire/Exceptions/RootTagMissingFromViewException.php:
--------------------------------------------------------------------------------
1 | component;
18 | }
19 |
20 | public function callMagewireConstruct(...$params): void
21 | {
22 | if (method_exists($this, 'magewireConstruct')) {
23 | $this->magewireConstruct(...$params);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | If you discover a security issue, please bring it to our attention right away!
4 |
5 | ## Reporting a Vulnerability
6 |
7 | Please **DO NOT** file a public issue to report a security vulberability, instead send your report privately to `magewirephp@wpoortman.nl`. This will help ensure that any vulnerabilities that are found can be [disclosed responsibly](https://en.wikipedia.org/wiki/Responsible_disclosure) to any affected parties.
8 |
9 | ## Supported Versions
10 |
11 | Project versions that are currently being supported with security updates vary per project.
12 | Please see specific project repositories for details.
13 | If nothing is specified, only the latest major versions are supported.
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Management/CompileManager.php:
--------------------------------------------------------------------------------
1 | directiveManager;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/lib/Magewire/Support/Concerns/WithFactory.php:
--------------------------------------------------------------------------------
1 | create(static::class, $arguments);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/themes/Hyva/Magewire/Features/SupportMagewireCompiling/View/Directive/Hyva/Dialog.php:
--------------------------------------------------------------------------------
1 | name = $name;
20 |
21 | return $this;
22 | }
23 |
24 | public function getName(): ?string
25 | {
26 | return $this->name;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/dist/Features/SupportFormObjects/HandlesFormObjects.php:
--------------------------------------------------------------------------------
1 | all() as $key => $value) {
18 | if ($value instanceof Form) {
19 | $forms[] = $value;
20 | }
21 | }
22 | return $forms;
23 | }
24 | }
--------------------------------------------------------------------------------
/themes/Hyva/view/frontend/templates/js/magewire/script.phtml:
--------------------------------------------------------------------------------
1 | getData('view_model');
14 | $magewireUtility = $magewireViewModel->utils()->magewire();
15 | ?>
16 |
21 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/ScopeDirectiveParser.php:
--------------------------------------------------------------------------------
1 | viewInstructions ??= ObjectManager::getInstance()->create(ViewInstructions::class);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Model/Magewire/Notifier/NotificationTypeEnum.php:
--------------------------------------------------------------------------------
1 | value;
23 | }
24 |
25 | public function getCssClass(): string
26 | {
27 | return 'notification-' . $this->value;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/etc/adminhtml/system/magewire.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
12 |
13 | advanced
14 | Magewirephp_Magewire::magewire
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/themes/Hyva/view/frontend/templates/js/magewire/features/support-magento-flash-messages/support-magento-flash-messages.phtml:
--------------------------------------------------------------------------------
1 | getData('view_model');
12 | $magewireFragment = $magewireViewModel->utils()->fragment();
13 | ?>
14 | make()->script()->start() ?>
15 |
20 | end() ?>
21 |
--------------------------------------------------------------------------------
/lib/Magewire/Mechanisms/HandleComponents/ComponentContext/Memo.php:
--------------------------------------------------------------------------------
1 | viewModel ??= ObjectManager::getInstance()->get(MagewireViewModel::class);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/dist/Features/SupportStreaming/HandlesStreaming.php:
--------------------------------------------------------------------------------
1 | stream($to, $content, $replace);
20 | }
21 | }
--------------------------------------------------------------------------------
/src/view/frontend/templates/magewire/tests/playwright/directives/scope.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Scope
4 |
5 |
6 |
7 |
8 |
9 | | Key |
10 | Value |
11 |
12 |
13 |
14 |
15 | @foreach(['a', 'b', 'c'] as $key => $value)
16 |
17 | | = $key ?> |
18 | = $value ?> |
19 |
20 | @endforeach
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/Exceptions/MagewirePageExpiredBecauseNewDeploymentHasSignificantEnoughChanges.php:
--------------------------------------------------------------------------------
1 | {
8 | await page.goto('/customer/account/login');
9 |
10 | await page.fill('#email', process.env.ACCOUNT_EMAIL);
11 | await page.fill('#pass', process.env.ACCOUNT_PASSWORD);
12 |
13 | const button = page.locator('button[type="submit"]', { hasText: 'Sign In' });
14 | await button.click();
15 |
16 | await page.waitForURL('/customer/account/');
17 |
18 | await use(page);
19 | }
20 | });
21 |
22 | export { test };
23 |
--------------------------------------------------------------------------------
/dist/Features/SupportEvents/HandlesEvents.php:
--------------------------------------------------------------------------------
1 | listeners;
19 | }
20 | public function dispatch($event, ...$params)
21 | {
22 | $event = new Event($event, $params);
23 | store($this)->push('dispatched', $event);
24 | return $event;
25 | }
26 | }
--------------------------------------------------------------------------------
/dist/Features/SupportLifecycleHooks/DirectlyCallingLifecycleHooksNotAllowedException.php:
--------------------------------------------------------------------------------
1 | handler()->data()->push('listeners', fn () => ['options' => $options], $event);
20 |
21 | return $this;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/styles/ui-component/notifier.css:
--------------------------------------------------------------------------------
1 | .magewire-notifier {
2 | @apply space-y-2 z-50 w-full fixed bottom-4 left-6 md:max-w-xs ml-2 mb-2 flex flex-col;
3 | }
4 |
5 | .magewire-notifier__notification {
6 | @apply pointer-events-auto relative w-full py-2 px-5 max-w-sm rounded-lg drop-shadow-md bg-white border-l-6 border-l-gray-600;
7 | }
8 |
9 | .magewire-notifier__notification-content {
10 | @apply flex items-center justify-between;
11 | }
12 |
13 | .magewire-notifier__notification-before {
14 | @apply flex items-center space-x-3;
15 | }
16 |
17 | .magewire-notifier__notification-text {
18 |
19 | }
20 |
21 | .magewire-notifier__notification-title {
22 |
23 | }
24 |
25 | .magewire-notifier__notification-message {
26 |
27 | }
28 |
29 | .magewire-notifier__notification-after {
30 | @apply flex items-center space-x-3;
31 | }
32 |
--------------------------------------------------------------------------------
/lib/Magewire/Containers/Livewire.php:
--------------------------------------------------------------------------------
1 | message);
27 | }
28 |
29 | function getType(): FlashMessageType
30 | {
31 | return $this->type;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/HandlesMagewireCompiling.php:
--------------------------------------------------------------------------------
1 | compiler = $compiler;
24 | }
25 |
26 | return $this->compiler;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/Magewire/Mechanisms/ResolveComponents/ResolveComponentsViewModel.php:
--------------------------------------------------------------------------------
1 | renderLifecycleManager->getLifecycle()) > 0;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Management/StubsManager.php:
--------------------------------------------------------------------------------
1 | collector->collect();
26 |
27 | return $stubs[$namespace] ?? null;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireExceptionHandling/SupportMagewireExceptionHandling.php:
--------------------------------------------------------------------------------
1 | self::ISOLATED, 'label' => 'Isolated'],
24 | ['value' => self::SHARED, 'label' => 'Shared']
25 | ];
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/Observer/ControllerActionPredispatch.php:
--------------------------------------------------------------------------------
1 | magewireServiceProvider->setup();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/etc/adminhtml/system/magewire/debug.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
12 |
13 |
14 |
21 |
22 | Magento\Config\Model\Config\Source\Yesno
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/portman/Livewire/Features/SupportEvents/Event.php:
--------------------------------------------------------------------------------
1 | $this->name, 'params' => $this->params];
20 |
21 | if ($this->self) {
22 | $output['self'] = true;
23 | }
24 | if ($this->component) {
25 | $output['to'] = app(ComponentRegistry::class)->getName($this->component);
26 | }
27 |
28 | return $output;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewModel/MagewireViewModel.php:
--------------------------------------------------------------------------------
1 | utils->$name($arguments) : $this->utils;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/rector.php:
--------------------------------------------------------------------------------
1 | withPaths([
11 | realpath('dist'),
12 | ])
13 | ->withRules([
14 | ClassPropertyAssignToConstructorPromotionRector::class,
15 | ArraySpreadInsteadOfArrayMergeRector::class
16 | ])
17 | ->withPhpSets(
18 | php82: true
19 | )
20 | ->withPreparedSets(
21 | deadCode: true,
22 | codeQuality: true,
23 | codingStyle: true,
24 | typeDeclarations: true,
25 | )
26 | ->withNoDiffs()
27 | //->withTypeCoverageLevel(Level::PHP_82)
28 | ->withImportNames(
29 | removeUnusedImports: true
30 | );
31 |
--------------------------------------------------------------------------------
/lib/Magewire/Mechanisms/HandleComponents/CorruptComponentPayloadException.php:
--------------------------------------------------------------------------------
1 | setData('application_state', $this->state);
27 |
28 | return $block;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/themes/Hyva/Magewire/Features/SupportMagewireCompiling/View/Action/Hyva/SvgIconViewAction.php:
--------------------------------------------------------------------------------
1 | icons->renderHtml($icon);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewInstructions/Concern/WithStacking.php:
--------------------------------------------------------------------------------
1 | stackPosition = $position;
20 |
21 | return $this;
22 | }
23 |
24 | public function getStackPosition(): int
25 | {
26 | return $this->stackPosition;
27 | }
28 |
29 | public function resetStackPosition(): static
30 | {
31 | return $this->withStackPosition(100);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lib/Magewire/Mechanisms/HandleRequests/ComponentContext/EffectsInterface.php:
--------------------------------------------------------------------------------
1 |
24 | = $block->getChildHtml() ?>
25 |
--------------------------------------------------------------------------------
/dist/Features/SupportRedirects/HandlesRedirects.php:
--------------------------------------------------------------------------------
1 | set('redirect', $url);
19 | if ($navigate) {
20 | store($this)->set('redirectUsingNavigate', true);
21 | }
22 | $shouldSkipRender = !config('livewire.render_on_redirect', false);
23 | $shouldSkipRender && $this->skipRender();
24 | }
25 | }
--------------------------------------------------------------------------------
/lib/Magewire/Features.php:
--------------------------------------------------------------------------------
1 | items as $accessor => $feature) {
27 | $this->componentHookRegistry::register($this->items[$accessor]['type']);
28 | }
29 |
30 | $this->componentHookRegistry::boot();
31 | return $this;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagentoObserverEvents/DTO/ListenerDataTransferObject.php:
--------------------------------------------------------------------------------
1 | */
18 | private array $listeners = [];
19 |
20 | public function with(callable $callback): static
21 | {
22 | $this->listeners[] = $callback;
23 |
24 | return $this;
25 | }
26 |
27 | public function listeners(): array
28 | {
29 | return $this->listeners;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/lib/Magewire/Mechanisms/FrontendAssets/FrontendAssetsFacade.php:
--------------------------------------------------------------------------------
1 | mechanism->returnJavaScriptAsFile();
26 | }
27 |
28 | function getMagewireScriptAttributes(): array
29 | {
30 | return $this->mechanism->getDataByPath('script.html_attributes', []);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/view/base/templates/js/magewire/state.phtml:
--------------------------------------------------------------------------------
1 | getData('view_model');
14 | $magewireFragment = $magewireViewModel->utils()->fragment();
15 |
16 | $state = $block->getData('state') ? 'active' : 'inactive';
17 |
18 | /** @internal Do not modify to ensure Magewire continues to function correctly. */
19 | ?>
20 | make()->script()->start() ?>
21 |
28 | end() ?>
29 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewInstructions/Instructions/Action.php:
--------------------------------------------------------------------------------
1 | action = $action;
32 |
33 | return $this;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/portman/Livewire/Features/SupportLocales/SupportLocales.php:
--------------------------------------------------------------------------------
1 | localeResolver->getLocale();
31 | $locale = strstr($code, '_', true);
32 |
33 | $context->addMemo('locale', $locale);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/dist/Features/SupportLocales/SupportLocales.php:
--------------------------------------------------------------------------------
1 | localeResolver->getLocale();
23 | $locale = strstr($code, '_', true);
24 | $context->addMemo('locale', $locale);
25 | }
26 | function __construct(private readonly LocaleResolver $localeResolver)
27 | {
28 | //
29 | }
30 | }
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Directive/Magento/Escape.php:
--------------------------------------------------------------------------------
1 | escapeUrl({$url}) ?>";
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/ViewStub.php:
--------------------------------------------------------------------------------
1 | stub->getName(), '.stub'));
29 | }
30 |
31 | public function getContent(): string
32 | {
33 | return $this->content ??= file_get_contents($this->stub->getFilename());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Model/View/Utils/Environment.php:
--------------------------------------------------------------------------------
1 | applicationState->getMode() === ApplicationState::MODE_DEVELOPER;
27 | }
28 |
29 | public function isProductionMode(): bool
30 | {
31 | return $this->applicationState->getMode() === ApplicationState::MODE_PRODUCTION;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/etc/events.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Directive/Script.php:
--------------------------------------------------------------------------------
1 | var('fragment')} = \$__magewire->utils()->fragment()->make()->script()->start() ?>";
22 | }
23 |
24 | public function endscript(): string
25 | {
26 | return "var('fragment')}->end() ?>";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireRateLimiting/Config/Source/RateLimitingVariant.php:
--------------------------------------------------------------------------------
1 | self::COMPONENTS_ONLY, 'label' => 'Components only'],
25 | ['value' => self::REQUESTS_ONLY, 'label' => 'Requests only'],
26 | ['value' => self::NONE, 'label' => 'None']
27 | ];
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewInstructions/Instructions/Magento/FlashMessage.php:
--------------------------------------------------------------------------------
1 | data()->set('args.text', $message->render());
31 | return $this;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/.github/workflows/portman.yml:
--------------------------------------------------------------------------------
1 | name: 'Portman Build'
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - main
7 | paths:
8 | - 'portman/**'
9 | - 'src/**'
10 | - 'lib/**'
11 |
12 | permissions:
13 | contents: write
14 | pull-requests: write
15 |
16 | jobs:
17 |
18 | portman:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - name: Checkout
22 | uses: actions/checkout@v4
23 | with:
24 | ref: ${{ github.head_ref }}
25 | token: ${{ secrets.MY_TOKEN }}
26 |
27 | - name: Setup php
28 | uses: shivammathur/setup-php@v2
29 | with:
30 | php-version: '8.2'
31 |
32 | - name: Install composer
33 | uses: ramsey/composer-install@v3
34 | with:
35 | composer-options: "--no-scripts"
36 |
37 | - name: Portman build
38 | run: ./vendor/bin/portman build
39 |
40 | - uses: stefanzweifel/git-auto-commit-action@v5
41 | with:
42 | commit_message: 'chore(portman) build'
43 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Directive/Magento/Block.php:
--------------------------------------------------------------------------------
1 | getChildBlock({$alias}) ? \$block->getChildBlock({$alias})->toHtml() : '' ?>";
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewInstructions/Handler/TypeContext/HandlerTypeMetaData.php:
--------------------------------------------------------------------------------
1 | alias = $alias;
22 |
23 | return $this;
24 | }
25 |
26 | public function getAlias(): string|null
27 | {
28 | return $this->alias;
29 | }
30 |
31 | public function hasAlias(): bool
32 | {
33 | return is_string($this->alias);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/Magewire/Containers/Redirect.php:
--------------------------------------------------------------------------------
1 | component = $component;
38 |
39 | return $this;
40 | }
41 |
42 | public function response($to)
43 | {
44 | //
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/lib/Magewire/Mechanisms/HandleComponents/ComponentContext/Effects.php:
--------------------------------------------------------------------------------
1 | setData($key, $value);
32 | }
33 |
34 | function exclude($key): static
35 | {
36 | return $this->unsetData($key);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Model/View/Utils/Magewire/Builder.php:
--------------------------------------------------------------------------------
1 | httpContext->getValue(Context::CONTEXT_AUTH);
28 | }
29 |
30 | public function isGuest(): bool
31 | {
32 | return ! $this->isCustomer();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/dist/Features/SupportEvents/BaseOn.php:
--------------------------------------------------------------------------------
1 | event) as $event) {
25 | store($this->component)->push('listenersFromAttributes', $this->getName() ?? '$refresh', $event);
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/dist/Features/SupportAttributes/HandlesAttributes.php:
--------------------------------------------------------------------------------
1 | attributes ??= AttributeCollection::fromComponent($this);
18 | }
19 | function setPropertyAttribute($property, $attribute)
20 | {
21 | $attribute->__boot($this, AttributeLevel::PROPERTY, $property);
22 | $this->mergeOutsideAttributes(new AttributeCollection([$attribute]));
23 | }
24 | function mergeOutsideAttributes(AttributeCollection $attributes)
25 | {
26 | $this->attributes = $this->getAttributes()->concat($attributes);
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Model/View/Fragment/Modifier/Developer.php:
--------------------------------------------------------------------------------
1 | applicationState->getMode() === ApplicationState::MODE_DEVELOPER) {
28 | $fragment->withAttribute('magewire-fragment');
29 | }
30 |
31 | return $fragment;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/lib/Magewire/Support/DataScope/Compiler.php:
--------------------------------------------------------------------------------
1 | $uses */
18 | protected array $uses = [];
19 |
20 | abstract public function compile(DataScope $data): array|string;
21 |
22 | /**
23 | * Assign an additional dependency to be used by callable values requiring
24 | * access to global variables that are otherwise inaccessible during injection.
25 | */
26 | public function use(string $name, object $object): static
27 | {
28 | $this->uses[$name] = $object;
29 |
30 | return $this;
31 | }
32 |
33 | protected function uses(): array
34 | {
35 | return $this->uses;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Directive/Base.php:
--------------------------------------------------------------------------------
1 | escapeHtml(__({$value})) ?>";
24 | }
25 |
26 | return "= __({$value}) ?>";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright © Willem Poortman
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/portman/Livewire/Features/SupportRedirects/SupportRedirects.php:
--------------------------------------------------------------------------------
1 | component($this->component);
17 | }
18 |
19 | public function dehydrate($context)
20 | {
21 | $to = $this->storeGet('redirect');
22 | $usingNavigate = $this->storeGet('redirectUsingNavigate');
23 |
24 | if ($to) {
25 | $context->addEffect('redirect', $to);
26 | }
27 |
28 | $usingNavigate && $context->addEffect('redirectUsingNavigate', true);
29 |
30 | if (! $context->isMounting()) {
31 | static::$atLeastOneMountedComponentHasRedirected = true;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/dist/Mechanisms/HandleComponents/Synthesizers/IntSynth.php:
--------------------------------------------------------------------------------
1 | getChildBlock('loader')
13 | ?>
14 |
15 |
16 |
17 |
18 |
19 |
22 | = $blockLoaderIcon->toHtml() ?>
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/view/base/templates/js/alpinejs/magewire.phtml:
--------------------------------------------------------------------------------
1 | getData('view_model');
12 | $magewireFragment = $magewireViewModel->utils()->fragment();
13 |
14 | /**
15 | * AlpineJS - Global
16 | *
17 | * @internal Do not modify to ensure Magewire continues to function correctly.
18 | */
19 | ?>
20 | make()->script()->start() ?>
21 |
32 | end() ?>
33 |
--------------------------------------------------------------------------------
/tests/Playwright/helpers/messages.js:
--------------------------------------------------------------------------------
1 | import process from "process";
2 |
3 | /**
4 | * Verifies whether the specified message was displayed as a flash message.
5 | */
6 | export async function has(page, message) {
7 | await hasAny(page).then(async result => {
8 | if (result) {
9 | const messages = await page.$$eval('.messages div', elements =>
10 | elements.map(el => el.textContent.trim())
11 | );
12 |
13 | if (messages.some(text => text.includes(message))) {
14 | return true;
15 | }
16 | }
17 | })
18 |
19 | return false;
20 | }
21 |
22 | /**
23 | * Verifies whether there are any messages been shown.
24 | */
25 | export async function hasAny(page) {
26 | const messages = page.locator('#messages');
27 |
28 | if (messages.isVisible()) {
29 | const messages = await page.$$eval('.messages div', elements =>
30 | elements.map(el => el.textContent.trim())
31 | );
32 |
33 | return messages.length !== 0;
34 | }
35 |
36 | return false;
37 | }
38 |
--------------------------------------------------------------------------------
/dist/Mechanisms/HandleComponents/Synthesizers/FloatSynth.php:
--------------------------------------------------------------------------------
1 | getData('view_model');
12 | $magewireFragment = $magewireViewModel->utils()->fragment();
13 | ?>
14 | make()->script()->start() ?>
15 |
25 | end() ?>
26 |
--------------------------------------------------------------------------------
/lib/Magewire/Mechanisms/HandleRequests/HandleRequestFacade.php:
--------------------------------------------------------------------------------
1 | mechanism->handleUpdate();
32 | }
33 |
34 | function getUpdateUri(): string
35 | {
36 | return $this->mechanism->getUpdateUri();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/MagewireBc/Features/SupportMagewireBackwardsCompatibility/HandlesComponentBackwardsCompatibility.php:
--------------------------------------------------------------------------------
1 | formKey->getFormKey();
31 | } catch (LocalizedException $exception) {
32 | $this->logger->critical($exception->getMessage(), ['exception' => $exception]);
33 | }
34 |
35 | return 'unknown-csrf-token';
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/Model/Magewire/Notifier/NotificationStateEnum.php:
--------------------------------------------------------------------------------
1 | value;
27 | }
28 |
29 | public function getCssClass(): string
30 | {
31 | return 'state-' . $this->value;
32 | }
33 |
34 | public function getLevel(): int
35 | {
36 | $level = array_search($this, self::cases(), true);
37 | return $level !== false ? $level : 0;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/Playwright/README.md:
--------------------------------------------------------------------------------
1 | # Playwright
2 |
3 | ## Requirements
4 |
5 | - Magento Sample Data
6 |
7 | ## Install
8 |
9 | To run the Magewire Playwright tests, follow these steps:
10 |
11 | 1. Navigate into the Playwright tests directory:
12 | ```sh
13 | cd tests/Playwright
14 | ```
15 |
16 | 2. Install all dev-dependencies
17 | ```sh
18 | npm install
19 | ```
20 |
21 | 3. Create a `.env` config file in the root `Playwright` folder using the following variables:
22 | ```text
23 | BASE_URL=https://local.test/
24 |
25 | ENVIRONMENT=local
26 | ACCOUNT_FIRSTNAME=Veronica
27 | ACCOUNT_LASTNAME=Costello
28 | ACCOUNT_EMAIL=roni_cost@example.com
29 | ACCOUNT_PASSWORD=roni_cost3@example.com
30 | ```
31 | _Set the `BASE_URL` value with the `base-url` of your Magento instance._
32 |
33 |
34 | 4. Run tests
35 | ```sh
36 | npm run test
37 | ```
38 |
39 | 5. Run tests manually (optional)
40 | ```sh
41 | npx playwright test --ui
42 | ```
43 |
44 | ## More details
45 |
46 | For more information about Playwright, please refer to [the documentation](https://playwright.dev/docs/intro).
47 |
--------------------------------------------------------------------------------
/src/registration.php:
--------------------------------------------------------------------------------
1 | parser(ExpressionParserType::FUNCTION_ARGUMENTS)->parse($expression);
22 |
23 | // TODO: should handle exceptions, logging them and return an empty string when so.
24 | return method_exists($this, $directive) ? $this->$directive(...$parsed->arguments()->all()) : '';
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lib/Magento/App/Cache/Type/Magewire.php:
--------------------------------------------------------------------------------
1 | get(self::TYPE_IDENTIFIER), self::CACHE_TAG);
27 | }
28 |
29 | public function load($identifier)
30 | {
31 | $data = parent::load($identifier);
32 |
33 | return is_string($data) ? $this->serializer->unserialize($data) : $data;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewInstructions/Handler/HandlerTypeContext.php:
--------------------------------------------------------------------------------
1 | handler();
26 | }
27 |
28 | public function return(): HandlerType
29 | {
30 | return $this->also();
31 | }
32 |
33 | public function only(array $arguments = []): HandlerType
34 | {
35 | return ObjectManager::getInstance()->create(get_class($this->handler()), $arguments);
36 | }
37 |
38 | protected function handler(): HandlerType
39 | {
40 | return $this->handler;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Model/App/AbstractExceptionHandler.php:
--------------------------------------------------------------------------------
1 | getMessage(), $exception->getCode(), $exception->getPrevious());
22 | }
23 |
24 | return $exception;
25 | }
26 |
27 | function handleWithBlock(AbstractBlock $block, Exception $exception, bool $subsequent = false): AbstractBlock
28 | {
29 | if ($block instanceof Template) {
30 | $block->setTemplate('Magewirephp_Magewire::magewire/exception.phtml');
31 | }
32 |
33 | return $block;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Model/View/Utils/Csp.php:
--------------------------------------------------------------------------------
1 | csp->isCspAvailable()
28 | ? $this->csp->getMagentoCspNonceProvider()->generateNonce()
29 | : '';
30 | }
31 |
32 | public function generateNonceAttribute(string $format = ' %s'): string
33 | {
34 | return $this->csp->isCspAvailable()
35 | ? sprintf(sprintf($format, 'nonce="%s"'), $this->escaper->escapeHtmlAttr($this->generateNonce()))
36 | : '';
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/lib/Magento/Framework/View/BlockRenderingRegistry.php:
--------------------------------------------------------------------------------
1 | current = $block;
25 | $this->blocks[] = $block;
26 |
27 | return $this;
28 | }
29 |
30 | public function pop(): static
31 | {
32 | $this->previous = array_pop($this->blocks);
33 |
34 | return $this;
35 | }
36 |
37 | public function previous(): BlockInterface|null
38 | {
39 | return $this->previous;
40 | }
41 |
42 | public function current(): BlockInterface|null
43 | {
44 | return $this->current;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Directive/Parser/ExpressionParser.php:
--------------------------------------------------------------------------------
1 | arguments()->merge(
28 | strlen($content) === 0 ? [] : $this->parseArguments($content)
29 | );
30 |
31 | return $this;
32 | }
33 |
34 | abstract protected function parseArguments(string $expression): array;
35 |
36 | public function arguments(): Arguments
37 | {
38 | return $this->arguments ??= $this->argumentsFactory->create();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Directive/Json.php:
--------------------------------------------------------------------------------
1 | parser(Directive\Parser\ExpressionParserType::FUNCTION_ARGUMENTS)->parse($expression)->arguments();
25 |
26 | $value = $arguments->get('value', $arguments->get('default', []));
27 | $flags = $arguments->get('flags', $this->encodingOptions);
28 | $depth = $arguments->get('depth', 512);
29 |
30 | return "";
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/view/frontend/templates/magewire/tests/playwright/directives/base.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Basics
5 |
6 |
7 |
8 |
9 |
10 | | Directive |
11 | Input |
12 | Result |
13 | Expected |
14 |
15 |
16 |
17 |
18 |
19 | | translate |
20 | foo |
21 | @translate(value: 'foo', escape: false) |
22 | foo |
23 |
24 |
25 |
26 | | translate (escaped) |
27 | bar |
28 | @translate(value: 'bar') |
29 | bar |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/Controller/MagewireUpdateRouteFrontend.php:
--------------------------------------------------------------------------------
1 | fn (Request $request): bool => $request->isPost(),
24 | 'update_uri' => fn (Request $request): bool => str_starts_with($request->getPathInfo(), '/magewire/update'),
25 | 'content_type' => fn (Request $request): bool => $request->getHeader('Content-Type') === 'application/json'
26 | ];
27 | }
28 |
29 | public function createAction(RequestInterface $request): ActionInterface
30 | {
31 | return $this->actionFactory()->create(Update::class);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/dist/Transparency.php:
--------------------------------------------------------------------------------
1 | target;
19 | }
20 | function offsetExists(mixed $offset): bool
21 | {
22 | return isset($this->target[$offset]);
23 | }
24 | function offsetGet(mixed $offset): mixed
25 | {
26 | return $this->target[$offset];
27 | }
28 | function offsetSet(mixed $offset, mixed $value): void
29 | {
30 | $this->target[$offset] = $value;
31 | }
32 | function offsetUnset(mixed $offset): void
33 | {
34 | unset($this->target[$offset]);
35 | }
36 | function getIterator(): Traversable
37 | {
38 | return (function () {
39 | foreach ($this->target as $key => $value) {
40 | yield $key => $value;
41 | }
42 | })();
43 | }
44 | }
--------------------------------------------------------------------------------
/portman/Livewire/Mechanisms/ComponentRegistry.php:
--------------------------------------------------------------------------------
1 | getNameAndClass($nameOrClass);
18 |
19 | $component = new $class;
20 |
21 | $component->setId($id ?: str()->random(20));
22 |
23 | $component->setName($name);
24 |
25 | // // Parameters passed in automatically set public properties by the same name...
26 | // foreach ($params as $key => $value) {
27 | // if (! property_exists($component, $key)) continue;
28 |
29 | // // Typed properties shouldn't be set back to "null". It will throw an error...
30 | // if ((new \ReflectionProperty($component, $key))->getType() && is_null($value)) continue;
31 |
32 | // $component->$key = $value;
33 | // }
34 |
35 | return $component;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireRateLimiting/RateLimiterExceptionHandler.php:
--------------------------------------------------------------------------------
1 | setBody('Too Many Requests.');
25 | $response->setHttpResponseCode(429);
26 |
27 | return $response;
28 | };
29 | }
30 |
31 | return $exception;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/dist/Pipe.php:
--------------------------------------------------------------------------------
1 | target = $target;
18 | }
19 | function __invoke(...$params)
20 | {
21 | if (empty($params)) {
22 | return $this->target;
23 | }
24 | [$before, $through, $after] = [[], null, []];
25 | foreach ($params as $key => $param) {
26 | if (!$through) {
27 | if (is_callable($param)) {
28 | $through = $param;
29 | } else {
30 | $before[$key] = $param;
31 | }
32 | } else {
33 | $after[$key] = $param;
34 | }
35 | }
36 | $params = [...$before, $this->target, ...$after];
37 | $this->target = $through(...$params);
38 | return $this;
39 | }
40 | }
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Directive/Magento/Auth.php:
--------------------------------------------------------------------------------
1 | action('magento.auth')->execute('is_customer')): ?>";
22 | }
23 |
24 | public function endauth(): string
25 | {
26 | return parent::endif();
27 | }
28 |
29 | #[ScopeDirectiveChain(methods: ['endguest'])]
30 | public function guest(): string
31 | {
32 | return "action('magento.auth')->execute('is_guest')): ?>";
33 | }
34 |
35 | public function endguest(): string
36 | {
37 | return parent::endif();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Model/View/Fragment/Script.php:
--------------------------------------------------------------------------------
1 | withValidator(fn ($script) => str_starts_with($script, ''));
23 | }
24 |
25 | /**
26 | * Returns the content between the script tags.
27 | */
28 | public function getScriptCode(): string
29 | {
30 | if (is_string($this->code)) {
31 | return $this->code;
32 | }
33 |
34 | $start = strpos($this->raw, '>');
35 | $end = strrpos($this->raw, '<');
36 |
37 | if ($start !== false && $end !== false && $start < $end) {
38 | $this->code = trim(substr($this->raw, $start + 1, $end - $start - 1));
39 | }
40 |
41 | return $this->code ?? '';
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/dist/Mechanisms/HandleComponents/Synthesizers/StdClassSynth.php:
--------------------------------------------------------------------------------
1 | $child) {
24 | $data[$key] = $dehydrateChild($key, $child);
25 | }
26 | return [$data, []];
27 | }
28 | function hydrate($value, $meta, $hydrateChild)
29 | {
30 | $obj = new stdClass();
31 | foreach ($value as $key => $child) {
32 | $obj->{$key} = $hydrateChild($key, $child);
33 | }
34 | return $obj;
35 | }
36 | function set(&$target, $key, $value)
37 | {
38 | $target->{$key} = $value;
39 | }
40 | }
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/Directive/Fragment.php:
--------------------------------------------------------------------------------
1 | var('fragment')} = \$__magewire->utils()->fragment()->make({$type})->start() ?>";
25 | }
26 |
27 | public function endfragment(): string
28 | {
29 | return "var('fragment')}->end() ?>";
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/view/frontend/layout/default.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/themes/Hyva/Magewire/Features/SupportMagewireCompiling/View/Directive/Hyva/SvgHeroIcon.php:
--------------------------------------------------------------------------------
1 | parser(ExpressionParserType::FUNCTION_ARGUMENTS)->parse($expression);
23 |
24 | $arguments = $parsed->arguments()->unset('type');
25 | $arguments->default('version', 'outlined');
26 |
27 | return "= \$__magewire->action('hyva.svg-icons')->execute('heroicon', {$arguments->renderAsNamed()}) ?>";
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/MagewireUnderscoreViewModel.php:
--------------------------------------------------------------------------------
1 | actionManager->load($class);
31 | }
32 |
33 | public function arguments(): DataScope
34 | {
35 | return $this->arguments;
36 | }
37 |
38 | public function utils(): Utils
39 | {
40 | return $this->utils;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewInstructions/Handler/TypeContext/HandlerTypeTargets.php:
--------------------------------------------------------------------------------
1 | query = $this->builder?->__toString();
28 | //
29 | // return $this;
30 | // }
31 |
32 | // public function query(): QueryBuilder
33 | // {
34 | // return $this->builder ??= ObjectManager::getInstance()->create(QueryBuilder::class, [
35 | // 'context' => $this
36 | // ]);
37 | // }
38 |
39 | public function __toString(): string
40 | {
41 | return $this->query ?? '';
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/dist/Mechanisms/HandleComponents/Synthesizers/EnumSynth.php:
--------------------------------------------------------------------------------
1 | value, ['class' => get_class($target)]];
33 | }
34 | function hydrate($value, $meta)
35 | {
36 | if ($value === null || $value === '') {
37 | return null;
38 | }
39 | $class = $meta['class'];
40 | return $class::from($value);
41 | }
42 | }
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireCompiling/View/ScopeDirective.php:
--------------------------------------------------------------------------------
1 | scopeResponsibilities[$directive] ?? null)) {
25 | $reflection = new ReflectionClass($this);
26 |
27 | foreach ($reflection->getMethods() as $method) {
28 | $attributes = $method->getAttributes(ScopeDirectiveChain::class);
29 | $attribute = ($attributes[0] ?? null) ? $attributes[0]->newInstance() : null;
30 |
31 | if ($attribute) {
32 | $this->scopeResponsibilities[$method->getName()] = $attribute->methods;
33 | }
34 | }
35 | }
36 |
37 | return $this->scopeResponsibilities[$directive] ?? [];
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewInstructions/ViewInstructionFactory.php:
--------------------------------------------------------------------------------
1 | $instructions
19 | */
20 | public function __construct(
21 | private readonly array $instructions = []
22 | ) {
23 | //
24 | }
25 |
26 | /**
27 | * @template T of ViewInstruction
28 | * @param class-string $instruction
29 | * @return T
30 | * @throws ViewInstructionDoesNotExistException
31 | */
32 | public function create(string $instruction): ViewInstruction
33 | {
34 | if (array_key_exists($instruction, $this->instructions)) {
35 | return $this->instructions[$instruction];
36 | }
37 | if (class_exists($instruction)) {
38 | return ObjectManager::getInstance()->create($instruction);
39 | }
40 |
41 | throw new ViewInstructionDoesNotExistException();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/portman/Livewire/Drawer/BaseUtils.php:
--------------------------------------------------------------------------------
1 | getDeclaringClass()->getName() !== \Magewirephp\Magewire\Component::class;
19 | });
20 | }
21 |
22 | static function getPublicMethodsDefinedBySubClass($target)
23 | {
24 | $methods = array_filter((new \ReflectionObject($target))->getMethods(), function ($method) {
25 | $isInBaseComponentClass = $method->getDeclaringClass()->getName() === \Livewire\Component::class;
26 |
27 | return $method->isPublic()
28 | && ! $method->isStatic()
29 | && ! $isInBaseComponentClass;
30 | });
31 |
32 | return array_map(function ($method) {
33 | return $method->getName();
34 | }, $methods);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewInstructions/Handler/TypeContext/HandlerTypeInteractions.php:
--------------------------------------------------------------------------------
1 | handler()->listen()->for('click');
21 |
22 | return $this;
23 | }
24 |
25 | public function onDoubleClick(): static
26 | {
27 | $this->handler()->listen()->for('dblclick');
28 |
29 | return $this;
30 | }
31 |
32 | public function onMouseOver(): static
33 | {
34 | $this->handler()->listen()->for('mouseover');
35 |
36 | return $this;
37 | }
38 |
39 | public function onMouseOut(): static
40 | {
41 | $this->handler()->listen()->for('mouseout');
42 |
43 | return $this;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireFlakes/View/Directive/FlakeDirective.php:
--------------------------------------------------------------------------------
1 | action('magewire.flake')->execute(
28 | 'create',
29 | flake: \$decoded['flake'],
30 | data: \$decoded['data'] ?? [],
31 | metadata: \$decoded['metadata'] ?? [],
32 | variables: \$variables
33 | );
34 |
35 | unset(\$decoded, \$fragment, \$variables);
36 | ?>
37 | DIRECTIVE;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/Setup/Patch/Data/EnableCache.php:
--------------------------------------------------------------------------------
1 | cacheManager->setEnabled(
41 | array_intersect($this->cacheManager->getAvailableTypes(), [MagewireCacheType::TYPE_IDENTIFIER]),
42 | true
43 | );
44 |
45 | $this->cacheManager->clean($enableMagewireCache);
46 | return $this;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/lib/Magento/App/Cache/MagewireCacheSection.php:
--------------------------------------------------------------------------------
1 | tags)) {
33 | $this->tags[] = $this->identifier;
34 | }
35 |
36 | return $this->magewireCacheType->save($this->serializer->serialize($data), $this->identifier, $this->tags, $ttl ?? $this->ttl);
37 | }
38 |
39 | public function fetch(): array
40 | {
41 | $data = $this->magewireCacheType->load($this->identifier);
42 |
43 | return ! $data ? [] : $data;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagentoFlashMessages/SupportMagentoFlashMessages.php:
--------------------------------------------------------------------------------
1 | component->hasFlashMessages()) {
21 | $context->pushEffect('dispatches', [
22 | 'name' => 'magewire:flash-messages:dispatch',
23 | 'params' => $this->mapFlashMessages($this->component->getFlashMessages())
24 | ]);
25 | }
26 | }
27 |
28 | /**
29 | * @param array $messages
30 | */
31 | private function mapFlashMessages(array $messages): array
32 | {
33 | return array_map(static function (FlashMessage $message) {
34 | return [
35 | 'text' => $message->getMessage()->render(),
36 | 'type' => $message->getType()
37 | ];
38 | }, $messages);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Model/View/Utils/Magewire/Features.php:
--------------------------------------------------------------------------------
1 | featuresServiceType->viewModel($utility);
35 | } catch (NotFoundException $exception) {
36 | $this->logger->critical($exception->getMessage(), ['exception' => $exception]);
37 |
38 | throw new BadMethodCallException(
39 | sprintf('Feature view model "%1" does not exist.', $utility)
40 | );
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/dist/Features/SupportRedirects/Redirector.php:
--------------------------------------------------------------------------------
1 | component->redirect($this->generator->to($path, [], $secure));
20 | return $this;
21 | }
22 | public function away($path, $status = 302, $headers = [])
23 | {
24 | return $this->to($path, $status, $headers);
25 | }
26 | public function with($key, $value = null)
27 | {
28 | $key = is_array($key) ? $key : [$key => $value];
29 | foreach ($key as $k => $v) {
30 | $this->session->flash($k, $v);
31 | }
32 | return $this;
33 | }
34 | public function component(Component $component)
35 | {
36 | $this->component = $component;
37 | return $this;
38 | }
39 | public function response($to)
40 | {
41 | return $this->createRedirect($to, 302, []);
42 | }
43 | }
--------------------------------------------------------------------------------
/lib/Magewire/Mechanisms/FrontendAssets/FrontendAssetsViewModel.php:
--------------------------------------------------------------------------------
1 | frontendAssetsMechanism->returnJavaScriptAsFile();
29 | }
30 |
31 | function getScriptAttributes(): string
32 | {
33 | $attributes = $this->frontendAssetsMechanism->getDataByPath('script.html_attributes', []);
34 |
35 | return implode(' ', array_map(function ($attribute, ?string $expression) {
36 | return $expression === null ? $attribute : sprintf('%s="%s"', $attribute, $this->escaper->escapeHtmlAttr($expression));
37 | }, array_keys($attributes), array_values($attributes)));
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireLoaders/SupportMagewireLoaders.php:
--------------------------------------------------------------------------------
1 | component->getLoader();
22 |
23 | if ($loader) {
24 | if (is_array($loader)) {
25 | $loader = map_with_keys(function ($value, $key) {
26 | if (is_string($value)) {
27 | $value = [$value];
28 | }
29 | if (is_array($value)) {
30 | $value = array_map('__', array_filter($value, 'is_string'));
31 | }
32 |
33 | return [$key => $value];
34 | }, $loader);
35 | } elseif (is_string($loader)) {
36 | $loader = __($loader);
37 | }
38 |
39 | $context->pushEffect('loader', $loader);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Controller/Router.php:
--------------------------------------------------------------------------------
1 | matchesMagewireSpecifics($request)) {
33 | foreach (array_filter($this->routes) as $route) {
34 | if ($result = $route->match($request)) {
35 | return $result;
36 | }
37 | }
38 | }
39 |
40 | return null;
41 | }
42 |
43 | private function matchesMagewireSpecifics(RequestInterface $request): bool
44 | {
45 | return $request instanceof Request && $this->magewireRouteValidator->validate($request);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/portman/Livewire/Concerns/InteractsWithProperties.php:
--------------------------------------------------------------------------------
1 | {Utils::beforeFirstDot($name)};
26 |
27 | if (Utils::containsDots($name)) {
28 | return data_get($value, Utils::afterFirstDot($name));
29 | }
30 |
31 | return $value;
32 | }
33 |
34 | function fill($values)
35 | {
36 | $publicProperties = array_keys($this->all());
37 |
38 | if ($values instanceof DataObject) {
39 | $values = $values->toArray();
40 | }
41 |
42 | foreach ($values as $key => $value) {
43 | if (in_array(Utils::beforeFirstDot($key), $publicProperties)) {
44 | data_set($this, $key, $value);
45 | }
46 | }
47 | }
48 |
49 | function all()
50 | {
51 | return Utils::getPublicPropertiesDefinedOnSubclass($this);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/tests/Playwright/tests/directives.spec.js:
--------------------------------------------------------------------------------
1 | import { expect } from '@playwright/test'
2 | import { test } from '../fixtures/frontend/customer.js';
3 | import { logout } from "../helpers/customer/account";
4 |
5 | test.describe('Directives', () => {
6 | /*
7 | * Runs before each individual test.
8 | */
9 | test.beforeEach(async ({ page, magentoCustomerDashboard }) => {
10 | const pageVersion = Math.floor(Math.random() * 10000);
11 |
12 | await magentoCustomerDashboard.goto(`/magewire/playwright/directives?v=${pageVersion}`);
13 | });
14 |
15 | /*
16 | * Runs after each individual test.
17 | */
18 | test.afterEach(async ({ page }) => {
19 | await logout(page)
20 | });
21 |
22 | test('Check Page Title', async ({ page }) => {
23 | const title = page.locator('[data-ui-id="page-title-wrapper"]');
24 |
25 | await expect(title).toHaveText('Magewire / Playwright / Directives');
26 | })
27 |
28 | test('Check Base Directives', async ({ page }) => {
29 | const table = page.locator('[wire\\:id="magewire.playwright.directives.base"]');
30 | await expect(table).toBeVisible();
31 |
32 | const rows = await table.locator('tbody tr').all();
33 | expect(rows).toHaveLength(2)
34 |
35 | for (const row of rows) {
36 | const cells = await row.locator('td').allInnerTexts();
37 |
38 | expect(cells[2]).toBe(cells[3]);
39 | }
40 | });
41 | });
42 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireRateLimiting/Storage/RateLimiterCacheStorage.php:
--------------------------------------------------------------------------------
1 | cache->fetch();
29 |
30 | return $storage[$key] ?? [];
31 | }
32 |
33 | public function set(string $key, array $data, int|null $ttl = null): bool
34 | {
35 | $storage = $this->cache->fetch();
36 | $storage[$key] = $data;
37 |
38 | return $this->cache->save($storage, $ttl);
39 | }
40 |
41 | public function unset(string $key): bool
42 | {
43 | $storage = $this->cache->fetch();
44 | unset($storage[$key]);
45 |
46 | return $this->cache->save($storage);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/lib/Magewire/Features/SupportMagewireViewInstructions/Instructions/Notification.php:
--------------------------------------------------------------------------------
1 | data()->set('args.text', $message->render());
31 | return $this;
32 | }
33 |
34 | public function withDelay(int|null $delay): static
35 | {
36 | $this->data()->set('args.delay', $delay);
37 | return $this;
38 | }
39 |
40 | public function withTitle(Phrase|null $title): static
41 | {
42 | $this->data()->set('args.title', $title);
43 | return $this;
44 | }
45 |
46 | public function withType(string|null $type): static
47 | {
48 | $this->data()->set('args.type', $type);
49 | return $this;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/Model/View/Utils/Fragment.php:
--------------------------------------------------------------------------------
1 | types (e.g., 'header', 'footer')
30 | * 2. Direct class names
31 | *
32 | * @param string|null $name
33 | * @return \Magewirephp\Magewire\Model\View\Fragment|FragmentFactory
34 | * @throws InvalidArgumentException
35 | *
36 | * @see FragmentFactory::$types For registering custom fragment types via DI
37 | */
38 | public function make(string|null $name = null): FragmentFactory|\Magewirephp\Magewire\Model\View\Fragment
39 | {
40 | if ($name) {
41 | return $this->fragmentFactory->custom($name);
42 | }
43 |
44 | return $this->fragmentFactory;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/lib/Magewire/Concerns/WithTagging.php:
--------------------------------------------------------------------------------
1 | */
16 | private array $tags = [];
17 |
18 | /**
19 | * Tag a fragment with a recognizable name.
20 | */
21 | public function tag(string $name): static
22 | {
23 | $sanitized = preg_replace('/[^a-z0-9]/', '', strtolower($name));
24 |
25 | if ($sanitized !== '') {
26 | $this->tags[] = $sanitized;
27 | }
28 |
29 | return $this;
30 | }
31 |
32 | /**
33 | * Clears all tags either completely or by a provided filter callback.
34 | */
35 | public function clearTags(callable|null $filter = null): static
36 | {
37 | $this->tags = $filter ? array_filter($this->tags, $filter) : [];
38 |
39 | return $this;
40 | }
41 |
42 | /**
43 | * Returns if the given tag exists.
44 | */
45 | public function hasTag(string $name): bool
46 | {
47 | return is_string($this->tags[$name] ?? null);
48 | }
49 |
50 | /**
51 | * Returns if any tags were set.
52 | */
53 | public function hasTags(): bool
54 | {
55 | return count($this->tags) > 0;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/lib/Magewire/Support/Parser/DomElementParser.php:
--------------------------------------------------------------------------------
1 | attributes()->set($match[1], $match[3]);
41 | }
42 |
43 | return $this;
44 | }
45 |
46 | public function attributes(): DataArray
47 | {
48 | return $this->attributes ??= $this->attributesFactory->create();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/dist/Features/SupportEvents/Event.php:
--------------------------------------------------------------------------------
1 | name = $name;
23 | $this->params = $params;
24 | }
25 | public function self()
26 | {
27 | $this->self = true;
28 | return $this;
29 | }
30 | public function component($name)
31 | {
32 | $this->component = $name;
33 | return $this;
34 | }
35 | public function to($name)
36 | {
37 | return $this->component($name);
38 | }
39 | public function serialize()
40 | {
41 | $output = ['name' => $this->name, 'params' => $this->params];
42 | if ($this->self) {
43 | $output['self'] = true;
44 | }
45 | if ($this->component) {
46 | $output['to'] = app(ComponentRegistry::class)->getName($this->component);
47 | }
48 | return $output;
49 | }
50 | }
--------------------------------------------------------------------------------