From d505e46b8b9ff9505e2fb1f1bcb0616321a3b8a8 Mon Sep 17 00:00:00 2001 From: aryaantony92 <97134765+aryaantony92@users.noreply.github.com> Date: Fri, 17 Feb 2023 17:01:30 +0100 Subject: [PATCH] Move personalization to own bundle (#14102) * Moved js files and controller to the personalization bundle * Moved translations,tests,lib files,configurations etc to own bundle * Update Doc * Add updated namespace in yaml config * Minor fixes * Moved some more files and fixed some errors * Remove TargetingOverrideHandlersPass from core * Error fixes and added event for document settings tab * More fixes * Update Documentation * Update doc and add migration to remove user permissions * Moved model files, fixed error with clearing editables, moved the dataobject configuration of target group to bundle * Minor fixes * More refactoring * More fixes * Fix Php stan * Fix PHP stan * Removed the dependency injection and implementd it using event listener in DocumentRenderer.php * Typo fixes * Added pre render event listener and removed the leftover targeting section from standard document page in the core * Add condition getUseTargetGroup() method in snipper * Added alias to model used by portal engine * Add if condition for target group value * Change namespace in ecommerce framework and update translations * DocumentTargetingConfigurator usages refactoring * Move DebugStopwatchPass to the bundle * Refactor geoip pimcore setting * Add class aliases for the data types * Delete listeners.yaml * Fix EventListener * Refactor Newsletter Address DefaultAdapter to extract target groups * Fix Snippet & IncludeRenderer * Further refactoring * futher refactoring * Revert configs * Refactor ecommerce target group condition * Refactor ecommerce target group condition * Refactor TargetGroup data types to use legacy namespaces for BC reasons * Action files cleanup * further refactorings * further refactorings & cleanup * Further Refactoring - Move Renderlet configure targeting to event listener * Use generic event for Document Page settings * Further Refactorings * Fix codeception test * Fix PHP stan * Remove user permission (targeting) from core bundle and add warning on bundle uninstall * Fix IncludeRenderer pre render even dispatch * Fix Renderlet pre render event arguments * Add ignore paths for passing phpstan * Revert DocumentTargetGroupListener return typehint * Fix PimcoreTargetingDataCollector return typehints * Add migration to mark bundle as installed * Further refactoring & fixes * Add requirement to EcommerceBundle * Modified migration to mark the bundle as installed * Add missing targetGroup.js * Remove comment in console * Re-add geoip2/geoip2 temporarily * Add TargetingSnippetController * Optimize uninstall warning * catch targeting configured check * Docs changes --------- Co-authored-by: Divesh Pahuja --- bundles/AdminBundle/public/css/admin.css | 26 - bundles/AdminBundle/public/css/icons.css | 28 - .../document/document_language_overview.js | 2 +- .../public/js/pimcore/document/edit.js | 97 +-- .../addressSourceAdapters/default.js | 2 +- .../js/pimcore/document/pages/settings.js | 42 +- .../public/js/pimcore/document/tree.js | 2 +- .../AdminBundle/public/js/pimcore/events.js | 6 + .../public/js/pimcore/layout/toolbar.js | 77 +- .../AdminBundle/public/js/pimcore/startup.js | 21 - .../Admin/Document/DocumentControllerBase.php | 4 +- .../Admin/Document/PageController.php | 17 +- .../Admin/Document/RenderletController.php | 29 +- .../src/Controller/Admin/IndexController.php | 1 - .../templates/admin/index/index.html.twig | 13 - .../AdminBundle/translations/admin.en.yaml | 6 - .../translations/admin_ext.en.yaml | 13 - .../CoreBundle/config/pimcore/default.yaml | 27 - bundles/CoreBundle/config/profiler.yaml | 7 - bundles/CoreBundle/config/targeting.yaml | 162 ----- .../config/targeting/listeners.yaml | 12 - .../CoreBundle/config/targeting/services.yaml | 7 - .../src/DependencyInjection/Configuration.php | 40 -- .../PimcoreCoreExtension.php | 67 -- .../Frontend/ElementListener.php | 29 +- .../Frontend/FullPageCacheListener.php | 32 +- .../src/Migrations/Version20230125164101.php | 47 ++ bundles/CoreBundle/src/PimcoreCoreBundle.php | 3 - .../EcommerceFrameworkBundle/composer.json | 1 + .../src/PimcoreEcommerceFrameworkBundle.php | 7 +- .../src/PricingManager/Environment.php | 2 +- .../PricingManager/EnvironmentInterface.php | 2 +- .../src/PricingManager/PricingManager.php | 2 +- .../src/Resources/config/pimcore/config.yaml | 1 - .../public/js/pricing/config/item.js | 70 -- .../src/Tools/Installer.php | 14 +- bundles/InstallBundle/dump/install.sql | 36 - bundles/InstallBundle/src/Installer.php | 1 - bundles/PersonalizationBundle/.editorconfig | 21 + bundles/PersonalizationBundle/.gitattributes | 2 + .../.github/ci/files/.env | 2 + .../.github/ci/files/.my.cnf | 5 + .../.github/ci/files/bin/console | 46 ++ .../.github/ci/files/config/bundles.php | 5 + .../.github/ci/files/config/config.yaml | 3 + .../ci/files/config/packages/security.yaml | 59 ++ .../ci/files/config/packages/test/config.yaml | 32 + .../.github/ci/files/config/services.yaml | 31 + .../.github/ci/files/config/system.yaml | 81 +++ .../.github/ci/files/kernel/Kernel.php | 22 + .../.github/ci/files/public/.htaccess | 336 +++++++++ .../.github/ci/files/public/index_test.php | 41 ++ .../.github/ci/files/templates/.gitkeep | 0 .../ci/scripts/setup-pimcore-environment.sh | 15 + bundles/PersonalizationBundle/.gitignore | 68 ++ bundles/PersonalizationBundle/.php_cs.dist | 71 ++ bundles/PersonalizationBundle/LICENSE.md | 36 + .../PersonalizationBundle}/README.md | 10 +- bundles/PersonalizationBundle/SECURITY.md | 20 + .../codeception.dist.yml | 17 + bundles/PersonalizationBundle/composer.json | 45 ++ .../config/pimcore/config.yaml | 2 + .../config/pimcore/default.yaml | 42 ++ .../config/pimcore/routing.yaml | 6 + .../config/targeting.yaml | 162 +++++ .../config/targeting/listeners.yaml | 22 + .../config/targeting/services.yaml | 42 ++ .../01_Visitor_Info.md | 6 +- .../03_Conditions.md | 40 +- .../05_Data_Providers.md | 20 +- .../07_Action_Handlers.md | 26 +- .../09_Targeting_Storage.md | 16 +- .../11_Frontend_Javascript.md | 16 +- .../doc/Development_Documentation}/README.md | 4 +- .../doc/User_Documentation}/01_Concepts.md | 0 .../01_Define_Target_Groups.md | 0 .../03_Visitor_Profiling.md | 0 .../05_Create_Personalized_Content.md | 0 ..._Deliver_Personalized_Content_and_Debug.md | 0 .../03_How_to_Personalize_Content/README.md | 0 .../User_Documentation}/05_Examples/README.md | 0 bundles/PersonalizationBundle/gpl-3.0.txt | 674 ++++++++++++++++++ .../public/css/icons.css | 27 + .../public/css/targeting.css | 25 + .../public/js/document/areatoolbar.js | 125 ++++ .../pricing/conditions/targetGroup.js | 82 +++ .../js}/object/classes/data/targetGroup.js | 0 .../classes/data/targetGroupMultiselect.js | 0 .../public/js}/object/tags/targetGroup.js | 0 .../js}/object/tags/targetGroupMultiselect.js | 0 .../public/js/settings}/action/abstract.js | 4 +- .../public/js/settings}/actions.js | 16 +- .../public/js/settings}/condition/abstract.js | 4 +- .../public/js/settings}/conditions.js | 58 +- .../public/js/settings}/rules/item.js | 18 +- .../public/js/settings}/rules/panel.js | 16 +- .../public/js/settings}/targetGroups/item.js | 6 +- .../public/js/settings}/targetGroups/panel.js | 14 +- .../public/js/settings/targetingtoolbar.js} | 4 +- .../public/js/startup.js | 142 ++++ .../public/js/targeting.js | 0 .../Controller/Admin/TargetingController.php | 29 +- .../Admin/TargetingPageController.php | 108 +++ .../Admin/TargetingSnippetController.php | 105 +++ .../PimcoreTargetingDataCollector.php | 11 +- .../Compiler/DebugStopwatchPass.php | 10 +- .../TargetingOverrideHandlersPass.php | 6 +- .../src/DependencyInjection/Configuration.php | 57 ++ .../PimcorePersonalizationExtension.php | 94 +++ .../AddressSourceAdapter/DefaultAdapter.php | 104 +++ .../PricingManager/Condition/TargetGroup.php | 15 +- .../src}/Event/Model/TargetGroupEvent.php | 4 +- .../src}/Event/TargetGroupEvents.php | 8 +- .../AssignDocumentTargetGroupEvent.php | 6 +- .../Event/Targeting/BuildConditionEvent.php | 4 +- .../src}/Event/Targeting/OverrideEvent.php | 2 +- .../Event/Targeting/RenderToolbarEvent.php | 2 +- .../Event/Targeting/TargetingCodeEvent.php | 2 +- .../src}/Event/Targeting/TargetingEvent.php | 4 +- .../TargetingResolveVisitorInfoEvent.php | 4 +- .../Event/Targeting/TargetingRuleEvent.php | 6 +- .../src}/Event/TargetingEvents.php | 18 +- .../EventListener/IndexSettingsListener.php | 28 + .../PersonalizationBundle/src/Installer.php | 105 +++ .../src/Model/Document/Page.php | 117 +++ .../src/Model/Document/Page/Dao.php | 80 +++ .../src/Model/Document/Snippet.php | 32 + .../src/Model/Document/Snippet/Dao.php | 64 ++ .../TargetingDocumentDaoInterface.php | 2 +- .../Targeting/TargetingDocumentDaoTrait.php | 2 +- .../Targeting/TargetingDocumentInterface.php | 2 +- .../Document/Traits/TargetDocumentTrait.php | 82 ++- .../src/Model}/Tool/Targeting/Rule.php | 4 +- .../src/Model}/Tool/Targeting/Rule/Dao.php | 6 +- .../Model}/Tool/Targeting/Rule/Listing.php | 4 +- .../Tool/Targeting/Rule/Listing/Dao.php | 7 +- .../src/Model}/Tool/Targeting/TargetGroup.php | 10 +- .../Model}/Tool/Targeting/TargetGroup/Dao.php | 4 +- .../Tool/Targeting/TargetGroup/Listing.php | 4 +- .../Targeting/TargetGroup/Listing/Dao.php | 4 +- .../ClassDefinition/Data/TargetGroup.php | 2 +- .../Data/TargetGroupMultiselect.php | 2 +- .../src/PimcorePersonalizationBundle.php | 87 +++ .../src/Resources/install/install.sql | 35 + .../src/Resources/uninstall/uninstall.sql | 3 + .../ActionHandler/ActionHandlerInterface.php | 6 +- .../ActionHandler/AssignTargetGroup.php | 12 +- .../Targeting/ActionHandler/CodeSnippet.php | 6 +- .../ActionHandler/DelegatingActionHandler.php | 10 +- .../src}/Targeting/ActionHandler/Redirect.php | 6 +- ...onseTransformingActionHandlerInterface.php | 4 +- .../Targeting/Code/TargetingCodeGenerator.php | 10 +- .../Condition/AbstractVariableCondition.php | 2 +- .../src}/Targeting/Condition/Browser.php | 8 +- .../Condition/ConditionInterface.php | 4 +- .../src}/Targeting/Condition/Country.php | 8 +- .../EventDispatchingConditionInterface.php | 4 +- .../src}/Targeting/Condition/GeoPoint.php | 10 +- .../Targeting/Condition/HardwarePlatform.php | 8 +- .../src}/Targeting/Condition/Language.php | 6 +- .../Targeting/Condition/OperatingSystem.php | 8 +- .../Targeting/Condition/ReferringSite.php | 4 +- .../src}/Targeting/Condition/SearchEngine.php | 4 +- .../src}/Targeting/Condition/TargetGroup.php | 4 +- .../src}/Targeting/Condition/TimeOnSite.php | 10 +- .../src}/Targeting/Condition/Url.php | 4 +- .../Condition/VariableConditionInterface.php | 2 +- .../Condition/VisitedPagesBefore.php | 12 +- .../src}/Targeting/ConditionFactory.php | 8 +- .../Targeting/ConditionFactoryInterface.php | 4 +- .../src}/Targeting/ConditionMatcher.php | 12 +- .../ConditionMatcher/ExpressionBuilder.php | 2 +- .../Targeting/ConditionMatcherInterface.php | 4 +- .../src}/Targeting/DataLoader.php | 6 +- .../src}/Targeting/DataLoaderInterface.php | 6 +- .../DataProvider/DataProviderInterface.php | 4 +- .../src}/Targeting/DataProvider/Device.php | 6 +- .../src}/Targeting/DataProvider/GeoIp.php | 6 +- .../Targeting/DataProvider/GeoLocation.php | 8 +- .../DataProvider/TargetingStorage.php | 6 +- .../DataProvider/VisitedPagesCounter.php | 6 +- .../DataProviderDependentInterface.php | 2 +- .../src}/Targeting/Debug/Form/DeviceType.php | 2 +- .../Targeting/Debug/Form/LocationType.php | 2 +- .../Debug/Override/DeviceOverrideHandler.php | 8 +- .../DocumentTargetingOverrideHandler.php | 8 +- .../Override/LanguageOverrideHandler.php | 6 +- .../Override/LocationOverrideHandler.php | 8 +- .../src}/Targeting/Debug/OverrideHandler.php | 4 +- .../Debug/TargetingDataCollector.php | 16 +- .../Debug/Util/OverrideAttributeResolver.php | 4 +- .../DocumentTargetingConfigurator.php | 12 +- .../DocumentTargetGroupListener.php | 39 +- .../FullPageCacheCookieCleanupListener.php | 4 +- .../TargetingDocumentRendererListener.php | 55 ++ .../Frontend/TargetingElementListener.php | 102 +++ .../TargetingFullPageCacheListener.php | 81 +++ .../EventListener/TargetingListener.php | 22 +- .../TargetingSessionBagListener.php | 5 +- .../EventListener/ToolbarListener.php | 18 +- .../VisitedPagesCountListener.php | 8 +- .../Maintenance/TargetingStorageTask.php | 6 +- .../src}/Targeting/Model/GeoLocation.php | 2 +- .../Targeting/Model/TargetGroupAssignment.php | 4 +- .../src}/Targeting/Model/VisitorInfo.php | 6 +- .../Targeting/OverrideHandlerInterface.php | 2 +- .../Targeting/Service/VisitedPagesCounter.php | 6 +- .../Cookie/AbstractCookieSaveHandler.php | 2 +- .../Cookie/CookieSaveHandlerInterface.php | 2 +- .../Storage/Cookie/JWTCookieSaveHandler.php | 2 +- .../Storage/Cookie/JsonCookieSaveHandler.php | 2 +- .../src}/Targeting/Storage/CookieStorage.php | 8 +- .../src}/Targeting/Storage/DbStorage.php | 6 +- .../Targeting/Storage/FallbackStorage.php | 4 +- .../Storage/MaintenanceStorageInterface.php | 2 +- .../src}/Targeting/Storage/RedisStorage.php | 6 +- .../src}/Targeting/Storage/SessionStorage.php | 8 +- .../Storage/TargetingStorageInterface.php | 4 +- .../Storage/Traits/TimestampsTrait.php | 2 +- .../src}/Targeting/VisitorInfoResolver.php | 28 +- .../src}/Targeting/VisitorInfoStorage.php | 4 +- .../Targeting/VisitorInfoStorageInterface.php | 4 +- .../templates/Profiler/target.svg.twig | 0 .../targeting_data_collector.html.twig | 10 +- .../Targeting/targetingCode.html.twig | 2 +- .../toolbar/icon/advanced_features.svg.twig | 0 .../Targeting/toolbar/icon/close.svg.twig | 0 .../toolbar/icon/toolbar-collapse.svg.twig | 0 .../Targeting/toolbar/macros.html.twig | 0 .../templates/Targeting/toolbar/toolbar.css | 0 .../Targeting/toolbar/toolbar.html.twig | 14 +- .../templates/Targeting/toolbar/toolbar.scss | 0 .../Targeting/toolbar/toolbar_js.html.twig | 0 bundles/PersonalizationBundle/tests/Readme.md | 8 + .../tests/Support/Data/.gitkeep | 0 .../tests/Support/UnitTester.php | 42 ++ .../tests/Support/_generated/.gitignore | 2 + .../Support/_generated/UnitTesterActions.php | 16 + .../tests/Unit.suite.yml | 5 + .../tests/Unit.suite.yml~ | 5 + .../Unit/Targeting/Condition/GeoPointTest.php | 63 +- .../tests/_bootstrap.php | 40 ++ .../tests/_output/.gitignore | 2 + .../tests/bin/docker-compose.yaml | 33 + .../tests/bin/init-tests.sh | 14 + .../translations/admin.en.yaml | 19 + composer.json | 4 +- .../09_Upgrade_Notes/README.md | 2 + .../AddressSourceAdapter/DefaultAdapter.php | 52 +- lib/Document/Renderer/DocumentRenderer.php | 8 - lib/Event/DocumentEvents.php | 20 + lib/Templating/Renderer/IncludeRenderer.php | 23 +- models/Document/Editable.php | 6 +- models/Document/Editable/Renderlet.php | 12 +- models/Document/Editable/Snippet.php | 16 +- models/Document/Page.php | 88 +-- models/Document/Page/Dao.php | 5 +- models/Document/Snippet.php | 2 +- models/Document/Snippet/Dao.php | 4 +- phpstan-baseline.neon | 10 +- phpstan-parameters.neon | 2 + 261 files changed, 4526 insertions(+), 1576 deletions(-) delete mode 100644 bundles/CoreBundle/config/targeting.yaml delete mode 100644 bundles/CoreBundle/config/targeting/listeners.yaml delete mode 100644 bundles/CoreBundle/config/targeting/services.yaml create mode 100644 bundles/CoreBundle/src/Migrations/Version20230125164101.php create mode 100644 bundles/PersonalizationBundle/.editorconfig create mode 100644 bundles/PersonalizationBundle/.gitattributes create mode 100644 bundles/PersonalizationBundle/.github/ci/files/.env create mode 100644 bundles/PersonalizationBundle/.github/ci/files/.my.cnf create mode 100644 bundles/PersonalizationBundle/.github/ci/files/bin/console create mode 100644 bundles/PersonalizationBundle/.github/ci/files/config/bundles.php create mode 100644 bundles/PersonalizationBundle/.github/ci/files/config/config.yaml create mode 100644 bundles/PersonalizationBundle/.github/ci/files/config/packages/security.yaml create mode 100644 bundles/PersonalizationBundle/.github/ci/files/config/packages/test/config.yaml create mode 100644 bundles/PersonalizationBundle/.github/ci/files/config/services.yaml create mode 100644 bundles/PersonalizationBundle/.github/ci/files/config/system.yaml create mode 100644 bundles/PersonalizationBundle/.github/ci/files/kernel/Kernel.php create mode 100644 bundles/PersonalizationBundle/.github/ci/files/public/.htaccess create mode 100644 bundles/PersonalizationBundle/.github/ci/files/public/index_test.php create mode 100644 bundles/PersonalizationBundle/.github/ci/files/templates/.gitkeep create mode 100755 bundles/PersonalizationBundle/.github/ci/scripts/setup-pimcore-environment.sh create mode 100644 bundles/PersonalizationBundle/.gitignore create mode 100644 bundles/PersonalizationBundle/.php_cs.dist create mode 100644 bundles/PersonalizationBundle/LICENSE.md rename {doc/User_Documentation/08_Targeting_and_Personalization => bundles/PersonalizationBundle}/README.md (58%) create mode 100644 bundles/PersonalizationBundle/SECURITY.md create mode 100644 bundles/PersonalizationBundle/codeception.dist.yml create mode 100644 bundles/PersonalizationBundle/composer.json create mode 100644 bundles/PersonalizationBundle/config/pimcore/config.yaml create mode 100644 bundles/PersonalizationBundle/config/pimcore/default.yaml create mode 100644 bundles/PersonalizationBundle/config/pimcore/routing.yaml create mode 100644 bundles/PersonalizationBundle/config/targeting.yaml create mode 100644 bundles/PersonalizationBundle/config/targeting/listeners.yaml create mode 100644 bundles/PersonalizationBundle/config/targeting/services.yaml rename {doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/Development_Documentation}/01_Visitor_Info.md (93%) rename {doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/Development_Documentation}/03_Conditions.md (81%) rename {doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/Development_Documentation}/05_Data_Providers.md (83%) rename {doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/Development_Documentation}/07_Action_Handlers.md (84%) rename {doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/Development_Documentation}/09_Targeting_Storage.md (91%) rename {doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/Development_Documentation}/11_Frontend_Javascript.md (87%) rename {doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/Development_Documentation}/README.md (98%) rename {doc/User_Documentation/08_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/User_Documentation}/01_Concepts.md (100%) rename {doc/User_Documentation/08_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/User_Documentation}/03_How_to_Personalize_Content/01_Define_Target_Groups.md (100%) rename {doc/User_Documentation/08_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/User_Documentation}/03_How_to_Personalize_Content/03_Visitor_Profiling.md (100%) rename {doc/User_Documentation/08_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/User_Documentation}/03_How_to_Personalize_Content/05_Create_Personalized_Content.md (100%) rename {doc/User_Documentation/08_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/User_Documentation}/03_How_to_Personalize_Content/07_Deliver_Personalized_Content_and_Debug.md (100%) rename {doc/User_Documentation/08_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/User_Documentation}/03_How_to_Personalize_Content/README.md (100%) rename {doc/User_Documentation/08_Targeting_and_Personalization => bundles/PersonalizationBundle/doc/User_Documentation}/05_Examples/README.md (100%) create mode 100644 bundles/PersonalizationBundle/gpl-3.0.txt create mode 100644 bundles/PersonalizationBundle/public/css/icons.css create mode 100644 bundles/PersonalizationBundle/public/css/targeting.css create mode 100644 bundles/PersonalizationBundle/public/js/document/areatoolbar.js create mode 100644 bundles/PersonalizationBundle/public/js/ecommerce/pricing/conditions/targetGroup.js rename bundles/{AdminBundle/public/js/pimcore => PersonalizationBundle/public/js}/object/classes/data/targetGroup.js (100%) rename bundles/{AdminBundle/public/js/pimcore => PersonalizationBundle/public/js}/object/classes/data/targetGroupMultiselect.js (100%) rename bundles/{AdminBundle/public/js/pimcore => PersonalizationBundle/public/js}/object/tags/targetGroup.js (100%) rename bundles/{AdminBundle/public/js/pimcore => PersonalizationBundle/public/js}/object/tags/targetGroupMultiselect.js (100%) rename bundles/{AdminBundle/public/js/pimcore/settings/targeting => PersonalizationBundle/public/js/settings}/action/abstract.js (82%) rename bundles/{AdminBundle/public/js/pimcore/settings/targeting => PersonalizationBundle/public/js/settings}/actions.js (93%) rename bundles/{AdminBundle/public/js/pimcore/settings/targeting => PersonalizationBundle/public/js/settings}/condition/abstract.js (84%) rename bundles/{AdminBundle/public/js/pimcore/settings/targeting => PersonalizationBundle/public/js/settings}/conditions.js (91%) rename bundles/{AdminBundle/public/js/pimcore/settings/targeting => PersonalizationBundle/public/js/settings}/rules/item.js (94%) rename bundles/{AdminBundle/public/js/pimcore/settings/targeting => PersonalizationBundle/public/js/settings}/rules/panel.js (91%) rename bundles/{AdminBundle/public/js/pimcore/settings/targeting => PersonalizationBundle/public/js/settings}/targetGroups/item.js (91%) rename bundles/{AdminBundle/public/js/pimcore/settings/targeting => PersonalizationBundle/public/js/settings}/targetGroups/panel.js (90%) rename bundles/{AdminBundle/public/js/pimcore/settings/targeting_toolbar.js => PersonalizationBundle/public/js/settings/targetingtoolbar.js} (92%) create mode 100644 bundles/PersonalizationBundle/public/js/startup.js rename bundles/{CoreBundle => PersonalizationBundle}/public/js/targeting.js (100%) rename bundles/{AdminBundle => PersonalizationBundle}/src/Controller/Admin/TargetingController.php (85%) create mode 100644 bundles/PersonalizationBundle/src/Controller/Admin/TargetingPageController.php create mode 100644 bundles/PersonalizationBundle/src/Controller/Admin/TargetingSnippetController.php rename bundles/{CoreBundle => PersonalizationBundle}/src/DataCollector/PimcoreTargetingDataCollector.php (88%) rename bundles/{CoreBundle => PersonalizationBundle}/src/DependencyInjection/Compiler/DebugStopwatchPass.php (83%) rename bundles/{CoreBundle => PersonalizationBundle}/src/DependencyInjection/Compiler/TargetingOverrideHandlersPass.php (79%) create mode 100644 bundles/PersonalizationBundle/src/DependencyInjection/Configuration.php create mode 100644 bundles/PersonalizationBundle/src/DependencyInjection/PimcorePersonalizationExtension.php create mode 100644 bundles/PersonalizationBundle/src/Document/Newsletter/AddressSourceAdapter/DefaultAdapter.php rename bundles/{EcommerceFrameworkBundle/src => PersonalizationBundle/src/Ecommerce}/PricingManager/Condition/TargetGroup.php (81%) rename {lib => bundles/PersonalizationBundle/src}/Event/Model/TargetGroupEvent.php (90%) rename {lib => bundles/PersonalizationBundle/src}/Event/TargetGroupEvents.php (72%) rename {lib => bundles/PersonalizationBundle/src}/Event/Targeting/AssignDocumentTargetGroupEvent.php (83%) rename {lib => bundles/PersonalizationBundle/src}/Event/Targeting/BuildConditionEvent.php (90%) rename {lib => bundles/PersonalizationBundle/src}/Event/Targeting/OverrideEvent.php (93%) rename {lib => bundles/PersonalizationBundle/src}/Event/Targeting/RenderToolbarEvent.php (94%) rename {lib => bundles/PersonalizationBundle/src}/Event/Targeting/TargetingCodeEvent.php (96%) rename {lib => bundles/PersonalizationBundle/src}/Event/Targeting/TargetingEvent.php (87%) rename {lib => bundles/PersonalizationBundle/src}/Event/Targeting/TargetingResolveVisitorInfoEvent.php (82%) rename {lib => bundles/PersonalizationBundle/src}/Event/Targeting/TargetingRuleEvent.php (79%) rename {lib => bundles/PersonalizationBundle/src}/Event/TargetingEvents.php (77%) create mode 100644 bundles/PersonalizationBundle/src/EventListener/IndexSettingsListener.php create mode 100644 bundles/PersonalizationBundle/src/Installer.php create mode 100644 bundles/PersonalizationBundle/src/Model/Document/Page.php create mode 100644 bundles/PersonalizationBundle/src/Model/Document/Page/Dao.php create mode 100644 bundles/PersonalizationBundle/src/Model/Document/Snippet.php create mode 100644 bundles/PersonalizationBundle/src/Model/Document/Snippet/Dao.php rename {models => bundles/PersonalizationBundle/src/Model}/Document/Targeting/TargetingDocumentDaoInterface.php (91%) rename {models => bundles/PersonalizationBundle/src/Model}/Document/Targeting/TargetingDocumentDaoTrait.php (95%) rename {models => bundles/PersonalizationBundle/src/Model}/Document/Targeting/TargetingDocumentInterface.php (96%) rename models/Document/TargetingDocument.php => bundles/PersonalizationBundle/src/Model/Document/Traits/TargetDocumentTrait.php (52%) rename {models => bundles/PersonalizationBundle/src/Model}/Tool/Targeting/Rule.php (97%) rename {models => bundles/PersonalizationBundle/src/Model}/Tool/Targeting/Rule/Dao.php (94%) rename {models => bundles/PersonalizationBundle/src/Model}/Tool/Targeting/Rule/Listing.php (87%) rename {models => bundles/PersonalizationBundle/src/Model}/Tool/Targeting/Rule/Listing/Dao.php (83%) rename {models => bundles/PersonalizationBundle/src/Model}/Tool/Targeting/TargetGroup.php (90%) rename {models => bundles/PersonalizationBundle/src/Model}/Tool/Targeting/TargetGroup/Dao.php (95%) rename {models => bundles/PersonalizationBundle/src/Model}/Tool/Targeting/TargetGroup/Listing.php (86%) rename {models => bundles/PersonalizationBundle/src/Model}/Tool/Targeting/TargetGroup/Listing/Dao.php (89%) rename {models => bundles/PersonalizationBundle/src/Pimcore/Model}/DataObject/ClassDefinition/Data/TargetGroup.php (98%) rename {models => bundles/PersonalizationBundle/src/Pimcore/Model}/DataObject/ClassDefinition/Data/TargetGroupMultiselect.php (97%) create mode 100644 bundles/PersonalizationBundle/src/PimcorePersonalizationBundle.php create mode 100644 bundles/PersonalizationBundle/src/Resources/install/install.sql create mode 100644 bundles/PersonalizationBundle/src/Resources/uninstall/uninstall.sql rename {lib => bundles/PersonalizationBundle/src}/Targeting/ActionHandler/ActionHandlerInterface.php (75%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/ActionHandler/AssignTargetGroup.php (89%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/ActionHandler/CodeSnippet.php (89%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/ActionHandler/DelegatingActionHandler.php (85%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/ActionHandler/Redirect.php (90%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/ActionHandler/ResponseTransformingActionHandlerInterface.php (84%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Code/TargetingCodeGenerator.php (87%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/AbstractVariableCondition.php (93%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/Browser.php (86%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/ConditionInterface.php (89%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/Country.php (84%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/EventDispatchingConditionInterface.php (86%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/GeoPoint.php (87%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/HardwarePlatform.php (89%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/Language.php (90%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/OperatingSystem.php (88%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/ReferringSite.php (91%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/SearchEngine.php (94%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/TargetGroup.php (91%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/TimeOnSite.php (84%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/Url.php (91%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/VariableConditionInterface.php (94%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Condition/VisitedPagesBefore.php (82%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/ConditionFactory.php (90%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/ConditionFactoryInterface.php (84%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/ConditionMatcher.php (90%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/ConditionMatcher/ExpressionBuilder.php (95%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/ConditionMatcherInterface.php (88%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/DataLoader.php (92%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/DataLoaderInterface.php (82%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/DataProvider/DataProviderInterface.php (81%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/DataProvider/Device.php (95%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/DataProvider/GeoIp.php (94%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/DataProvider/GeoLocation.php (93%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/DataProvider/TargetingStorage.php (79%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/DataProvider/VisitedPagesCounter.php (78%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/DataProviderDependentInterface.php (93%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Debug/Form/DeviceType.php (96%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Debug/Form/LocationType.php (94%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Debug/Override/DeviceOverrideHandler.php (79%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Debug/Override/DocumentTargetingOverrideHandler.php (86%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Debug/Override/LanguageOverrideHandler.php (83%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Debug/Override/LocationOverrideHandler.php (80%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Debug/OverrideHandler.php (94%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Debug/TargetingDataCollector.php (89%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Debug/Util/OverrideAttributeResolver.php (89%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Document/DocumentTargetingConfigurator.php (94%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/EventListener/DocumentTargetGroupListener.php (65%) rename {lib/Targeting/EventListener => bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend}/FullPageCacheCookieCleanupListener.php (91%) create mode 100644 bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/TargetingDocumentRendererListener.php create mode 100644 bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/TargetingElementListener.php create mode 100644 bundles/PersonalizationBundle/src/Targeting/EventListener/TargetingFullPageCacheListener.php rename {lib => bundles/PersonalizationBundle/src}/Targeting/EventListener/TargetingListener.php (90%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/EventListener/TargetingSessionBagListener.php (95%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/EventListener/ToolbarListener.php (89%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/EventListener/VisitedPagesCountListener.php (87%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Maintenance/TargetingStorageTask.php (79%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Model/GeoLocation.php (96%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Model/TargetGroupAssignment.php (89%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Model/VisitorInfo.php (97%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/OverrideHandlerInterface.php (95%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Service/VisitedPagesCounter.php (88%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/Cookie/AbstractCookieSaveHandler.php (97%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/Cookie/CookieSaveHandlerInterface.php (92%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/Cookie/JWTCookieSaveHandler.php (98%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/Cookie/JsonCookieSaveHandler.php (94%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/CookieStorage.php (95%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/DbStorage.php (98%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/FallbackStorage.php (97%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/MaintenanceStorageInterface.php (91%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/RedisStorage.php (96%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/SessionStorage.php (95%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/TargetingStorageInterface.php (93%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/Storage/Traits/TimestampsTrait.php (93%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/VisitorInfoResolver.php (90%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/VisitorInfoStorage.php (87%) rename {lib => bundles/PersonalizationBundle/src}/Targeting/VisitorInfoStorageInterface.php (86%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Profiler/target.svg.twig (100%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Profiler/targeting_data_collector.html.twig (92%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Targeting/targetingCode.html.twig (88%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Targeting/toolbar/icon/advanced_features.svg.twig (100%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Targeting/toolbar/icon/close.svg.twig (100%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Targeting/toolbar/icon/toolbar-collapse.svg.twig (100%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Targeting/toolbar/macros.html.twig (100%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Targeting/toolbar/toolbar.css (100%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Targeting/toolbar/toolbar.html.twig (95%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Targeting/toolbar/toolbar.scss (100%) rename bundles/{CoreBundle => PersonalizationBundle}/templates/Targeting/toolbar/toolbar_js.html.twig (100%) create mode 100644 bundles/PersonalizationBundle/tests/Readme.md create mode 100644 bundles/PersonalizationBundle/tests/Support/Data/.gitkeep create mode 100644 bundles/PersonalizationBundle/tests/Support/UnitTester.php create mode 100644 bundles/PersonalizationBundle/tests/Support/_generated/.gitignore create mode 100644 bundles/PersonalizationBundle/tests/Support/_generated/UnitTesterActions.php create mode 100644 bundles/PersonalizationBundle/tests/Unit.suite.yml create mode 100644 bundles/PersonalizationBundle/tests/Unit.suite.yml~ rename {tests => bundles/PersonalizationBundle/tests}/Unit/Targeting/Condition/GeoPointTest.php (58%) mode change 100644 => 100755 create mode 100644 bundles/PersonalizationBundle/tests/_bootstrap.php create mode 100644 bundles/PersonalizationBundle/tests/_output/.gitignore create mode 100644 bundles/PersonalizationBundle/tests/bin/docker-compose.yaml create mode 100755 bundles/PersonalizationBundle/tests/bin/init-tests.sh create mode 100644 bundles/PersonalizationBundle/translations/admin.en.yaml diff --git a/bundles/AdminBundle/public/css/admin.css b/bundles/AdminBundle/public/css/admin.css index eb805cfc2ee..c3ed28cbd4a 100644 --- a/bundles/AdminBundle/public/css/admin.css +++ b/bundles/AdminBundle/public/css/admin.css @@ -869,32 +869,6 @@ span.warning { background: url(/bundles/pimcoreadmin/img/flat-color-icons/high_priority.svg) 2px 2px/16px no-repeat #ffdbdb; } -.pimcore_targeting_bracket { - position: absolute; - top: 64px; - cursor: pointer; - - color: #CCCCCC; - font-family: sans-serif; - font-size: 50px; -} - -.pimcore_targeting_bracket:hover { - color: #B4B4B4; -} - -.pimcore_targeting_bracket_active { - color: #000 !important; -} - -.pimcore_targeting_bracket_left { - left: 5px; -} - -.pimcore_targeting_bracket_right { - right: 5px; -} - #pimcore_tree_preview { position:fixed; top:0; diff --git a/bundles/AdminBundle/public/css/icons.css b/bundles/AdminBundle/public/css/icons.css index cfba6a3d7ee..9b4028ad277 100644 --- a/bundles/AdminBundle/public/css/icons.css +++ b/bundles/AdminBundle/public/css/icons.css @@ -275,18 +275,6 @@ background: url(/bundles/pimcoreadmin/img/flat-white-icons/targetgroup.svg) center center no-repeat !important; } -.pimcore_nav_icon_targeting { - background: url(/bundles/pimcoreadmin/img/flat-white-icons/person.svg) center center no-repeat !important; -} - -.pimcore_nav_icon_target_groups { - background: url(/bundles/pimcoreadmin/img/flat-white-icons/targetgroup.svg) center center no-repeat !important; -} - -.pimcore_nav_icon_targeting_toolbar { - background: url(/bundles/pimcoreadmin/img/flat-white-icons/ok.svg) center center no-repeat !important; -} - .pimcore_nav_icon_marketing_settings { background: url(/bundles/pimcoreadmin/img/flat-white-icons/settings.svg) center center no-repeat !important; } @@ -794,10 +782,6 @@ background: url(/bundles/pimcoreadmin/img/flat-color-icons/settings.svg) center center no-repeat !important; } -.pimcore_icon_targeting { - background: url(/bundles/pimcoreadmin/img/flat-color-icons/person.svg) center center no-repeat !important; -} - .pimcore_icon_versions { background: url(/bundles/pimcoreadmin/img/flat-color-icons/org_unit.svg) center center no-repeat !important; } @@ -978,18 +962,6 @@ background: url(/bundles/pimcoreadmin/img/flat-color-icons/stop-circle.svg) center center no-repeat !important; } -.pimcore_icon_targeting_toolbar_enable { - background: url(/bundles/pimcoreadmin/img/flat-color-icons/ok.svg) center center no-repeat !important; -} - -.pimcore_icon_targeting_toolbar_disable { - background: url(/bundles/pimcoreadmin/img/flat-color-icons/stop-circle.svg) center center no-repeat !important; -} - -.pimcore_icon_targeting_toolbar { - background: url(/bundles/pimcoreadmin/img/flat-color-icons/list.svg) center center no-repeat !important; -} - .pimcore_icon_info { background: url(/bundles/pimcoreadmin/img/flat-color-icons/info.svg) center center no-repeat !important; } diff --git a/bundles/AdminBundle/public/js/pimcore/document/document_language_overview.js b/bundles/AdminBundle/public/js/pimcore/document/document_language_overview.js index a49bc20db0b..16de8fae5fc 100644 --- a/bundles/AdminBundle/public/js/pimcore/document/document_language_overview.js +++ b/bundles/AdminBundle/public/js/pimcore/document/document_language_overview.js @@ -192,7 +192,7 @@ pimcore.document.document_language_overview = Class.create({ parameters.id = id; Ext.Ajax.request({ - url: '/admin/' + type + '/save?task=' + task, + url: Routing.generate('pimcore_admin_document_' + type + '_save', {task: task}), method: "PUT", params: parameters, success: function (task, response) { diff --git a/bundles/AdminBundle/public/js/pimcore/document/edit.js b/bundles/AdminBundle/public/js/pimcore/document/edit.js index 55af175e2cf..19497975dbf 100644 --- a/bundles/AdminBundle/public/js/pimcore/document/edit.js +++ b/bundles/AdminBundle/public/js/pimcore/document/edit.js @@ -31,8 +31,10 @@ pimcore.document.edit = Class.create({ link += "&unminified_js"; } - if(this.targetGroup && this.targetGroup.getValue()) { - link += "&_ptg=" + this.targetGroup.getValue(); + if (pimcore.bundle.personalization) { + if (this.areaToolBar && this.areaToolBar.targetGroup && this.areaToolBar.targetGroup.getValue()) { + link += "&_ptg=" + this.areaToolBar.targetGroup.getValue(); + } } return link; @@ -53,7 +55,6 @@ pimcore.document.edit = Class.create({ url: Routing.generate('pimcore_admin_document_page_cleareditabledata'), method: "PUT", params: { - targetGroup: this["targetGroup"] ? this.targetGroup.getValue() : "", id: this.document.id }, success: function () { @@ -100,7 +101,9 @@ pimcore.document.edit = Class.create({ handler: cleanupFunction.bind(this) }]; - this.addTargetingPanel(lbar, cleanupFunction); + if (pimcore.bundle.personalization) { + this.areaToolBar = new pimcore.bundle.personalization.document.areatoolbar(this.document, lbar); + } // edit panel configuration var config = { @@ -189,91 +192,6 @@ pimcore.document.edit = Class.create({ this.highlightTagButton.toggle(this.tagHighlightingActive); }, - addTargetingPanel: function(lbar, cleanupFunction) { - if (!Ext.Array.contains(['page', 'snippet'], this.document.getType())) { - return; - } - - if (pimcore.globalmanager.get("target_group_store").getCount() === 0) { - return; - } - - this.targetGroupText = Ext.create('Ext.toolbar.TextItem', { - scale: "medium", - style: "-webkit-transform: rotate(270deg); -moz-transform: rotate(270deg); -o-transform: rotate(270deg); writing-mode: lr-tb;" - }); - - this.targetGroupStore = Ext.create('Ext.data.JsonStore', { - proxy: { - type: 'ajax', - url: Routing.generate('pimcore_admin_targeting_targetgrouplist', {'add-default': true}) - }, - fields: ["id", "text"], - listeners: { - load: function() { - this.updateTargetGroupText(this.targetGroup.getValue()); - }.bind(this) - } - }); - - // add target group selection to toolbar - this.targetGroup = new Ext.form.ComboBox({ - displayField:'text', - valueField: "id", - store: this.targetGroupStore, - editable: false, - triggerAction: 'all', - width: 240, - listeners: { - select: function (el) { - if(this.document.isDirty()) { - Ext.Msg.confirm(t('warning'), t('you_have_unsaved_changes') - + "
" + t("continue") + "?", - function(btn){ - if (btn === 'yes'){ - this.reload(true); - this.updateTargetGroupText(this.targetGroup.getValue()); - } - }.bind(this) - ); - } else { - this.reload(true); - this.updateTargetGroupText(this.targetGroup.getValue()); - } - }.bind(this) - } - }); - - this.targetGroupStore.load(); - - lbar.push("->", - this.targetGroupText, - { - tooltip: t("edit_content_for_target_group"), - iconCls: "pimcore_icon_target_groups", - arrowVisible: false, - menuAlign: "tl", - menu: [this.targetGroup] - }, - { - tooltip: t("clear_content_of_selected_target_group"), - iconCls: "pimcore_icon_cleanup", - handler: cleanupFunction.bind(this) - } - ); - }, - - updateTargetGroupText: function(targetgroup) { - var record = this.targetGroupStore.getById(targetgroup); - - if(record) { - this.targetGroupText.update('    ' - + record.data.text); - } else { - this.targetGroupText.update(''); - } - }, - setLayoutFrameDimensions: function (el, width, height, rWidth, rHeight) { Ext.get(this.iframeName).setStyle({ height: (height-7) + "px" @@ -305,7 +223,6 @@ pimcore.document.edit = Class.create({ }, reload: function (disableSaveToSession) { - this.areaToolbarTrigger.toggle(false); if (this.reloadInProgress) { diff --git a/bundles/AdminBundle/public/js/pimcore/document/newsletters/addressSourceAdapters/default.js b/bundles/AdminBundle/public/js/pimcore/document/newsletters/addressSourceAdapters/default.js index 9299671f433..4ba22e8b2e8 100644 --- a/bundles/AdminBundle/public/js/pimcore/document/newsletters/addressSourceAdapters/default.js +++ b/bundles/AdminBundle/public/js/pimcore/document/newsletters/addressSourceAdapters/default.js @@ -111,7 +111,7 @@ pimcore.document.newsletters.addressSourceAdapters.default = Class.create({ },{ fieldLabel: t('assign_target_group'), xtype: "multiselect", - hidden: pimcore.globalmanager.get("target_group_store").getCount() < 1, + hidden: !pimcore.globalmanager.get("target_group_store"), store: pimcore.globalmanager.get("target_group_store"), displayField: "text", valueField: "id", diff --git a/bundles/AdminBundle/public/js/pimcore/document/pages/settings.js b/bundles/AdminBundle/public/js/pimcore/document/pages/settings.js index 69e9598ad42..c95f65e24bb 100644 --- a/bundles/AdminBundle/public/js/pimcore/document/pages/settings.js +++ b/bundles/AdminBundle/public/js/pimcore/document/pages/settings.js @@ -124,7 +124,6 @@ pimcore.document.pages.settings = Class.create(pimcore.document.settings_abstrac var serpAbsoluteUrl = this.document.data.url; // create layout - this.layout = new Ext.FormPanel({ title: t('SEO') + ' & ' + t('settings'), border: false, @@ -245,39 +244,28 @@ pimcore.document.pages.settings = Class.create(pimcore.document.settings_abstrac } } ] - }, { - xtype:'fieldset', - title: t('assign_target_groups'), - collapsible: true, - autoHeight:true, - defaults: { - labelWidth: 300 - }, - defaultType: 'textfield', - items :[ - Ext.create('Ext.ux.form.MultiSelect', { - fieldLabel: t('visitors_of_this_page_will_be_automatically_associated_with_the_selected_target_groups'), - store: pimcore.globalmanager.get("target_group_store"), - displayField: "text", - valueField: "id", - name: 'targetGroupIds', - width: 700, - //listWidth: 200, - value: this.document.data["targetGroupIds"].split(',').map(Number).filter(item => item), - minHeight: 100 - }) - ] }, - this.getControllerViewFields(true), - this.getStaticGeneratorFields(true), - this.getPathAndKeyFields(true), - this.getContentMasterFields(true) ] + }); + // To add additional block to settings + const additionalSettings = new CustomEvent(pimcore.events.prepareDocumentPageSettingsLayout, { + detail: { + layout: this.layout, + document: this.document + } }); + document.dispatchEvent(additionalSettings); + + this.layout.add(this.getControllerViewFields(true)); + this.layout.add(this.getStaticGeneratorFields(true)); + this.layout.add(this.getPathAndKeyFields(true)); + this.layout.add(this.getContentMasterFields(true)); } return this.layout; } + + }); diff --git a/bundles/AdminBundle/public/js/pimcore/document/tree.js b/bundles/AdminBundle/public/js/pimcore/document/tree.js index 18ede5cd79a..33f2c28951f 100644 --- a/bundles/AdminBundle/public/js/pimcore/document/tree.js +++ b/bundles/AdminBundle/public/js/pimcore/document/tree.js @@ -1484,7 +1484,7 @@ pimcore.document.tree = Class.create({ parameters.id = id; Ext.Ajax.request({ - url: '/admin/' + type + '/save?task=' + task, + url: Routing.generate('pimcore_admin_document_' + type + '_save', {task: task}), method: "PUT", params: parameters, success: function (task, response) { diff --git a/bundles/AdminBundle/public/js/pimcore/events.js b/bundles/AdminBundle/public/js/pimcore/events.js index ef40979d02d..b5ef831bb75 100644 --- a/bundles/AdminBundle/public/js/pimcore/events.js +++ b/bundles/AdminBundle/public/js/pimcore/events.js @@ -241,3 +241,9 @@ */ pimcore.events.preMenuBuild = "pimcore.menu.preBuild"; +/** + * after settings tab of page is opened + * layout and document are passed as parameter + */ +pimcore.events.prepareDocumentPageSettingsLayout = "pimcore.documentPageSettingsLayout.prepare"; + diff --git a/bundles/AdminBundle/public/js/pimcore/layout/toolbar.js b/bundles/AdminBundle/public/js/pimcore/layout/toolbar.js index de52d42a576..45e1a7fa793 100644 --- a/bundles/AdminBundle/public/js/pimcore/layout/toolbar.js +++ b/bundles/AdminBundle/public/js/pimcore/layout/toolbar.js @@ -422,42 +422,11 @@ pimcore.layout.toolbar = Class.create({ cls: "pimcore_navigation_flyout" }; } - + if (perspectiveCfg.inToolbar("marketing")) { // marketing menu var marketingItems = []; - if (user.isAllowed("targeting") && perspectiveCfg.inToolbar("marketing.targeting")) { - marketingItems.push({ - text: t("personalization") + " / " + t("targeting"), - iconCls: "pimcore_nav_icon_usergroup", - itemId: 'pimcore_menu_marketing_personalization', - hideOnClick: false, - menu: { - cls: "pimcore_navigation_flyout", - shadow: false, - items: [ - { - text: t("global_targeting_rules"), - iconCls: "pimcore_nav_icon_targeting", - itemId: 'pimcore_menu_marketing_personalization_global_targeting_rules', - handler: this.showTargetingRules - }, { - text: t('target_groups'), - iconCls: "pimcore_nav_icon_target_groups", - itemId: 'pimcore_menu_marketing_personalization_target_groups', - handler: this.showTargetGroups - }, { - text: t("targeting_toolbar"), - iconCls: "pimcore_nav_icon_targeting_toolbar", - itemId: 'pimcore_menu_marketing_personalization_targeting_toolbar', - handler: this.showTargetingToolbarSettings - } - ] - } - }); - } - menu.marketing = { label: t('marketing'), iconCls: 'pimcore_main_nav_icon_marketing', @@ -1162,50 +1131,6 @@ pimcore.layout.toolbar = Class.create({ pimcore.helpers.sendTestEmail(pimcore.settings.mailDefaultAddress); }, - showTargetingRules: function () { - var tabPanel = Ext.getCmp("pimcore_panel_tabs"); - try { - tabPanel.setActiveTab(pimcore.globalmanager.get("targeting").getLayout()); - } - catch (e) { - var targeting = new pimcore.settings.targeting.rules.panel(); - pimcore.globalmanager.add("targeting", targeting); - - tabPanel.add(targeting.getLayout()); - tabPanel.setActiveTab(targeting.getLayout()); - - targeting.getLayout().on("destroy", function () { - pimcore.globalmanager.remove("targeting"); - }.bind(this)); - - pimcore.layout.refresh(); - } - }, - - showTargetGroups: function () { - var tabPanel = Ext.getCmp("pimcore_panel_tabs"); - try { - tabPanel.setActiveTab(pimcore.globalmanager.get("targetGroupsPanel").getLayout()); - } - catch (e) { - var targetGroups = new pimcore.settings.targeting.targetGroups.panel(); - pimcore.globalmanager.add("targetGroupsPanel", targetGroups); - - tabPanel.add(targetGroups.getLayout()); - tabPanel.setActiveTab(targetGroups.getLayout()); - - targetGroups.getLayout().on("destroy", function () { - pimcore.globalmanager.remove("targetGroupsPanel"); - }.bind(this)); - - pimcore.layout.refresh(); - } - }, - - showTargetingToolbarSettings: function () { - new pimcore.settings.targetingToolbar(); - }, - notes: function () { try { pimcore.globalmanager.get("notes").activate(); diff --git a/bundles/AdminBundle/public/js/pimcore/startup.js b/bundles/AdminBundle/public/js/pimcore/startup.js index c1b53b479b4..a89a9a8fece 100644 --- a/bundles/AdminBundle/public/js/pimcore/startup.js +++ b/bundles/AdminBundle/public/js/pimcore/startup.js @@ -499,27 +499,6 @@ Ext.onReady(function () { sitesStore.load(); pimcore.globalmanager.add("sites", sitesStore); - // target groups - Ext.define('pimcore.model.target_groups', { - extend: 'Ext.data.Model', - fields: ["id", "text"] - }); - - var targetGroupStore = Ext.create('Ext.data.JsonStore', { - model: "pimcore.model.target_groups", - proxy: { - type: 'ajax', - url: Routing.generate('pimcore_admin_targeting_targetgrouplist'), - reader: { - type: 'json' - } - } - }); - - targetGroupStore.load(); - pimcore.globalmanager.add("target_group_store", targetGroupStore); - - // check for updates window.setTimeout(function () { diff --git a/bundles/AdminBundle/src/Controller/Admin/Document/DocumentControllerBase.php b/bundles/AdminBundle/src/Controller/Admin/Document/DocumentControllerBase.php index bda5320e183..10bda5c5eed 100644 --- a/bundles/AdminBundle/src/Controller/Admin/Document/DocumentControllerBase.php +++ b/bundles/AdminBundle/src/Controller/Admin/Document/DocumentControllerBase.php @@ -26,7 +26,6 @@ use Pimcore\Logger; use Pimcore\Model; use Pimcore\Model\Document; -use Pimcore\Model\Document\Targeting\TargetingDocumentInterface; use Pimcore\Model\Element; use Pimcore\Model\Property; use Pimcore\Model\Version; @@ -167,7 +166,8 @@ protected function addDataToDocument(Request $request, Model\Document $document) { if ($document instanceof Model\Document\PageSnippet) { // if a target group variant get's saved, we have to load all other editables first, otherwise they will get deleted - if ($request->get('appendEditables') || ($document instanceof TargetingDocumentInterface && $document->hasTargetGroupSpecificEditables())) { + + if ($request->get('appendEditables')) { // ensure editable are loaded $document->getEditables(); } else { diff --git a/bundles/AdminBundle/src/Controller/Admin/Document/PageController.php b/bundles/AdminBundle/src/Controller/Admin/Document/PageController.php index 99d4c379269..8371cda040b 100644 --- a/bundles/AdminBundle/src/Controller/Admin/Document/PageController.php +++ b/bundles/AdminBundle/src/Controller/Admin/Document/PageController.php @@ -26,7 +26,6 @@ use Pimcore\Localization\LocaleService; use Pimcore\Messenger\GeneratePagePreviewMessage; use Pimcore\Model\Document; -use Pimcore\Model\Document\Targeting\TargetingDocumentInterface; use Pimcore\Model\Element; use Pimcore\Model\Redirect; use Pimcore\Model\Schedule\Task; @@ -332,9 +331,7 @@ public function checkPrettyUrlAction(Request $request): JsonResponse */ public function clearEditableDataAction(Request $request): JsonResponse { - $targetGroupId = $request->request->get('targetGroup'); $docId = $request->request->getInt('id'); - $doc = Document\PageSnippet::getById($docId); if (!$doc) { @@ -342,16 +339,10 @@ public function clearEditableDataAction(Request $request): JsonResponse } foreach ($doc->getEditables() as $editable) { - if ($targetGroupId && $doc instanceof TargetingDocumentInterface) { - // remove target group specific elements - if (preg_match('/^' . preg_quote($doc->getTargetGroupEditablePrefix($targetGroupId), '/') . '/', $editable->getName())) { - $doc->removeEditable($editable->getName()); - } - } else { - // remove all but target group data - if (!preg_match('/^' . preg_quote(TargetingDocumentInterface::TARGET_GROUP_EDITABLE_PREFIX, '/') . '/', $editable->getName())) { - $doc->removeEditable($editable->getName()); - } + // remove all but target group data + // Hardcoded the TARGET_GROUP_EDITABLE_PREFIX prefix here as we shouldn't remove the bundle specific editables even if bundle is not enabled/installed + if (!preg_match ('/^' . preg_quote ('persona_ -', '/') . '/', $editable->getName ())) { + $doc->removeEditable ($editable->getName ()); } } diff --git a/bundles/AdminBundle/src/Controller/Admin/Document/RenderletController.php b/bundles/AdminBundle/src/Controller/Admin/Document/RenderletController.php index e6e4be808b1..8a69131d734 100644 --- a/bundles/AdminBundle/src/Controller/Admin/Document/RenderletController.php +++ b/bundles/AdminBundle/src/Controller/Admin/Document/RenderletController.php @@ -19,16 +19,18 @@ use Pimcore\Bundle\AdminBundle\Controller\AdminController; use Pimcore\Document\Editable\EditableHandler; +use Pimcore\Event\DocumentEvents; use Pimcore\Localization\LocaleServiceInterface; use Pimcore\Model\Document; use Pimcore\Model\Element\ElementInterface; use Pimcore\Model\Element\Service; -use Pimcore\Model\Tool\Targeting\TargetGroup; use Pimcore\Templating\Renderer\ActionRenderer; use Symfony\Cmf\Bundle\RoutingBundle\Routing\DynamicRouter; +use Symfony\Component\EventDispatcher\GenericEvent; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** * @internal @@ -51,7 +53,8 @@ public function renderletAction( Request $request, ActionRenderer $actionRenderer, EditableHandler $editableHandler, - LocaleServiceInterface $localeService + LocaleServiceInterface $localeService, + EventDispatcherInterface $eventDispatcher ): Response { $query = $request->query->all(); $attributes = []; @@ -59,8 +62,11 @@ public function renderletAction( // load element to make sure the request is valid $element = $this->loadElement($request); - // apply targeting to element - $this->configureElementTargeting($request, $element); + $event = new GenericEvent($this, [ + 'requestParams' => array_merge($request->request->all(), $request->query->all()), + 'element' => $element, + ]); + $eventDispatcher->dispatch($event, DocumentEvents::EDITABLE_RENDERLET_PRE_RENDER); $controller = $request->get('controller'); $action = $request->get('action'); @@ -124,19 +130,4 @@ private function loadElement(Request $request): ElementInterface return $element; } - - private function configureElementTargeting(Request $request, ElementInterface $element): void - { - if (!$element instanceof Document\Targeting\TargetingDocumentInterface) { - return; - } - - // set selected target group on element - if ($request->get('_ptg')) { - $targetGroup = TargetGroup::getById((int)$request->get('_ptg')); - if ($targetGroup) { - $element->setUseTargetGroup($targetGroup->getId()); - } - } - } } diff --git a/bundles/AdminBundle/src/Controller/Admin/IndexController.php b/bundles/AdminBundle/src/Controller/Admin/IndexController.php index 5d84b17b095..8a760a33462 100644 --- a/bundles/AdminBundle/src/Controller/Admin/IndexController.php +++ b/bundles/AdminBundle/src/Controller/Admin/IndexController.php @@ -226,7 +226,6 @@ protected function buildPimcoreSettings(Request $request, array &$templateParams 'asset_tree_paging_limit' => $config['assets']['tree_paging_limit'], 'document_tree_paging_limit' => $config['documents']['tree_paging_limit'], 'object_tree_paging_limit' => $config['objects']['tree_paging_limit'], - 'maxmind_geoip_installed' => (bool) $this->getParameter('pimcore.geoip.db_file'), 'hostname' => htmlentities(\Pimcore\Tool::getHostname(), ENT_QUOTES, 'UTF-8'), 'document_auto_save_interval' => $config['documents']['auto_save_interval'], diff --git a/bundles/AdminBundle/templates/admin/index/index.html.twig b/bundles/AdminBundle/templates/admin/index/index.html.twig index 508e52f00bd..60cac2333a4 100644 --- a/bundles/AdminBundle/templates/admin/index/index.html.twig +++ b/bundles/AdminBundle/templates/admin/index/index.html.twig @@ -257,15 +257,6 @@ "pimcore/settings/maintenance.js", "pimcore/settings/email/log.js", "pimcore/settings/email/blacklist.js", - "pimcore/settings/targeting/condition/abstract.js", - "pimcore/settings/targeting/conditions.js", - "pimcore/settings/targeting/action/abstract.js", - "pimcore/settings/targeting/actions.js", - "pimcore/settings/targeting/rules/panel.js", - "pimcore/settings/targeting/rules/item.js", - "pimcore/settings/targeting/targetGroups/panel.js", - "pimcore/settings/targeting/targetGroups/item.js", - "pimcore/settings/targeting_toolbar.js", "pimcore/settings/gdpr/gdprPanel.js", "pimcore/settings/gdpr/dataproviders/assets.js", @@ -442,8 +433,6 @@ "pimcore/object/classes/data/gender.js", "pimcore/object/classes/data/newsletterActive.js", "pimcore/object/classes/data/newsletterConfirmed.js", - "pimcore/object/classes/data/targetGroup.js", - "pimcore/object/classes/data/targetGroupMultiselect.js", "pimcore/object/classes/data/quantityValue.js", "pimcore/object/classes/data/inputQuantityValue.js", "pimcore/object/classes/data/quantityValueRange.js", @@ -568,8 +557,6 @@ "pimcore/object/tags/gender.js", "pimcore/object/tags/newsletterActive.js", "pimcore/object/tags/newsletterConfirmed.js", - "pimcore/object/tags/targetGroup.js", - "pimcore/object/tags/targetGroupMultiselect.js", "pimcore/object/tags/quantityValue.js", "pimcore/object/tags/quantityValueRange.js", "pimcore/object/tags/inputQuantityValue.js", diff --git a/bundles/AdminBundle/translations/admin.en.yaml b/bundles/AdminBundle/translations/admin.en.yaml index 7b5f4494b2b..0554ec3186d 100644 --- a/bundles/AdminBundle/translations/admin.en.yaml +++ b/bundles/AdminBundle/translations/admin.en.yaml @@ -28,9 +28,6 @@ clear_content_of_current_view: 'Clear content of current view' highlight_editable_elements: 'Highlight editable elements' continue: Continue you_have_unsaved_changes: 'You have unsaved changes.' -global_targeting_rule: 'Global Targeting Rule' -global_targeting_rules: 'Global Targeting Rules' -personalization: Personalization shared_translations: 'Shared Translations' textfield: Textfield add_data: 'Add data' @@ -63,7 +60,6 @@ tablet: Tablet hardlink: Hardlink convert_to: 'Convert to' replace: Replace -targeting: Targeting paste_inheritance: 'Paste (inheritance)' are_you_sure: 'Are you sure?' all_content_will_be_lost: 'All content will be lost' @@ -588,7 +584,6 @@ visitors_of_this_page_will_be_automatically_associated_with_the_selected_target_ assign_target_group: 'Assign Target Group' assign_target_groups: 'Assign Target Groups' target_group: 'Target Group' -target_groups: 'Target Groups' edit_content_for_target_group: 'Edit Content for Target Group' email_reply_to: 'Reply To' element_tag_filtered_tags: 'Filtered Tags' @@ -687,7 +682,6 @@ batch_append_to: 'Append data to all' login_token_invalid_user_error: 'Invalid user.' login_token_as_admin_non_admin_user_error: 'Only admin users are allowed to login as an admin user.' login_token_no_password_error: 'User has no password set.' -targeting_toolbar: 'Targeting Toolbar' sort_children_by: 'Sort Children By' by_key: 'Key (A to Z)' by_index: 'Index (Manual)' diff --git a/bundles/AdminBundle/translations/admin_ext.en.yaml b/bundles/AdminBundle/translations/admin_ext.en.yaml index f70f4f77009..0078896c6ff 100644 --- a/bundles/AdminBundle/translations/admin_ext.en.yaml +++ b/bundles/AdminBundle/translations/admin_ext.en.yaml @@ -85,19 +85,6 @@ action_scope: Action Scope hit: Hit session: Session session_with_variables: Session (with variables) -targeting_visitor: Visitor -targeting_condition_visited_page_before_piwik_data_warning: >- - This condition fetches data synchronously from Piwik which can be quite slow. - Use with care! -targeting_condition_visited_page_before_piwik_not_configured_warning: >- - This condition cannot be matched as Piwik is not configured and will always - resolve to false. -targeting_condition_url_pattern: URL (RegExp) -targeting_toolbar_browser_note: >- - NOTE: Enabling the targeting toolbar affects only the browser you are - currently using. If you want to use the toolbar on another browser you need to - enable it again. See the - documentation for details. fallback_languages: 'Fallback Languages (CSV eg. de_CH,de)' frontend_languages: Frontend Languages add_language: Add Language diff --git a/bundles/CoreBundle/config/pimcore/default.yaml b/bundles/CoreBundle/config/pimcore/default.yaml index 6bcf9c10a6a..2e538c517c6 100644 --- a/bundles/CoreBundle/config/pimcore/default.yaml +++ b/bundles/CoreBundle/config/pimcore/default.yaml @@ -161,8 +161,6 @@ pimcore: advancedManyToManyObjectRelation: \Pimcore\Model\DataObject\ClassDefinition\Data\AdvancedManyToManyObjectRelation password: \Pimcore\Model\DataObject\ClassDefinition\Data\Password rgbaColor: \Pimcore\Model\DataObject\ClassDefinition\Data\RgbaColor - targetGroup: \Pimcore\Model\DataObject\ClassDefinition\Data\TargetGroup - targetGroupMultiselect: \Pimcore\Model\DataObject\ClassDefinition\Data\TargetGroupMultiselect quantityValue: \Pimcore\Model\DataObject\ClassDefinition\Data\QuantityValue quantityValueRange: \Pimcore\Model\DataObject\ClassDefinition\Data\QuantityValueRange inputQuantityValue: \Pimcore\Model\DataObject\ClassDefinition\Data\InputQuantityValue @@ -210,31 +208,6 @@ pimcore: defaultAdapter: pimcore.document.newsletter.factory.default csvList: pimcore.document.newsletter.factory.csv - targeting: - data_providers: - device: Pimcore\Targeting\DataProvider\Device - geoip: Pimcore\Targeting\DataProvider\GeoIp - geolocation: Pimcore\Targeting\DataProvider\GeoLocation - targeting_storage: Pimcore\Targeting\DataProvider\TargetingStorage - visited_pages_counter: Pimcore\Targeting\DataProvider\VisitedPagesCounter - conditions: - browser: Pimcore\Targeting\Condition\Browser - country: Pimcore\Targeting\Condition\Country - geopoint: Pimcore\Targeting\Condition\GeoPoint - hardwareplatform: Pimcore\Targeting\Condition\HardwarePlatform - language: Pimcore\Targeting\Condition\Language - operatingsystem: Pimcore\Targeting\Condition\OperatingSystem - referringsite: Pimcore\Targeting\Condition\ReferringSite - searchengine: Pimcore\Targeting\Condition\SearchEngine - target_group: Pimcore\Targeting\Condition\TargetGroup - timeonsite: Pimcore\Targeting\Condition\TimeOnSite - url: Pimcore\Targeting\Condition\Url - visitedpagesbefore: Pimcore\Targeting\Condition\VisitedPagesBefore - action_handlers: - assign_target_group: Pimcore\Targeting\ActionHandler\AssignTargetGroup - codesnippet: Pimcore\Targeting\ActionHandler\CodeSnippet - redirect: Pimcore\Targeting\ActionHandler\Redirect - # the routes below are used to determine the request context in PimcoreContextGuesser context: profiler: diff --git a/bundles/CoreBundle/config/profiler.yaml b/bundles/CoreBundle/config/profiler.yaml index 901e9f376d9..cfeca9f917e 100644 --- a/bundles/CoreBundle/config/profiler.yaml +++ b/bundles/CoreBundle/config/profiler.yaml @@ -16,10 +16,3 @@ services: id: 'pimcore' priority: 500 - Pimcore\Bundle\CoreBundle\DataCollector\PimcoreTargetingDataCollector: - tags: - - - name: data_collector - template: '@PimcoreCore/Profiler/targeting_data_collector.html.twig' - id: 'pimcore_targeting' - priority: 312 diff --git a/bundles/CoreBundle/config/targeting.yaml b/bundles/CoreBundle/config/targeting.yaml deleted file mode 100644 index 8ecc23e8443..00000000000 --- a/bundles/CoreBundle/config/targeting.yaml +++ /dev/null @@ -1,162 +0,0 @@ -services: - _defaults: - autowire: true - autoconfigure: true - public: false - - # - # TARGETING STORAGE - # - # The TargetingStorageInterface alias will be set to whatever service_id is configured - # in pimcore.targeting.service_id. The services below are just the core storages, but - # it's possible to define a custom service which can be configured via service_id. - # - - # Cookie - Pimcore\Targeting\Storage\Cookie\JWTCookieSaveHandler: - arguments: - $secret: '%kernel.secret%' - - # NOTE: using this save handler is inherently insecure and can open vulnerabilities by injecting malicious data into the - # client cookie. Use only for testing! - Pimcore\Targeting\Storage\Cookie\JsonCookieSaveHandler: ~ - - Pimcore\Targeting\Storage\CookieStorage: - arguments: - $saveHandler: '@Pimcore\Targeting\Storage\Cookie\JWTCookieSaveHandler' - - # Session Storage. If this is used, the pimcore.targeting.session.enabled entry - # must be set to true to load the session configurator. - Pimcore\Targeting\Storage\SessionStorage: ~ - - # Database - Pimcore\Targeting\Storage\DbStorage: ~ - - # Example for redis - # pimcore.targeting.storage.redis.connection: - # class: Credis_Client - # factory: [Pimcore\Storage\Redis\ConnectionFactory, createConnection] - # arguments: - # - { server: 127.0.0.1, database: 7 } - - # Pimcore\Targeting\Storage\RedisStorage: - # arguments: - # $redis: '@pimcore.targeting.storage.redis.connection' - - # Example for fallback - # Pimcore\Targeting\Storage\FallbackStorage: - # arguments: - # $primaryStorage: '@Pimcore\Targeting\Storage\DbStorage' - # $fallbackStorage: '@Pimcore\Targeting\Storage\CookieStorage' - - - # - # VISITOR INFO - # - - Pimcore\Targeting\VisitorInfoStorageInterface: '@Pimcore\Targeting\VisitorInfoStorage' - Pimcore\Targeting\VisitorInfoStorage: ~ - Pimcore\Targeting\VisitorInfoResolver: ~ - - - # - # DATA PROVIDERS - # - - GeoIp2\ProviderInterface: '@GeoIp2\Database\Reader' - GeoIp2\Database\Reader: - arguments: - $filename: '%pimcore.geoip.db_file%' - - Pimcore\Targeting\DataLoaderInterface: '@Pimcore\Targeting\DataLoader' - Pimcore\Targeting\DataLoader: ~ - - Pimcore\Targeting\DataProvider\GeoIp: - calls: - - [setCache, ['@Pimcore\Cache\Core\CoreCacheHandler']] - - Pimcore\Targeting\DataProvider\GeoLocation: ~ - - Pimcore\Targeting\DataProvider\Device: - calls: - - [setCache, ['@Pimcore\Cache\Core\CoreCacheHandler']] - - [setCachePool, ['@pimcore.cache.pool']] - - Pimcore\Targeting\DataProvider\TargetingStorage: ~ - - Pimcore\Targeting\Service\VisitedPagesCounter: ~ - Pimcore\Targeting\DataProvider\VisitedPagesCounter: ~ - - - # - # CONDITIONS - # - - Pimcore\Targeting\ConditionFactoryInterface: '@Pimcore\Targeting\ConditionFactory' - Pimcore\Targeting\ConditionFactory: - arguments: - $conditions: '%pimcore.targeting.conditions%' - - pimcore.targeting.condition_matcher.expression_language: - class: Symfony\Component\ExpressionLanguage\ExpressionLanguage - arguments: - $cache: '@pimcore.cache.pool' - - Pimcore\Targeting\ConditionMatcherInterface: '@Pimcore\Targeting\ConditionMatcher' - Pimcore\Targeting\ConditionMatcher: - arguments: - $expressionLanguage: '@pimcore.targeting.condition_matcher.expression_language' - - - # - # ACTION HANDLERS - # - - Pimcore\Targeting\ActionHandler\ActionHandlerInterface: '@Pimcore\Targeting\ActionHandler\DelegatingActionHandler' - Pimcore\Targeting\ActionHandler\DelegatingActionHandler: ~ - Pimcore\Targeting\ActionHandler\AssignTargetGroup: ~ - Pimcore\Targeting\ActionHandler\Redirect: ~ - Pimcore\Targeting\ActionHandler\CodeSnippet: ~ - - - # - # DOCUMENT HANDLING - # - - Pimcore\Targeting\Document\DocumentTargetingConfigurator: - public: true - - - # - # TARGETING CODE - # - - Pimcore\Targeting\Code\TargetingCodeGenerator: ~ - - # - # TOOLBAR AND PROFILER - # - - Pimcore\Targeting\Debug\TargetingDataCollector: ~ - - Pimcore\Targeting\Debug\OverrideHandler: - lazy: true - arguments: - # injected by TargetingOverrideHandlersPass - $overrideHandlers: '?@' - - Pimcore\Targeting\Debug\Override\DocumentTargetingOverrideHandler: - tags: - - { name: pimcore.targeting.override_handler, priority: 500 } - - Pimcore\Targeting\Debug\Override\LanguageOverrideHandler: - tags: - - { name: pimcore.targeting.override_handler, priority: 475 } - - Pimcore\Targeting\Debug\Override\DeviceOverrideHandler: - tags: - - { name: pimcore.targeting.override_handler, priority: 450 } - - Pimcore\Targeting\Debug\Override\LocationOverrideHandler: - tags: - - { name: pimcore.targeting.override_handler, priority: 425 } diff --git a/bundles/CoreBundle/config/targeting/listeners.yaml b/bundles/CoreBundle/config/targeting/listeners.yaml deleted file mode 100644 index 4ba53e1d9d9..00000000000 --- a/bundles/CoreBundle/config/targeting/listeners.yaml +++ /dev/null @@ -1,12 +0,0 @@ -services: - _defaults: - autowire: true - autoconfigure: true - public: false - - Pimcore\Targeting\EventListener\TargetingListener: ~ - Pimcore\Targeting\EventListener\DocumentTargetGroupListener: ~ - Pimcore\Targeting\EventListener\FullPageCacheCookieCleanupListener: ~ - Pimcore\Targeting\EventListener\VisitedPagesCountListener: ~ - Pimcore\Targeting\EventListener\ToolbarListener: ~ - Pimcore\Targeting\EventListener\TargetingSessionBagListener: ~ diff --git a/bundles/CoreBundle/config/targeting/services.yaml b/bundles/CoreBundle/config/targeting/services.yaml deleted file mode 100644 index 131536b99ab..00000000000 --- a/bundles/CoreBundle/config/targeting/services.yaml +++ /dev/null @@ -1,7 +0,0 @@ -services: - _defaults: - autowire: true - autoconfigure: true - public: false - - Pimcore\Targeting\Maintenance\TargetingStorageTask: ~ diff --git a/bundles/CoreBundle/src/DependencyInjection/Configuration.php b/bundles/CoreBundle/src/DependencyInjection/Configuration.php index 424044dd9f3..2bf4cc92a79 100644 --- a/bundles/CoreBundle/src/DependencyInjection/Configuration.php +++ b/bundles/CoreBundle/src/DependencyInjection/Configuration.php @@ -17,8 +17,6 @@ namespace Pimcore\Bundle\CoreBundle\DependencyInjection; use Pimcore\Bundle\CoreBundle\DependencyInjection\Config\Processor\PlaceholderProcessor; -use Pimcore\Targeting\Storage\CookieStorage; -use Pimcore\Targeting\Storage\TargetingStorageInterface; use Pimcore\Workflow\EventSubscriber\ChangePublishedStateSubscriber; use Pimcore\Workflow\EventSubscriber\NotificationSubscriber; use Pimcore\Workflow\Notification\NotificationEmailService; @@ -126,7 +124,6 @@ public function getConfigTreeBuilder(): TreeBuilder $this->addSecurityNode($rootNode); $this->addEmailNode($rootNode); $this->addNewsletterNode($rootNode); - $this->addTargetingNode($rootNode); $this->addSitemapsNode($rootNode); $this->addWorkflowNode($rootNode); $this->addHttpClientNode($rootNode); @@ -1182,43 +1179,6 @@ private function addNewsletterNode(ArrayNodeDefinition $rootNode): void ->end(); } - private function addTargetingNode(ArrayNodeDefinition $rootNode): void - { - $rootNode - ->children() - ->arrayNode('targeting') - ->canBeDisabled() - ->addDefaultsIfNotSet() - ->children() - ->scalarNode('storage_id') - ->info('Service ID of the targeting storage which should be used. This ID will be aliased to ' . TargetingStorageInterface::class) - ->defaultValue(CookieStorage::class) - ->cannotBeEmpty() - ->end() - ->arrayNode('session') - ->info('Enables HTTP session support by configuring session bags and the full page cache') - ->canBeEnabled() - ->end() - ->arrayNode('data_providers') - ->useAttributeAsKey('key') - ->prototype('scalar') - ->end() - ->end() - ->arrayNode('conditions') - ->useAttributeAsKey('key') - ->prototype('scalar') - ->end() - ->end() - ->arrayNode('action_handlers') - ->useAttributeAsKey('name') - ->prototype('scalar') - ->end() - ->end() - ->end() - ->end() - ->end(); - } - private function addSitemapsNode(ArrayNodeDefinition $rootNode): void { $rootNode diff --git a/bundles/CoreBundle/src/DependencyInjection/PimcoreCoreExtension.php b/bundles/CoreBundle/src/DependencyInjection/PimcoreCoreExtension.php index e67873856d8..efb188e4a8f 100644 --- a/bundles/CoreBundle/src/DependencyInjection/PimcoreCoreExtension.php +++ b/bundles/CoreBundle/src/DependencyInjection/PimcoreCoreExtension.php @@ -29,9 +29,6 @@ use Pimcore\Model\Document\TypeDefinition\Loader\TypeLoader; use Pimcore\Model\Factory; use Pimcore\Sitemap\EventListener\SitemapGeneratorListener; -use Pimcore\Targeting\ActionHandler\DelegatingActionHandler; -use Pimcore\Targeting\DataLoaderInterface; -use Pimcore\Targeting\Storage\TargetingStorageInterface; use Symfony\Component\Config\FileLocator; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -133,7 +130,6 @@ public function loadInternal(array $config, ContainerBuilder $container): void $this->configureModelFactory($container, $config); $this->configureRouting($container, $config['routing']); $this->configureTranslations($container, $config['translations']); - $this->configureTargeting($container, $loader, $config['targeting']); $this->configurePasswordHashers($container, $config); $this->configureAdapterFactories($container, $config['newsletter']['source_adapters'], 'pimcore.newsletter.address_source_adapter.factories'); $this->configureGoogleAnalyticsFallbackServiceLocator($container); @@ -236,69 +232,6 @@ private function configureTranslations(ContainerBuilder $container, array $confi } } - private function configureTargeting(ContainerBuilder $container, LoaderInterface $loader, array $config): void - { - $container->setParameter('pimcore.targeting.enabled', $config['enabled']); - $container->setParameter('pimcore.targeting.conditions', $config['conditions']); - if (!$container->hasParameter('pimcore.geoip.db_file')) { - $container->setParameter('pimcore.geoip.db_file', ''); - } - - $loader->load('targeting.yaml'); - - // set TargetingStorageInterface type hint to the configured service ID - $container->setAlias(TargetingStorageInterface::class, $config['storage_id']); - - if ($config['enabled']) { - // enable targeting by registering listeners - $loader->load('targeting/services.yaml'); - $loader->load('targeting/listeners.yaml'); - } - - $dataProviders = []; - foreach ($config['data_providers'] as $dataProviderKey => $dataProviderServiceId) { - $dataProviders[$dataProviderKey] = new Reference($dataProviderServiceId); - } - - $dataProviderLocator = new Definition(ServiceLocator::class, [$dataProviders]); - $dataProviderLocator - ->setPublic(false) - ->addTag('container.service_locator'); - - $container - ->findDefinition(DataLoaderInterface::class) - ->setArgument('$dataProviders', $dataProviderLocator); - - $actionHandlers = []; - foreach ($config['action_handlers'] as $actionHandlerKey => $actionHandlerServiceId) { - $actionHandlers[$actionHandlerKey] = new Reference($actionHandlerServiceId); - } - - $actionHandlerLocator = new Definition(ServiceLocator::class, [$actionHandlers]); - $actionHandlerLocator - ->setPublic(false) - ->addTag('container.service_locator'); - - $container - ->getDefinition(DelegatingActionHandler::class) - ->setArgument('$actionHandlers', $actionHandlerLocator); - } - - /** - * Configures a "typed locator" (a class exposing get/has for a specific type) wrapping - * a standard service locator. Example: Pimcore\Targeting\DataProviderLocator - */ - private function configureTypedLocator(ContainerBuilder $container, string $locatorClass, array $services): void - { - $serviceLocator = new Definition(ServiceLocator::class, [$services]); - $serviceLocator - ->setPublic(false) - ->addTag('container.service_locator'); - - $locator = $container->getDefinition($locatorClass); - $locator->setArgument('$locator', $serviceLocator); - } - /** * Handle pimcore.security.password_hasher_factories mapping */ diff --git a/bundles/CoreBundle/src/EventListener/Frontend/ElementListener.php b/bundles/CoreBundle/src/EventListener/Frontend/ElementListener.php index 2e81096eac1..9149351ce14 100644 --- a/bundles/CoreBundle/src/EventListener/Frontend/ElementListener.php +++ b/bundles/CoreBundle/src/EventListener/Frontend/ElementListener.php @@ -27,7 +27,6 @@ use Pimcore\Model\Document; use Pimcore\Model\User; use Pimcore\Model\Version; -use Pimcore\Targeting\Document\DocumentTargetingConfigurator; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerAwareTrait; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -51,8 +50,7 @@ public function __construct( protected DocumentResolver $documentResolver, protected EditmodeResolver $editmodeResolver, protected RequestHelper $requestHelper, - protected UserLoader $userLoader, - private DocumentTargetingConfigurator $targetingConfigurator + protected UserLoader $userLoader ) { } @@ -98,8 +96,6 @@ public function onKernelController(ControllerEvent $event): void // for public versions $document = $this->handleVersion($request, $document); - // apply target group configuration - $this->applyTargetGroups($request, $document); $this->documentResolver->setDocument($request, $document); } @@ -129,29 +125,6 @@ protected function handleVersion(Request $request, Document $document): Document return $document; } - protected function applyTargetGroups(Request $request, Document $document): void - { - if (!$document instanceof Document\Targeting\TargetingDocumentInterface) { - return; - } - - if (class_exists(Staticroute::class) && null !== Staticroute::getCurrentRoute()) { - return; - } - - // reset because of preview and editmode (saved in session) - $document->setUseTargetGroup(null); - - $this->targetingConfigurator->configureTargetGroup($document); - - if ($document->getUseTargetGroup()) { - $this->logger->info('Setting target group to {targetGroup} for document {document}', [ - 'targetGroup' => $document->getUseTargetGroup(), - 'document' => $document->getFullPath(), - ]); - } - } - private function handleAdminUserDocumentParams(Request $request, ?Document $document, User $user): ?Document { if (!$document) { diff --git a/bundles/CoreBundle/src/EventListener/Frontend/FullPageCacheListener.php b/bundles/CoreBundle/src/EventListener/Frontend/FullPageCacheListener.php index be11bbfc6d2..4e4756ac38e 100644 --- a/bundles/CoreBundle/src/EventListener/Frontend/FullPageCacheListener.php +++ b/bundles/CoreBundle/src/EventListener/Frontend/FullPageCacheListener.php @@ -26,7 +26,6 @@ use Pimcore\Event\FullPageCacheEvents; use Pimcore\Http\Request\Resolver\PimcoreContextResolver; use Pimcore\Logger; -use Pimcore\Targeting\VisitorInfoStorageInterface; use Pimcore\Tool; use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\Response; @@ -54,9 +53,8 @@ class FullPageCacheListener protected ?string $defaultCacheKey = null; public function __construct( - private VisitorInfoStorageInterface $visitorInfoStorage, - private SessionStatus $sessionStatus, - private EventDispatcherInterface $eventDispatcher, + protected SessionStatus $sessionStatus, + protected EventDispatcherInterface $eventDispatcher, protected Config $config ) { } @@ -310,13 +308,6 @@ public function onKernelResponse(ResponseEvent $event): void $this->disable('Response can\'t be cached'); } - // check if targeting matched anything and disable cache - if ($this->disabledByTargeting()) { - $this->disable('Targeting matched rules/target groups'); - - return; - } - if ($this->enabled && $this->sessionStatus->isDisabledBySession($request)) { $this->disable('Session in use'); } @@ -388,23 +379,4 @@ private function responseCanBeCached(Response $response): bool return $event->getCache(); } - - private function disabledByTargeting(): bool - { - if (!$this->visitorInfoStorage->hasVisitorInfo()) { - return false; - } - - $visitorInfo = $this->visitorInfoStorage->getVisitorInfo(); - - if (!empty($visitorInfo->getMatchingTargetingRules())) { - return true; - } - - if (!empty($visitorInfo->getTargetGroupAssignments())) { - return true; - } - - return false; - } } diff --git a/bundles/CoreBundle/src/Migrations/Version20230125164101.php b/bundles/CoreBundle/src/Migrations/Version20230125164101.php new file mode 100644 index 00000000000..d2c77483594 --- /dev/null +++ b/bundles/CoreBundle/src/Migrations/Version20230125164101.php @@ -0,0 +1,47 @@ +warnIf( + null !== SettingsStore::get('BUNDLE_INSTALLED__Pimcore\\Bundle\\PersonalizationBundle\\PimcorePersonalizationBundle', 'pimcore'), + 'Please make sure to enable the Pimcore\\Bundle\\PersonalizationBundle\\PimcorePersonalizationBundle manually in config/bundles.php' + ); + } + + public function down(Schema $schema): void + { + + } +} diff --git a/bundles/CoreBundle/src/PimcoreCoreBundle.php b/bundles/CoreBundle/src/PimcoreCoreBundle.php index cf227daa7ee..f00d7bfc6a2 100644 --- a/bundles/CoreBundle/src/PimcoreCoreBundle.php +++ b/bundles/CoreBundle/src/PimcoreCoreBundle.php @@ -29,7 +29,6 @@ use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\RegisterMaintenanceTaskPass; use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\RoutingLoaderPass; use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\ServiceControllersPass; -use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\TargetingOverrideHandlersPass; use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\WorkflowPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; @@ -71,10 +70,8 @@ public function build(ContainerBuilder $container): void $container->addCompilerPass(new AreabrickPass()); $container->addCompilerPass(new NavigationRendererPass()); $container->addCompilerPass(new ServiceControllersPass()); - $container->addCompilerPass(new TargetingOverrideHandlersPass()); $container->addCompilerPass(new MonologPublicLoggerPass()); $container->addCompilerPass(new MonologPsrLogMessageProcessorPass()); - $container->addCompilerPass(new DebugStopwatchPass()); $container->addCompilerPass(new LongRunningHelperPass()); $container->addCompilerPass(new WorkflowPass()); $container->addCompilerPass(new RegisterImageOptimizersPass()); diff --git a/bundles/EcommerceFrameworkBundle/composer.json b/bundles/EcommerceFrameworkBundle/composer.json index cc877ffa859..1db9adf23dd 100644 --- a/bundles/EcommerceFrameworkBundle/composer.json +++ b/bundles/EcommerceFrameworkBundle/composer.json @@ -14,6 +14,7 @@ "minimum-stability": "dev", "require": { "pimcore/pimcore": "^11.0", + "pimcore/personalization-bundle": "^1.0", "knplabs/knp-paginator-bundle": "^6.0.0" }, "require-dev": { diff --git a/bundles/EcommerceFrameworkBundle/src/PimcoreEcommerceFrameworkBundle.php b/bundles/EcommerceFrameworkBundle/src/PimcoreEcommerceFrameworkBundle.php index cf62bc2a14b..b09c80d27b0 100644 --- a/bundles/EcommerceFrameworkBundle/src/PimcoreEcommerceFrameworkBundle.php +++ b/bundles/EcommerceFrameworkBundle/src/PimcoreEcommerceFrameworkBundle.php @@ -16,9 +16,11 @@ namespace Pimcore\Bundle\EcommerceFrameworkBundle; +use Pimcore\Bundle\ApplicationLoggerBundle\PimcoreApplicationLoggerBundle; use Pimcore\Bundle\EcommerceFrameworkBundle\DependencyInjection\Compiler\RegisterConfiguredServicesPass; use Pimcore\Bundle\EcommerceFrameworkBundle\Tools\Installer; use Pimcore\Bundle\EcommerceFrameworkBundle\Type\Decimal; +use Pimcore\Bundle\PersonalizationBundle\PimcorePersonalizationBundle; use Pimcore\Extension\Bundle\AbstractPimcoreBundle; use Pimcore\HttpKernel\Bundle\DependentBundleInterface; use Pimcore\HttpKernel\BundleCollection\BundleCollection; @@ -84,8 +86,7 @@ public function getInstaller(): Installer public static function registerDependentBundles(BundleCollection $collection): void { - if (\Pimcore\Version::getMajorVersion() >= 11) { - $collection->addBundle(\Pimcore\Bundle\ApplicationLoggerBundle\PimcoreApplicationLoggerBundle::class); - } + $collection->addBundle(PimcoreApplicationLoggerBundle::class); + $collection->addBundle(PimcorePersonalizationBundle::class); } } diff --git a/bundles/EcommerceFrameworkBundle/src/PricingManager/Environment.php b/bundles/EcommerceFrameworkBundle/src/PricingManager/Environment.php index abe4a7a6b76..cb802d1fa33 100644 --- a/bundles/EcommerceFrameworkBundle/src/PricingManager/Environment.php +++ b/bundles/EcommerceFrameworkBundle/src/PricingManager/Environment.php @@ -20,7 +20,7 @@ use Pimcore\Bundle\EcommerceFrameworkBundle\CartManager\CartItemInterface; use Pimcore\Bundle\EcommerceFrameworkBundle\Model\AbstractCategory; use Pimcore\Bundle\EcommerceFrameworkBundle\Model\CheckoutableInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface; class Environment implements EnvironmentInterface diff --git a/bundles/EcommerceFrameworkBundle/src/PricingManager/EnvironmentInterface.php b/bundles/EcommerceFrameworkBundle/src/PricingManager/EnvironmentInterface.php index 087dd85eb68..c17d648a434 100644 --- a/bundles/EcommerceFrameworkBundle/src/PricingManager/EnvironmentInterface.php +++ b/bundles/EcommerceFrameworkBundle/src/PricingManager/EnvironmentInterface.php @@ -20,7 +20,7 @@ use Pimcore\Bundle\EcommerceFrameworkBundle\CartManager\CartItemInterface; use Pimcore\Bundle\EcommerceFrameworkBundle\Model\AbstractCategory; use Pimcore\Bundle\EcommerceFrameworkBundle\Model\CheckoutableInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; interface EnvironmentInterface { diff --git a/bundles/EcommerceFrameworkBundle/src/PricingManager/PricingManager.php b/bundles/EcommerceFrameworkBundle/src/PricingManager/PricingManager.php index 7172e30ef0b..d95d6ea5e51 100644 --- a/bundles/EcommerceFrameworkBundle/src/PricingManager/PricingManager.php +++ b/bundles/EcommerceFrameworkBundle/src/PricingManager/PricingManager.php @@ -21,7 +21,7 @@ use Pimcore\Bundle\EcommerceFrameworkBundle\Exception\InvalidConfigException; use Pimcore\Bundle\EcommerceFrameworkBundle\Model\CheckoutableInterface; use Pimcore\Bundle\EcommerceFrameworkBundle\PriceSystem\PriceInfoInterface as PriceSystemPriceInfoInterface; -use Pimcore\Targeting\VisitorInfoStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class PricingManager implements PricingManagerInterface diff --git a/bundles/EcommerceFrameworkBundle/src/Resources/config/pimcore/config.yaml b/bundles/EcommerceFrameworkBundle/src/Resources/config/pimcore/config.yaml index 5a6c9aff4c9..ba759fb294b 100644 --- a/bundles/EcommerceFrameworkBundle/src/Resources/config/pimcore/config.yaml +++ b/bundles/EcommerceFrameworkBundle/src/Resources/config/pimcore/config.yaml @@ -38,7 +38,6 @@ pimcore_ecommerce_framework: ClientIp: \Pimcore\Bundle\EcommerceFrameworkBundle\PricingManager\Condition\ClientIp VoucherToken: \Pimcore\Bundle\EcommerceFrameworkBundle\PricingManager\Condition\VoucherToken Tenant: \Pimcore\Bundle\EcommerceFrameworkBundle\PricingManager\Condition\Tenant - TargetGroup: \Pimcore\Bundle\EcommerceFrameworkBundle\PricingManager\Condition\TargetGroup actions: ProductDiscount: \Pimcore\Bundle\EcommerceFrameworkBundle\PricingManager\Action\ProductDiscount CartDiscount: \Pimcore\Bundle\EcommerceFrameworkBundle\PricingManager\Action\CartDiscount diff --git a/bundles/EcommerceFrameworkBundle/src/Resources/public/js/pricing/config/item.js b/bundles/EcommerceFrameworkBundle/src/Resources/public/js/pricing/config/item.js index ad3127d906b..08a06cb96c7 100644 --- a/bundles/EcommerceFrameworkBundle/src/Resources/public/js/pricing/config/item.js +++ b/bundles/EcommerceFrameworkBundle/src/Resources/public/js/pricing/config/item.js @@ -1155,76 +1155,6 @@ pimcore.bundle.EcommerceFramework.pricing.conditions = { }] }); - return item; - }, - - /** - * @param panel - * @param data - * @param getName - * @returns Ext.form.FormPanel - */ - conditionTargetGroup: function (panel, data, getName) { - var niceName = t("bundle_ecommerce_pricing_config_condition_targetgroup"); - if (typeof getName !== "undefined" && getName) { - return niceName; - } - - // check params - if (typeof data === "undefined") { - data = {}; - } - - - this.targetGroupStore = Ext.create('Ext.data.JsonStore', { - autoLoad: true, - proxy: { - type: 'ajax', - url: Routing.generate('pimcore_admin_targeting_targetgrouplist') - }, - fields: ["id", "text"], - listeners: { - load: function() { - this.targetGroup.setValue(data.targetGroupId); - }.bind(this) - } - }); - - this.targetGroup = new Ext.form.ComboBox({ - displayField:'text', - valueField: "id", - name: "targetGroupId", - fieldLabel: t("bundle_ecommerce_pricing_config_condition_targetgroup"), - store: this.targetGroupStore, - editable: false, - triggerAction: 'all', - width: 500, - listeners: { - } - }); - - - // create item - var myId = Ext.id(); - var item = new Ext.form.FormPanel({ - id: myId, - type: 'TargetGroup', - forceLayout: true, - style: "margin: 10px 0 0 0", - bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: this.getTopBar(niceName, myId, panel, data, "bundle_ecommerce_pricing_icon_conditionTargetGroup"), - items: [ - this.targetGroup, - { - xtype: "numberfield", - fieldLabel: t("bundle_ecommerce_pricing_config_condition_targetgroup_threshold"), - name: "threshold", - width: 200, - value: data.threshold - } - ] - }); - return item; } }; diff --git a/bundles/EcommerceFrameworkBundle/src/Tools/Installer.php b/bundles/EcommerceFrameworkBundle/src/Tools/Installer.php index 3e6e246f8f9..317668d0570 100644 --- a/bundles/EcommerceFrameworkBundle/src/Tools/Installer.php +++ b/bundles/EcommerceFrameworkBundle/src/Tools/Installer.php @@ -147,12 +147,16 @@ public function __construct( public function installDependentBundles(): void { - if (\Pimcore\Version::getMajorVersion() >= 11) { - $appLoggerInstaller = \Pimcore::getContainer()->get(\Pimcore\Bundle\ApplicationLoggerBundle\Installer::class); + //Install ApplicationLoggerBundle Bundle + $appLoggerInstaller = \Pimcore::getContainer()->get(\Pimcore\Bundle\ApplicationLoggerBundle\Installer::class); + if (!$appLoggerInstaller->isInstalled()) { + $appLoggerInstaller->install(); + } - if (!$appLoggerInstaller->isInstalled()) { - $appLoggerInstaller->install(); - } + //Install PersonalizationBundle + $personalizationInstaller = \Pimcore::getContainer()->get(\Pimcore\Bundle\PersonalizationBundle\Installer::class); + if (!$personalizationInstaller->isInstalled()) { + $personalizationInstaller->install(); } } diff --git a/bundles/InstallBundle/dump/install.sql b/bundles/InstallBundle/dump/install.sql index 58c42aa4d6e..fbda42793ac 100644 --- a/bundles/InstallBundle/dump/install.sql +++ b/bundles/InstallBundle/dump/install.sql @@ -442,42 +442,6 @@ CREATE TABLE `tags_assignment` ( KEY `ctype_cid` (`cid`,`ctype`) ) DEFAULT CHARSET=utf8mb4; -DROP TABLE IF EXISTS `targeting_rules`; -CREATE TABLE `targeting_rules` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL DEFAULT '', - `description` text, - `scope` varchar(50) DEFAULT NULL, - `active` tinyint(1) DEFAULT NULL, - `prio` smallint(5) unsigned NOT NULL DEFAULT '0', - `conditions` longtext, - `actions` longtext, - PRIMARY KEY (`id`) -) DEFAULT CHARSET=utf8mb4; - -DROP TABLE IF EXISTS `targeting_storage`; -CREATE TABLE `targeting_storage` ( - `visitorId` varchar(100) NOT NULL, - `scope` varchar(50) NOT NULL, - `name` varchar(100) NOT NULL, - `value` json, - `creationDate` datetime DEFAULT NULL, - `modificationDate` datetime DEFAULT NULL, - PRIMARY KEY (`visitorId`,`scope`,`name`), - KEY `targeting_storage_scope_index` (`scope`), - KEY `targeting_storage_name_index` (`name`) -) DEFAULT CHARSET=utf8mb4; - -DROP TABLE IF EXISTS `targeting_target_groups`; -CREATE TABLE `targeting_target_groups` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL DEFAULT '', - `description` text, - `threshold` int(11) DEFAULT NULL, - `active` tinyint(1) DEFAULT NULL, - PRIMARY KEY (`id`) -) DEFAULT CHARSET=utf8mb4; - DROP TABLE IF EXISTS `tmp_store`; CREATE TABLE `tmp_store` ( `id` varchar(190) NOT NULL DEFAULT '', diff --git a/bundles/InstallBundle/src/Installer.php b/bundles/InstallBundle/src/Installer.php index bf7ae4616c7..4dd63a3a9bf 100644 --- a/bundles/InstallBundle/src/Installer.php +++ b/bundles/InstallBundle/src/Installer.php @@ -740,7 +740,6 @@ protected function insertDatabaseContents(): void 'tags_configuration', 'tags_assignment', 'tags_search', - 'targeting', 'thumbnails', 'translations', 'users', diff --git a/bundles/PersonalizationBundle/.editorconfig b/bundles/PersonalizationBundle/.editorconfig new file mode 100644 index 00000000000..724304db261 --- /dev/null +++ b/bundles/PersonalizationBundle/.editorconfig @@ -0,0 +1,21 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_style = space +indent_size = 4 + +[*.php] +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.yml] +indent_size = 4 + +[composer.json] +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.gitattributes b/bundles/PersonalizationBundle/.gitattributes new file mode 100644 index 00000000000..3569d634e76 --- /dev/null +++ b/bundles/PersonalizationBundle/.gitattributes @@ -0,0 +1,2 @@ + +* -text diff --git a/bundles/PersonalizationBundle/.github/ci/files/.env b/bundles/PersonalizationBundle/.github/ci/files/.env new file mode 100644 index 00000000000..007e4e91eb4 --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/.env @@ -0,0 +1,2 @@ +APP_ENV=test +APP_DEBUG=true \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.github/ci/files/.my.cnf b/bundles/PersonalizationBundle/.github/ci/files/.my.cnf new file mode 100644 index 00000000000..fd25c4ef5de --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/.my.cnf @@ -0,0 +1,5 @@ +[client] +host=127.0.0.1 +port=33006 +user=root +password= \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.github/ci/files/bin/console b/bundles/PersonalizationBundle/.github/ci/files/bin/console new file mode 100644 index 00000000000..232606f7c69 --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/bin/console @@ -0,0 +1,46 @@ +#!/usr/bin/env php +getParameterOption(['--env', '-e'], null, true)) { + putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env); +} + +if ($input->hasParameterOption('--no-debug', true)) { + putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0'); +} + +/** @var \Pimcore\Kernel $kernel */ +$kernel = \Pimcore\Bootstrap::startupCli(); +$application = new \Pimcore\Console\Application($kernel); +$application->run(); \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.github/ci/files/config/bundles.php b/bundles/PersonalizationBundle/.github/ci/files/config/bundles.php new file mode 100644 index 00000000000..d4d63ced02c --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/config/bundles.php @@ -0,0 +1,5 @@ + ['all' => true], +]; diff --git a/bundles/PersonalizationBundle/.github/ci/files/config/config.yaml b/bundles/PersonalizationBundle/.github/ci/files/config/config.yaml new file mode 100644 index 00000000000..459522eee27 --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/config/config.yaml @@ -0,0 +1,3 @@ +imports: + - { resource: services.yaml } + - { resource: system.yaml } \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.github/ci/files/config/packages/security.yaml b/bundles/PersonalizationBundle/.github/ci/files/config/packages/security.yaml new file mode 100644 index 00000000000..8a02965d1af --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/config/packages/security.yaml @@ -0,0 +1,59 @@ +security: + providers: + pimcore_admin: + id: Pimcore\Bundle\AdminBundle\Security\User\UserProvider + + firewalls: + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + + # Pimcore WebDAV HTTP basic // DO NOT CHANGE! + pimcore_admin_webdav: + pattern: ^/admin/asset/webdav + provider: pimcore_admin + http_basic: ~ + + # Pimcore admin form login // DO NOT CHANGE! + pimcore_admin: + pattern: ^/admin(/.*)?$ + user_checker: Pimcore\Bundle\AdminBundle\Security\User\UserChecker + provider: pimcore_admin + login_throttling: + max_attempts: 3 + interval: '5 minutes' + logout: + path: pimcore_admin_logout + target: pimcore_admin_login + form_login: + default_target_path: pimcore_admin_index + always_use_default_target_path: true + login_path: pimcore_admin_login + check_path: pimcore_admin_login_check + username_parameter: username + password_parameter: password + custom_authenticators: + - Pimcore\Bundle\AdminBundle\Security\Authenticator\AdminTokenAuthenticator + two_factor: + auth_form_path: /admin/login/2fa # Path or route name of the two-factor form + check_path: /admin/login/2fa-verify # Path or route name of the two-factor code check + default_target_path: /admin # Where to redirect by default after successful authentication + always_use_default_target_path: false # If it should always redirect to default_target_path + auth_code_parameter_name: _auth_code # Name of the parameter for the two-factor authentication code + trusted_parameter_name: _trusted # Name of the parameter for the trusted device option + multi_factor: false # If ALL active two-factor methods need to be fulfilled (multi-factor authentication) + + + access_control: + # Pimcore admin ACl // DO NOT CHANGE! + - { path: ^/admin/settings/display-custom-logo, roles: PUBLIC_ACCESS } + - { path: ^/admin/login/2fa-verify, roles: IS_AUTHENTICATED_2FA_IN_PROGRESS } + - { path: ^/admin/login/2fa-setup, roles: ROLE_PIMCORE_USER } + - { path: ^/admin/login/2fa, roles: IS_AUTHENTICATED_2FA_IN_PROGRESS } + - { path: ^/admin/login$, roles: PUBLIC_ACCESS } + - { path: ^/admin/login/(login|lostpassword|deeplink|csrf-token)$, roles: PUBLIC_ACCESS } + - { path: ^/admin, roles: ROLE_PIMCORE_USER } + + role_hierarchy: + # Pimcore admin // DO NOT CHANGE! + ROLE_PIMCORE_ADMIN: [ROLE_PIMCORE_USER] diff --git a/bundles/PersonalizationBundle/.github/ci/files/config/packages/test/config.yaml b/bundles/PersonalizationBundle/.github/ci/files/config/packages/test/config.yaml new file mode 100644 index 00000000000..0afd2a0987f --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/config/packages/test/config.yaml @@ -0,0 +1,32 @@ +imports: + - { resource: ../../config.yaml } + +# this cache is used during tests when setting up pimcore +framework: + cache: + pools: + pimcore.cache.pool: + public: true + tags: true + default_lifetime: 31536000 # 1 year + adapter: cache.adapter.array + + +doctrine: + dbal: + connections: + default: + url: '%pimcore_test.db.dsn%' + host: ~ + port: ~ + dbname: ~ + user: ~ + password: ~ + mapping_types: + enum: string + bit: boolean + +parameters: + pimcore_test.db.dsn: '%env(PIMCORE_TEST_DB_DSN)%' + env(PIMCORE_TEST_DB_DSN): ~ + pimcore.encryption.secret: 'def00000fc1e34a17a03e2ef85329325b0736a5941633f8062f6b0a1a20f416751af119256bea0abf83ac33ef656b3fff087e1ce71fa6b8810d7f854fe2781f3fe4507f6' \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.github/ci/files/config/services.yaml b/bundles/PersonalizationBundle/.github/ci/files/config/services.yaml new file mode 100644 index 00000000000..cbcba33df6e --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/config/services.yaml @@ -0,0 +1,31 @@ +parameters: + secret: ThisTokenIsNotSoSecretChangeIt + +services: + # default configuration for services in *this* file + _defaults: + # automatically injects dependencies in your services + autowire: true + # automatically registers your services as commands, event subscribers, etc. + autoconfigure: true + # this means you cannot fetch services directly from the container via $container->get() + # if you need to do this, you can override this setting on individual services + public: true + + # Example custom templating helper + # AppBundle\Templating\Helper\Example: + # # templating helpers need to be public as they + # # are fetched from the container on demand + # public: true + # tags: + # - { name: templating.helper, alias: fooBar } + + # Example event listener for objects + # AppBundle\EventListener\TestListener: + # tags: + # - { name: kernel.event_listener, event: pimcore.dataobject.preUpdate, method: onObjectPreUpdate } + + Pimcore\PersonalizationBundle\Installer: + public: true + arguments: + $bundle: "@=service('kernel').getBundle('PimcorePersonalizationBundle')" \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.github/ci/files/config/system.yaml b/bundles/PersonalizationBundle/.github/ci/files/config/system.yaml new file mode 100644 index 00000000000..3d4fe319910 --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/config/system.yaml @@ -0,0 +1,81 @@ +pimcore: + general: + timezone: Europe/Berlin + path_variable: '' + domain: pimcore-test.dev + redirect_to_maindomain: false + language: en + valid_languages: 'en,de' + fallback_languages: + en: '' + de: '' + default_language: '' + disable_usage_statistics: false + instance_identifier: '' + documents: + versions: + days: null + steps: 10 + error_pages: + default: /error + allow_trailing_slash: 'no' + generate_preview: true + objects: + versions: + days: null + steps: 10 + assets: + versions: + days: null + steps: 10 + icc_rgb_profile: '' + icc_cmyk_profile: '' + hide_edit_image: false + disable_tree_preview: false + services: + google: + client_id: '' + email: '' + simple_api_key: '' + browser_api_key: '' + full_page_cache: + enabled: false + lifetime: null + exclude_patterns: '' + exclude_cookie: '' + httpclient: + adapter: Socket + proxy_host: '' + proxy_port: '' + proxy_user: '' + proxy_pass: '' + email: + sender: + name: pimcore + email: pimcore@example.com + return: + name: pimcore + email: pimcore@example.com + debug: + email_addresses: '' + newsletter: + sender: + name: '' + email: '' + return: + name: '' + email: '' + debug: null + use_specific: true + applicationlog: + mail_notification: + send_log_summary: false + filter_priority: null + mail_receiver: '' + archive_treshold: '30' + archive_alternative_database: '' +pimcore_admin: + branding: + color_login_screen: '' + color_admin_interface: '' + login_screen_custom_image: '' \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.github/ci/files/kernel/Kernel.php b/bundles/PersonalizationBundle/.github/ci/files/kernel/Kernel.php new file mode 100644 index 00000000000..c801b2773c5 --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/kernel/Kernel.php @@ -0,0 +1,22 @@ + + + Options -MultiViews + + + + + + +# mime types + +AddType video/mp4 .mp4 + +AddType video/webm .webm + +AddType image/jpeg .pjpeg + + + + +Options +SymLinksIfOwnerMatch + + + + +# Use UTF-8 encoding for anything served text/plain or text/html + +AddDefaultCharset utf-8 + + + + +RewriteEngine On + + + + + + + + + Header always unset X-Content-Type-Options + + + + + + + + +# Determine the RewriteBase automatically and set it as environment variable. + +# If you are using Apache aliases to do mass virtual hosting or installed the + +# project in a subdirectory, the base path will be prepended to allow proper + +# resolution of the app.php file and to redirect to the correct URI. It will + +# work in environments without path prefix as well, providing a safe, one-size + +# fits all solution. But as you do not need it in this case, you can comment + +# the following 2 lines to eliminate the overhead. + +RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ + +RewriteRule ^(.*) - [E=BASE:%1] + + + + +# Sets the HTTP_AUTHORIZATION header removed by Apache + +RewriteCond %{HTTP:Authorization} . + +RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + + + +# Redirect to URI without front controller to prevent duplicate content + +# (with and without `/app.php`). Only do this redirect on the initial + +# rewrite by Apache and not on subsequent cycles. Otherwise we would get an + +# endless redirect loop (request -> rewrite to front controller -> + +# redirect -> request -> ...). + +# So in case you get a "too many redirects" error or you always get redirected + +# to the start page because your Apache does not expose the REDIRECT_STATUS + +# environment variable, you have 2 choices: + +# - disable this feature by commenting the following 2 lines or + +# - use Apache >= 2.3.9 and replace all L flags by END flags and remove the + +# following RewriteCond (best solution) + +RewriteCond %{ENV:REDIRECT_STATUS} ^$ + +RewriteRule ^app\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L] + + + + + + + RewriteCond %{REQUEST_URI} ^/(fpm|server)-(info|status|ping) + + RewriteRule . - [L] + + + + + + +# restrict access to dotfiles + +RewriteCond %{REQUEST_FILENAME} -d [OR] + +RewriteCond %{REQUEST_FILENAME} -l [OR] + +RewriteCond %{REQUEST_FILENAME} -f + +RewriteRule /\.|^\.(?!well-known/) - [F,L] + + + + +# ASSETS: check if request method is GET (because of WebDAV) and if the requested file (asset) exists on the filesystem, if both match, deliver the asset directly + +RewriteCond %{REQUEST_METHOD} ^(GET|HEAD) + +RewriteCond %{DOCUMENT_ROOT}/var/assets%{REQUEST_URI} -f + +RewriteRule ^(.*)$ /var/assets%{REQUEST_URI} [PT,L] + + + + +# Thumbnails + +RewriteCond %{REQUEST_URI} .*/(image|video)-thumb__[\d]+__.* + +RewriteCond %{DOCUMENT_ROOT}/var/tmp/%1-thumbnails%{REQUEST_URI} -f + +RewriteRule ^(.*)$ /var/tmp/%1-thumbnails%{REQUEST_URI} [PT,L] + + + + +# cache-buster rule for scripts & stylesheets embedded using view helpers + +RewriteRule ^cache-buster\-[\d]+/(.*) $1 [PT,L] + + + + +# If the requested filename exists, simply serve it. + +# We only want to let Apache serve files and not directories. + +RewriteCond %{REQUEST_FILENAME} -f + +RewriteRule ^ - [L] + + + + +# Rewrite all other queries to the front controller. + +RewriteRule ^ %{ENV:BASE}/index_test.php [L] + + + + + + + + + + + + + +########################################## + +### OPTIONAL PERFORMANCE OPTIMIZATIONS ### + +########################################## + + + + + + + # Force compression for mangled headers. + + # http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping + + + + + + SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding + + RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding + + + + + + + + + # Compress all output labeled with one of the following MIME-types + + # (for Apache versions below 2.3.7, you don't need to enable `mod_filter` + + # and can remove the `` and `` lines + + # as `AddOutputFilterByType` is still in the core directives). + + + + AddOutputFilterByType DEFLATE application/atom+xml application/javascript application/json \ + + application/vnd.ms-fontobject application/x-font-ttf application/rss+xml \ + + application/x-web-app-manifest+json application/xhtml+xml \ + + application/xml font/opentype image/svg+xml image/x-icon \ + + text/css text/html text/plain text/x-component text/xml text/javascript + + + + + + + + + + + ExpiresActive on + + ExpiresDefault "access plus 31536000 seconds" + + + + + # specific overrides + + #ExpiresByType text/css "access plus 1 year" + + + + + + + + + # pimcore mod_pagespeed integration + + # pimcore automatically disables mod_pagespeed in the following situations: debug-mode on, /admin, preview, editmode, ... + + # if you want to disable pagespeed for specific actions in pimcore you can use $this->disableBrowserCache() in your action + + RewriteCond %{REQUEST_URI} ^/(mod_)?pagespeed_(statistics|message|console|beacon|admin|global_admin) + + RewriteRule . - [L] + + + + + ModPagespeed Off + + AddOutputFilterByType MOD_PAGESPEED_OUTPUT_FILTER text/html + + ModPagespeedModifyCachingHeaders off + + ModPagespeedRewriteLevel PassThrough + + # low risk filters + + ModPagespeedEnableFilters remove_comments,recompress_images + + # low and moderate filters, recommended filters, but can cause problems + + ModPagespeedEnableFilters lazyload_images,extend_cache_images,inline_preview_images,sprite_images + + ModPagespeedEnableFilters combine_css,rewrite_css,move_css_to_head,flatten_css_imports,extend_cache_css,prioritize_critical_css + + ModPagespeedEnableFilters extend_cache_scripts,combine_javascript,canonicalize_javascript_libraries,rewrite_javascript + + # high risk + + #ModPagespeedEnableFilters defer_javascript,local_storage_cache + + \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.github/ci/files/public/index_test.php b/bundles/PersonalizationBundle/.github/ci/files/public/index_test.php new file mode 100644 index 00000000000..5ade43af06f --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/files/public/index_test.php @@ -0,0 +1,41 @@ +handle ($request); +$response->send (); + +$kernel->terminate ($request, $response); diff --git a/bundles/PersonalizationBundle/.github/ci/files/templates/.gitkeep b/bundles/PersonalizationBundle/.github/ci/files/templates/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/bundles/PersonalizationBundle/.github/ci/scripts/setup-pimcore-environment.sh b/bundles/PersonalizationBundle/.github/ci/scripts/setup-pimcore-environment.sh new file mode 100755 index 00000000000..d22d2bce43d --- /dev/null +++ b/bundles/PersonalizationBundle/.github/ci/scripts/setup-pimcore-environment.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +set -eu + +#cp -rv .github/ci/files/var . +mkdir -p var/config +mkdir -p bin + +cp .github/ci/files/.env . +cp -r .github/ci/files/config/. config +cp -r .github/ci/files/templates/. templates +cp -r .github/ci/files/bin/console bin/console +chmod 755 bin/console +cp -r .github/ci/files/kernel/. kernel +cp -r .github/ci/files/public/. public \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.gitignore b/bundles/PersonalizationBundle/.gitignore new file mode 100644 index 00000000000..de789b9fea0 --- /dev/null +++ b/bundles/PersonalizationBundle/.gitignore @@ -0,0 +1,68 @@ +.DS_Store +Thumbs.db +*.log + +# symfony default +/.web-server-pid +/app/config/parameters.yml +/build/ +/phpunit.xml +/web/bundles/ + +# local config +!/app/config/local +/app/config/local/* +!app/config/local/.gitkeep + +# pimcore legacy (remove this for your own development) +!/legacy +/legacy/* +!legacy/.gitkeep +!legacy/bundle + +/var/* +!/var/.gitkeep +!/var/classes/ +/var/classes/DataObject + +!/var/config +/var/config/system.php +/var/config/debug-mode.php +/var/config/maintenance.php + +# project specific recommendations +/var/config/tag-manager.php +/var/config/reports.php + + +/web/var/ + +# PHP-CS-Fixer +/.php_cs +/.php_cs.cache + +# composer +/composer.lock +!/vendor +/vendor/* +!/vendor/.gitkeep + +# PhpStorm / IDEA +.idea +.idea_modules +# NetBeans +nbproject + +node_modules/ + +# codeception (only stage *.dist.yml config files) +/codeception.yml +/pimcore/codeception.yml +/pimcore/tests/*.suite.yml +/pimcore/tests/_output/* +/pimcore/tests/_support/_generated/* + +# keep legacy paths ignored for easier migration +/plugins/ +/tools/ +/website/ \ No newline at end of file diff --git a/bundles/PersonalizationBundle/.php_cs.dist b/bundles/PersonalizationBundle/.php_cs.dist new file mode 100644 index 00000000000..7eb28332c11 --- /dev/null +++ b/bundles/PersonalizationBundle/.php_cs.dist @@ -0,0 +1,71 @@ +in([__DIR__ . '/src']) + + // do not fix views + ->notName('*.html.php'); + +return PhpCsFixer\Config::create() + ->setRules([ + '@PSR1' => true, + '@PSR2' => true, + 'array_syntax' => ['syntax' => 'short'], + + 'header_comment' => [ + 'commentType' => 'PHPDoc', + 'header' => 'Pimcore' . PHP_EOL . PHP_EOL . + 'This source file is available under two different licenses:' . PHP_EOL . + '- GNU General Public License version 3 (GPLv3)' . PHP_EOL . + '- Pimcore Commercial License (PCL)' . PHP_EOL . + 'Full copyright and license information is available in' . PHP_EOL . + 'LICENSE.md which is distributed with this source code.' . PHP_EOL . + PHP_EOL . + ' @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)' . PHP_EOL . + ' @license http://www.pimcore.org/license GPLv3 and PCL' + ], + + // keep aligned = and => operators as they are: do not force aligning, but do not remove it + 'binary_operator_spaces' => ['align_double_arrow' => null, 'align_equals' => null], + + 'blank_line_before_return' => true, + 'encoding' => true, + 'function_typehint_space' => true, + 'hash_to_slash_comment' => true, + 'lowercase_cast' => true, + 'magic_constant_casing' => true, + 'method_argument_space' => ['ensure_fully_multiline' => false], + 'method_separation' => true, + 'native_function_casing' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_consecutive_blank_lines' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_short_bool_cast' => true, + 'no_spaces_around_offset' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unused_imports' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'object_operator_without_whitespace' => true, + 'ordered_imports' => true, + 'phpdoc_indent' => true, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_scalar' => true, + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'return_type_declaration' => true, + 'self_accessor' => true, + 'short_scalar_cast' => true, + 'single_blank_line_before_namespace' => true, + 'single_quote' => true, + 'space_after_semicolon' => true, + 'standardize_not_equals' => true, + 'ternary_operator_spaces' => true, + 'whitespace_after_comma_in_array' => true, + ]) + ->setFinder($finder); \ No newline at end of file diff --git a/bundles/PersonalizationBundle/LICENSE.md b/bundles/PersonalizationBundle/LICENSE.md new file mode 100644 index 00000000000..4dd4db4dfea --- /dev/null +++ b/bundles/PersonalizationBundle/LICENSE.md @@ -0,0 +1,36 @@ +# License +Copyright (C) Pimcore GmbH + +This software is available under two different licenses: +* GNU General Public License version 3 (GPLv3) as Pimcore Community Edition +* Pimcore Commercial License (PCL) + +The default Pimcore license, without a valid Pimcore Commercial License agreement, is the Open-Source GPLv3 license. + +## GNU General Public License version 3 (GPLv3) +If you decide to choose the GPLv3 license, you must comply with the following terms: + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +## Pimcore Commercial License (PCL) +Alternatively, commercial and supported versions of the program - also known as +Commercial Distributions - must be used in accordance with the terms and conditions +contained in a separate written agreement between you and Pimcore GmbH. +For more information about the Pimcore Commercial License (PCL) please contact info@pimcore.com. + + + +Please see also (files in this directory): +- [Licensing FAQ - license-faq.md](https://github.com/pimcore/pimcore/blob/master/license-faq.md) +- [GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - gpl-3.0.txt](gpl-3.0.txt) \ No newline at end of file diff --git a/doc/User_Documentation/08_Targeting_and_Personalization/README.md b/bundles/PersonalizationBundle/README.md similarity index 58% rename from doc/User_Documentation/08_Targeting_and_Personalization/README.md rename to bundles/PersonalizationBundle/README.md index c9b76ea4901..9eba5f0c5c5 100644 --- a/doc/User_Documentation/08_Targeting_and_Personalization/README.md +++ b/bundles/PersonalizationBundle/README.md @@ -6,14 +6,14 @@ these target groups. This makes it possible to show contextual, relevant, and pe Before starting with Personalization you should know about following Pimcore concepts: -* [Target Group](./01_Concepts.md#page_Target-Group) -* [Global Targeting Rule](./01_Concepts.md#page_Global-Targeting-Rule) -* [Personalized Document Content](./01_Concepts.md#page_Personalized-Document-Content) +* [Target Group](./doc/User_Documentation/01_Concepts.md#page_Target-Group) +* [Global Targeting Rule](./doc/User_Documentation/01_Concepts.md#page_Global-Targeting-Rule) +* [Personalized Document Content](./doc/User_Documentation/01_Concepts.md#page_Personalized-Document-Content) After reading everything about the base concepts, you are -[ready to get started with personalizing content](./03_How_to_Personalize_Content/README.md). +[ready to get started with personalizing content](./doc/User_Documentation/03_How_to_Personalize_Content/README.md). > For details on how to extend Pimcores targeting engine and use targeting information in custom modules - > see our [Dev Docs](../../Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/README.md) + > see our [Dev Docs](./doc/Development_Documentation/README.md) diff --git a/bundles/PersonalizationBundle/SECURITY.md b/bundles/PersonalizationBundle/SECURITY.md new file mode 100644 index 00000000000..53173b7ce02 --- /dev/null +++ b/bundles/PersonalizationBundle/SECURITY.md @@ -0,0 +1,20 @@ +# Security Policy + +## Reporting a Vulnerability + +If you think that you have found a security issue, +don’t use the bug tracker and don’t publish it publicly. +Instead, all security issues must be reported via 📫 to [security-issue@pimcore.com](mailto:security-issue@pimcore.com). + + +## Resolving Process +Every submitted security issue is handled with top priority by following these steps: + +1. Confirm the vulnerability +2. Determine the severity +3. Contact reporter +4. Work on a patch +5. Get a CVE identification number (may be done by the reporter or a security service provider) +6. Patch reviewing +7. Tagging a new release for supported versions +8. Publish security announcement \ No newline at end of file diff --git a/bundles/PersonalizationBundle/codeception.dist.yml b/bundles/PersonalizationBundle/codeception.dist.yml new file mode 100644 index 00000000000..e3a88caa27c --- /dev/null +++ b/bundles/PersonalizationBundle/codeception.dist.yml @@ -0,0 +1,17 @@ +namespace: Pimcore\Bundle\PersonalizationBundle\Tests +actor_suffix: Tester +paths: + tests: tests + output: tests/_output + data: tests/Support/Data + support: tests/Support + envs: tests/_envs +settings: + colors: true + memory_limit: 1024M +bootstrap: _bootstrap.php +params: + - env +extensions: + enabled: + - Codeception\Extension\RunFailed \ No newline at end of file diff --git a/bundles/PersonalizationBundle/composer.json b/bundles/PersonalizationBundle/composer.json new file mode 100644 index 00000000000..5a17d232601 --- /dev/null +++ b/bundles/PersonalizationBundle/composer.json @@ -0,0 +1,45 @@ +{ + "name": "pimcore/personalization-bundle", + "license": "GPL-3.0+", + "type": "pimcore-bundle", + "description": "Pimcore Personalization Bundle", + "config": { + "sort-packages": true, + "preferred-install": { + "pimcore/pimcore": "source", + "*": "dist" + } + }, + "prefer-stable": true, + "minimum-stability": "dev", + "require": { + "pimcore/pimcore": "^11.0", + "geoip2/geoip2": "^2.9" + }, + "require-dev": { + "phpstan/phpstan": "^1.9", + "codeception/codeception": "^5.0.3", + "codeception/phpunit-wrapper": "^9" + }, + "autoload": { + "psr-4": { + "Pimcore\\Bundle\\PersonalizationBundle\\": "src/", + "Pimcore\\Model\\DataObject\\": "src/Pimcore/Model/DataObject" + } + }, + "autoload-dev": { + "psr-4": { + "Pimcore\\Bundle\\PersonalizationBundle\\Tests\\": "tests" + }, + "files": [ + "kernel/Kernel.php" + ] + }, + "extra": { + "pimcore": { + "bundles": [ + "Pimcore\\Bundle\\PersonalizationBundle\\PimcorePersonalizationBundle" + ] + } + } +} \ No newline at end of file diff --git a/bundles/PersonalizationBundle/config/pimcore/config.yaml b/bundles/PersonalizationBundle/config/pimcore/config.yaml new file mode 100644 index 00000000000..74f488660fa --- /dev/null +++ b/bundles/PersonalizationBundle/config/pimcore/config.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: default.yaml } \ No newline at end of file diff --git a/bundles/PersonalizationBundle/config/pimcore/default.yaml b/bundles/PersonalizationBundle/config/pimcore/default.yaml new file mode 100644 index 00000000000..a2d655733b0 --- /dev/null +++ b/bundles/PersonalizationBundle/config/pimcore/default.yaml @@ -0,0 +1,42 @@ +pimcore_personalization: + targeting: + data_providers: + device: Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\Device + geoip: Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\GeoIp + geolocation: Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\GeoLocation + targeting_storage: Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\TargetingStorage + visited_pages_counter: Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\VisitedPagesCounter + conditions: + browser: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\Browser + country: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\Country + geopoint: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\GeoPoint + hardwareplatform: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\HardwarePlatform + language: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\Language + operatingsystem: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\OperatingSystem + referringsite: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\ReferringSite + searchengine: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\SearchEngine + target_group: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\TargetGroup + timeonsite: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\TimeOnSite + url: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\Url + visitedpagesbefore: Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\VisitedPagesBefore + action_handlers: + assign_target_group: Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\AssignTargetGroup + codesnippet: Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\CodeSnippet + redirect: Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\Redirect +pimcore: + documents: + type_definitions: + map: + snippet: Pimcore\Bundle\PersonalizationBundle\Model\Document\Snippet + page: Pimcore\Bundle\PersonalizationBundle\Model\Document\Page + objects: + class_definitions: + data: + map: + targetGroup: Pimcore\Model\DataObject\ClassDefinition\Data\TargetGroup + targetGroupMultiselect: Pimcore\Model\DataObject\ClassDefinition\Data\TargetGroupMultiselect + +pimcore_ecommerce_framework: + pricing_manager: + conditions: + TargetGroup: \Pimcore\Bundle\PersonalizationBundle\Ecommerce\PricingManager\Condition\TargetGroup diff --git a/bundles/PersonalizationBundle/config/pimcore/routing.yaml b/bundles/PersonalizationBundle/config/pimcore/routing.yaml new file mode 100644 index 00000000000..2fc5eb624cc --- /dev/null +++ b/bundles/PersonalizationBundle/config/pimcore/routing.yaml @@ -0,0 +1,6 @@ +_pimcore_bundle_personalization_backend: + resource: "../../src/Controller/" + type: annotation + prefix: /admin/bundle/personalization + options: + expose: true \ No newline at end of file diff --git a/bundles/PersonalizationBundle/config/targeting.yaml b/bundles/PersonalizationBundle/config/targeting.yaml new file mode 100644 index 00000000000..f8d66cbd216 --- /dev/null +++ b/bundles/PersonalizationBundle/config/targeting.yaml @@ -0,0 +1,162 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + # + # TARGETING STORAGE + # + # The TargetingStorageInterface alias will be set to whatever service_id is configured + # in pimcore_personalization.targeting.service_id. The services below are just the core storages, but + # it's possible to define a custom service which can be configured via service_id. + # + + # Cookie + Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Cookie\JWTCookieSaveHandler: + arguments: + $secret: '%kernel.secret%' + + # NOTE: using this save handler is inherently insecure and can open vulnerabilities by injecting malicious data into the + # client cookie. Use only for testing! + Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Cookie\JsonCookieSaveHandler: ~ + + Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\CookieStorage: + arguments: + $saveHandler: '@Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Cookie\JWTCookieSaveHandler' + + # Session Storage. If this is used, the pimcore_personalization.targeting.session.enabled entry + # must be set to true to load the session configurator. + Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\SessionStorage: ~ + + # Database + Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\DbStorage: ~ + + # Example for redis + # pimcore_personalization.targeting.storage.redis.connection: + # class: Credis_Client + # factory: [Pimcore\Storage\Redis\ConnectionFactory, createConnection] + # arguments: + # - { server: 127.0.0.1, database: 7 } + + # Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\RedisStorage: + # arguments: + # $redis: '@pimcore_personalization.targeting.storage.redis.connection' + + # Example for fallback + # Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\FallbackStorage: + # arguments: + # $primaryStorage: '@Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\DbStorage' + # $fallbackStorage: '@Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\CookieStorage' + + + # + # VISITOR INFO + # + + Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface: '@Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorage' + Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorage: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoResolver: ~ + + + # + # DATA PROVIDERS + # + + GeoIp2\ProviderInterface: '@GeoIp2\Database\Reader' + GeoIp2\Database\Reader: + arguments: + $filename: '%pimcore.geoip.db_file%' + + Pimcore\Bundle\PersonalizationBundle\Targeting\DataLoaderInterface: '@Pimcore\Bundle\PersonalizationBundle\Targeting\DataLoader' + Pimcore\Bundle\PersonalizationBundle\Targeting\DataLoader: ~ + + Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\GeoIp: + calls: + - [ setCache, [ '@Pimcore\Cache\Core\CoreCacheHandler' ] ] + + Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\GeoLocation: ~ + + Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\Device: + calls: + - [ setCache, [ '@Pimcore\Cache\Core\CoreCacheHandler' ] ] + - [ setCachePool, [ '@pimcore.cache.pool' ] ] + + Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\TargetingStorage: ~ + + Pimcore\Bundle\PersonalizationBundle\Targeting\Service\VisitedPagesCounter: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\VisitedPagesCounter: ~ + + + # + # CONDITIONS + # + + Pimcore\Bundle\PersonalizationBundle\Targeting\ConditionFactoryInterface: '@Pimcore\Bundle\PersonalizationBundle\Targeting\ConditionFactory' + Pimcore\Bundle\PersonalizationBundle\Targeting\ConditionFactory: + arguments: + $conditions: '%pimcore_personalization.targeting.conditions%' + + pimcore_personalization.targeting.condition_matcher.expression_language: + class: Symfony\Component\ExpressionLanguage\ExpressionLanguage + arguments: + $cache: '@pimcore.cache.pool' + + Pimcore\Bundle\PersonalizationBundle\Targeting\ConditionMatcherInterface: '@Pimcore\Bundle\PersonalizationBundle\Targeting\ConditionMatcher' + Pimcore\Bundle\PersonalizationBundle\Targeting\ConditionMatcher: + arguments: + $expressionLanguage: '@pimcore_personalization.targeting.condition_matcher.expression_language' + + + # + # ACTION HANDLERS + # + + Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\ActionHandlerInterface: '@Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\DelegatingActionHandler' + Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\DelegatingActionHandler: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\AssignTargetGroup: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\Redirect: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\CodeSnippet: ~ + + + # + # DOCUMENT HANDLING + # + + Pimcore\Bundle\PersonalizationBundle\Targeting\Document\DocumentTargetingConfigurator: + public: true + + + # + # TARGETING CODE + # + + Pimcore\Bundle\PersonalizationBundle\Targeting\Code\TargetingCodeGenerator: ~ + + # + # TOOLBAR AND PROFILER + # + + Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\TargetingDataCollector: ~ + + Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\OverrideHandler: + lazy: true + arguments: + # injected by TargetingOverrideHandlersPass + $overrideHandlers: '?@' + + Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Override\DocumentTargetingOverrideHandler: + tags: + - { name: pimcore_personalization.targeting.override_handler, priority: 500 } + + Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Override\LanguageOverrideHandler: + tags: + - { name: pimcore_personalization.targeting.override_handler, priority: 475 } + + Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Override\DeviceOverrideHandler: + tags: + - { name: pimcore_personalization.targeting.override_handler, priority: 450 } + + Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Override\LocationOverrideHandler: + tags: + - { name: pimcore_personalization.targeting.override_handler, priority: 425 } diff --git a/bundles/PersonalizationBundle/config/targeting/listeners.yaml b/bundles/PersonalizationBundle/config/targeting/listeners.yaml new file mode 100644 index 00000000000..b28c8ba7358 --- /dev/null +++ b/bundles/PersonalizationBundle/config/targeting/listeners.yaml @@ -0,0 +1,22 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\TargetingListener: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\DocumentTargetGroupListener: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\Frontend\FullPageCacheCookieCleanupListener: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\VisitedPagesCountListener: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\ToolbarListener: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\TargetingSessionBagListener: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\Frontend\TargetingElementListener: ~ + Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\Frontend\TargetingDocumentRendererListener: ~ + + Pimcore\Bundle\CoreBundle\EventListener\Frontend\FullPageCacheListener: + class: Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\TargetingFullPageCacheListener + public: true + tags: + - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: 120 } + - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse, priority: -120 } + - { name: kernel.event_listener, event: kernel.response, method: stopPropagationCheck, priority: 100 } diff --git a/bundles/PersonalizationBundle/config/targeting/services.yaml b/bundles/PersonalizationBundle/config/targeting/services.yaml new file mode 100644 index 00000000000..d0249f7655d --- /dev/null +++ b/bundles/PersonalizationBundle/config/targeting/services.yaml @@ -0,0 +1,42 @@ +services: + _defaults: + public: false + autowire: true + autoconfigure: true + + # + # INSTALLER + # + Pimcore\Bundle\PersonalizationBundle\Installer: + public: true + arguments: + $bundle: "@=service('kernel').getBundle('PimcorePersonalizationBundle')" + + # auto-register all controllers as services + Pimcore\Bundle\PersonalizationBundle\Controller\: + resource: '../src/Controller' + public: true + tags: [ 'controller.service_arguments' ] + + Pimcore\Bundle\PersonalizationBundle\Targeting\Maintenance\TargetingStorageTask: ~ + + Pimcore\Bundle\PersonalizationBundle\DataCollector\PimcoreTargetingDataCollector: + tags: + - name: data_collector + template: '@PimcorePersonalization/Profiler/targeting_data_collector.html.twig' + id: 'pimcore_targeting' + priority: 312 + + # + # Event Listeners + # + + Pimcore\Bundle\PersonalizationBundle\EventListener\IndexSettingsListener: + tags: + - { name: kernel.event_listener, event: pimcore.admin.indexAction.settings, method: indexSettings } + + # Newsletter Adapter + pimcore.document.newsletter.factory.default: + class: Pimcore\Document\Newsletter\DefaultAddressSourceAdapterFactory + arguments: + - 'Pimcore\Bundle\PersonalizationBundle\Document\Newsletter\AddressSourceAdapter\DefaultAdapter' diff --git a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/01_Visitor_Info.md b/bundles/PersonalizationBundle/doc/Development_Documentation/01_Visitor_Info.md similarity index 93% rename from doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/01_Visitor_Info.md rename to bundles/PersonalizationBundle/doc/Development_Documentation/01_Visitor_Info.md index 90e49c301fc..9fe59bf5a7a 100644 --- a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/01_Visitor_Info.md +++ b/bundles/PersonalizationBundle/doc/Development_Documentation/01_Visitor_Info.md @@ -46,7 +46,7 @@ As an example, a sample service working with the `VisitorInfo`: namespace App\Targeting; -use Pimcore\Targeting\VisitorInfoStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface; class MyService { @@ -91,7 +91,7 @@ services: # if you don't use autowiring you need to manually wire your dependency App\Targeting\MyService: arguments: - $visitorInfoStorage: '@Pimcore\Targeting\VisitorInfoStorageInterface' + $visitorInfoStorage: '@Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface' ``` If your controllers are defined as services, you can make use of argument injection: @@ -101,7 +101,7 @@ If your controllers are defined as services, you can make use of argument inject namespace App\Controller; -use Pimcore\Targeting\VisitorInfoStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Routing\Annotation\Route; diff --git a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/03_Conditions.md b/bundles/PersonalizationBundle/doc/Development_Documentation/03_Conditions.md similarity index 81% rename from doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/03_Conditions.md rename to bundles/PersonalizationBundle/doc/Development_Documentation/03_Conditions.md index 3b53901f7bd..6f69a980697 100644 --- a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/03_Conditions.md +++ b/bundles/PersonalizationBundle/doc/Development_Documentation/03_Conditions.md @@ -5,17 +5,17 @@ to implement `match()` method which always returns a boolean. To implement a condition, you need to implement 2 parts: -* A PHP class implementing the [`ConditionInterface`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/Condition/ConditionInterface.php). - Have a look at [existing implementations](https://github.com/pimcore/pimcore/tree/11.x/lib/Targeting/Condition) +* A PHP class implementing the [`ConditionInterface`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/Condition/ConditionInterface.php). + Have a look at [existing implementations](https://github.com/pimcore/personalization-bundle/tree/main/src/Targeting/Condition) to get an idea how to implement your own conditions. -* A frontend JS class defining the admin UI for your condition. You can have a look at [Pimcore's core conditions](https://github.com/pimcore/pimcore/blob/11.x/bundles/AdminBundle/public/js/pimcore/settings/targeting/conditions.js) +* A frontend JS class defining the admin UI for your condition. You can have a look at [this bundle's conditions](https://github.com/pimcore/personalization-bundle/blob/main/public/js/settings/conditions.js) for UI examples and at the [Customer Management Framework](https://github.com/pimcore/customer-data-framework/blob/master/src/Resources/public/js/pimcore/targeting/conditions.js) as example for a third-party integration. ## Implementing a Condition -As stated before, a condition needs to implement the [`ConditionInterface`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/Condition/ConditionInterface.php). +As stated before, a condition needs to implement the [`ConditionInterface`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/Condition/ConditionInterface.php). The most important method in the interface is the `match()` method which receives the current `VisitorInfo` instance and is expected to return a boolean which indicates if the condition matches or not. @@ -32,8 +32,8 @@ hour, not the full time. namespace App\Targeting\Condition; -use Pimcore\Targeting\Condition\ConditionInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\ConditionInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class TimeOfTheDay implements ConditionInterface { @@ -79,7 +79,7 @@ After implementing your condition, you need to register it to the system with th name when implementing the JS class. ```yaml -pimcore: +pimcore_personalization: targeting: conditions: timeoftheday: App\Targeting\Condition\TimeOfTheDay @@ -88,7 +88,7 @@ pimcore: ### Building a Condition Instance -When an instance of your condition is build, by default the [`ConditionFactory`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/ConditionFactory.php) +When an instance of your condition is build, by default the [`ConditionFactory`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/ConditionFactory.php) will call the static `fromConfig()` method with the data configured in the admin UI. Avoid injecting any services or custom data into your condition and use the data provider system instead to add data to the `VisitorInfo`. However, if you need more control over how your condition is built you can either: @@ -102,19 +102,19 @@ you need more control over how your condition is built you can either: ## Condition Data -If your condition needs any outside data, implement the [`DataProviderDependentInterface`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/DataProviderDependentInterface.php) +If your condition needs any outside data, implement the [`DataProviderDependentInterface`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/DataProviderDependentInterface.php) and define a list of data provider keys which need to be set on the `VisitorInfo` before matching. We'll enhance our `TimeOfTheDay` -condition on the [Data Providers](./05_Data_Providers.md) chapter. For further examples, you can take a look at [existing core conditions](https://github.com/pimcore/pimcore/tree/11.x/pimcore/lib/Pimcore/Targeting/Condition). +condition on the [Data Providers](./05_Data_Providers.md) chapter. For further examples, you can take a look at [existing core conditions](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/Condition). ## Condition Variables -An important part are [variable conditions](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/Condition/VariableConditionInterface.php) +An important part are [variable conditions](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/Condition/VariableConditionInterface.php) which support the `session_with_variables` rule matching scope. A condition implementing this interface is expected to return an array of the variables which led to match the condition in the `getMatchedVariables()` method. This data will be used to determine if the rule was already applied with the exact same data. -You should implement this interface whenever possible. To get started, you can use the [`AbstractVariableCondition`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/Condition/AbstractVariableCondition.php) +You should implement this interface whenever possible. To get started, you can use the [`AbstractVariableCondition`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/Condition/AbstractVariableCondition.php) which contains helper methods to collect variable data. Make sure you build your data in a deterministic way (e.g. using the same order of keys in an array structure or the same format when serializing data) as a hash of this data is used to compare it to previous evaluations in order to decide if a rule needs to be applied. @@ -131,8 +131,8 @@ resolved current hour. namespace App\Targeting\Condition; -use Pimcore\Targeting\Condition\AbstractVariableCondition; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\AbstractVariableCondition; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class TimeOfTheDay extends AbstractVariableCondition { @@ -156,10 +156,10 @@ class TimeOfTheDay extends AbstractVariableCondition ## Admin UI To make your condition configurable, you need to create a JS class defining the admin interface for your condition. To do -so, create a class extending `pimcore.settings.targeting.condition.abstract` and register it to the system by calling -`pimcore.settings.targeting.conditions.register()`. +so, create a class extending `pimcore.bundle.personalization.settings.condition.abstract` and register it to the system by calling +`pimcore.bundle.personalization.settings.conditions.register()`. -Have a look at [Pimcore's core conditions](https://github.com/pimcore/pimcore/blob/11.x/bundles/AdminBundle/public/js/pimcore/settings/targeting/conditions.js) +Have a look at [this bundle's conditions](https://github.com/pimcore/personalization-bundle/blob/main/public/js/settings/conditions.js) and the [Customer Management Framework](https://github.com/pimcore/customer-data-framework/blob/master/src/Resources/public/js/pimcore/targeting/conditions.js) for examples. @@ -171,9 +171,9 @@ Start by adding a new JS file implementing the admin UI panel for your condition (function () { 'use strict'; - pimcore.settings.targeting.conditions.register( + pimcore.bundle.personalization.settings.conditions.register( 'timeoftheday', - Class.create(pimcore.settings.targeting.condition.abstract, { + Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return 'Time of the Day'; }, @@ -191,7 +191,7 @@ Start by adding a new JS file implementing the admin UI panel for your condition forceLayout: true, style: 'margin: 10px 0 0 0', bodyStyle: 'padding: 10px 30px 10px 30px; min-height:40px;', - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [ { name: 'hour', diff --git a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/05_Data_Providers.md b/bundles/PersonalizationBundle/doc/Development_Documentation/05_Data_Providers.md similarity index 83% rename from doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/05_Data_Providers.md rename to bundles/PersonalizationBundle/doc/Development_Documentation/05_Data_Providers.md index bea59e87612..3cafc74f248 100644 --- a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/05_Data_Providers.md +++ b/bundles/PersonalizationBundle/doc/Development_Documentation/05_Data_Providers.md @@ -1,14 +1,14 @@ # Data Providers -A data provider is a service implementing the [`DataProviderInterface`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/DataProvider/DataProviderInterface.php). -Components (e.g. conditions) which implement the [`DataProviderDependentInterface`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/DataProviderDependentInterface.php) +A data provider is a service implementing the [`DataProviderInterface`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/DataProvider/DataProviderInterface.php). +Components (e.g. conditions) which implement the [`DataProviderDependentInterface`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/DataProviderDependentInterface.php) can define a set of data providers they depend on, triggering the data provider to load its data before the component is used. A data provider does not directly return its value, but is expected to set it on the `VisitorInfo` instance instead. As best practice, the core data providers expose their storage key as constant. This constant is used to store and retrieve -the data from the `VisitorInfo` storage. As example: the [GeoIP](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/DataProvider/GeoIp.php) -data provider defines the [GeoIP::PROVIDER_KEY](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/DataProvider/GeoIp.php#L28) +the data from the `VisitorInfo` storage. As example: the [GeoIP](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/DataProvider/GeoIp.php) +data provider defines the [GeoIP::PROVIDER_KEY](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/DataProvider/GeoIp.php#L28) constant which is used when storing and retrieving the data. ## Implementing a Data Provider @@ -33,8 +33,8 @@ reusable `DateTime` data provider which stores the current `DateTime` on the `Vi namespace App\Targeting\DataProvider; -use Pimcore\Targeting\DataProvider\DataProviderInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\DataProviderInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class DateTime implements DataProviderInterface { @@ -69,7 +69,7 @@ services: And register the provider to the targeting engine with its provider key: ```yaml -pimcore: +pimcore_personalization: targeting: data_providers: datetime: App\Targeting\DataProvider\DateTime @@ -90,9 +90,9 @@ provider: namespace App\Targeting\Condition; use App\Targeting\DataProvider\DateTime; -use Pimcore\Targeting\Condition\AbstractVariableCondition; -use Pimcore\Targeting\DataProviderDependentInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\AbstractVariableCondition; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProviderDependentInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class TimeOfTheDay extends AbstractVariableCondition implements DataProviderDependentInterface { diff --git a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/07_Action_Handlers.md b/bundles/PersonalizationBundle/doc/Development_Documentation/07_Action_Handlers.md similarity index 84% rename from doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/07_Action_Handlers.md rename to bundles/PersonalizationBundle/doc/Development_Documentation/07_Action_Handlers.md index 91c879c0ba8..cc96b6e100c 100644 --- a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/07_Action_Handlers.md +++ b/bundles/PersonalizationBundle/doc/Development_Documentation/07_Action_Handlers.md @@ -1,15 +1,15 @@ # Action Handlers After a targeting rule matched it executes one or more actions as configured in the admin UI. These actions are actually -executed by action handlers, which are services implementing the [`ActionHandlerInterface`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/ActionHandler/ActionHandlerInterface.php). +executed by action handlers, which are services implementing the [`ActionHandlerInterface`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/ActionHandler/ActionHandlerInterface.php). As with conditions, an action handler consists of 2 parts: -* A PHP class implementing the [`ActionHandlerInterface`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/ActionHandler/ActionHandlerInterface.php). - Have a look at [existing implementations](https://github.com/pimcore/pimcore/tree/11.x/pimcore/lib/Pimcore/Targeting/ActionHandler) +* A PHP class implementing the [`ActionHandlerInterface`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/ActionHandler/ActionHandlerInterface.php). + Have a look at [existing implementations](https://github.com/pimcore/personalization-bundle/tree/main/src/Targeting/Targeting/ActionHandler) to get an idea how to implement your own action handlers. * A frontend JS class defining the admin UI for your action handler as shown on the actions tab of a targeting rule. You - can have a look at [Pimcore's core actions](https://github.com/pimcore/pimcore/blob/11.x/bundles/AdminBundle/public/js/pimcore/settings/targeting/actions.js) + can have a look at [Pimcore's core actions](https://github.com/pimcore/personalization-bundle/blob/main/public/js/settings/actions.js) for UI examples and at the [Customer Management Framework](https://github.com/pimcore/customer-data-framework/blob/master/src/Resources/public/js/pimcore/targeting/actions.js) as example for a third-party integration. @@ -32,9 +32,9 @@ check those values before using them! namespace App\Targeting\ActionHandler; -use Pimcore\Model\Tool\Targeting\Rule; -use Pimcore\Targeting\ActionHandler\ActionHandlerInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\ActionHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Psr\Log\LoggerInterface; class Log implements ActionHandlerInterface @@ -83,7 +83,7 @@ As last step, register the action handler to the targeting engine. Make sure the as you'll need to use it when implementing the admin UI JS part. ```yaml -pimcore: +pimcore_personalization: targeting: action_handlers: log: App\Targeting\ActionHandler\Log @@ -95,7 +95,7 @@ If your action handler needs to apply data in a later stage of the request/respo the `VisitorInfo` which can be consumed later. Currently only the `response` action scope is defined which is executed in the `onKernelResponse` event, but more action scopes might be added in the future. -Have a look at the [CodeSnippet](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/ActionHandler/CodeSnippet.php) +Have a look at the [CodeSnippet](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/ActionHandler/CodeSnippet.php) action handler as example. It registers an action via `$visitorInfo->addAction()` and implements the `ResponseTransformingActionHandlerInterface::transformResponse()` which is called by the targeting engine for every action registered with the `response` scope. @@ -106,7 +106,7 @@ To make your action handler appear in the admin UI, you need to create and regis for your action. Create a class extending `pimcore.settings.targeting.action.abstract` and register it to the system by calling `pimcore.settings.targeting.actions.register()`. -Have a look at [Pimcore's core actions](https://github.com/pimcore/pimcore/blob/11.x/bundles/AdminBundle/public/js/pimcore/settings/targeting/actions.js) +Have a look at [this bundle's actions](https://github.com/pimcore/personalization-bundle/blob/main/public/js/settings/actions.js) and the [Customer Management Framework](https://github.com/pimcore/customer-data-framework/blob/master/src/Resources/public/js/pimcore/targeting/actions.js) for examples. @@ -118,9 +118,9 @@ Start by adding a new JS file implementing the admin UI panel for your action: (function () { 'use strict'; - pimcore.settings.targeting.actions.register( + pimcore.bundle.personalization.settings.actions.register( 'log', - Class.create(pimcore.settings.targeting.action.abstract, { + Class.create(pimcore.bundle.personalization.settings.action.abstract, { getName: function () { return 'Log'; }, @@ -133,7 +133,7 @@ Start by adding a new JS file implementing the admin UI panel for your action: forceLayout: true, style: 'margin: 10px 0 0 0', bodyStyle: 'padding: 10px 30px 10px 30px; min-height:40px;', - tbar: pimcore.settings.targeting.actions.getTopBar(this, id, panel), + tbar: pimcore.bundle.personalization.settings.actions.getTopBar(this, id, panel), items: [ { name: 'level', diff --git a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/09_Targeting_Storage.md b/bundles/PersonalizationBundle/doc/Development_Documentation/09_Targeting_Storage.md similarity index 91% rename from doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/09_Targeting_Storage.md rename to bundles/PersonalizationBundle/doc/Development_Documentation/09_Targeting_Storage.md index 0d4a927c9fd..5d54d4fdb82 100644 --- a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/09_Targeting_Storage.md +++ b/bundles/PersonalizationBundle/doc/Development_Documentation/09_Targeting_Storage.md @@ -20,17 +20,17 @@ The targeting storage needs to be defined as service and its service ID needs to entry: ```yaml -pimcore: +pimcore_personalization: targeting: - storage_id: Pimcore\Targeting\Storage\CookieStorage + storage_id: Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\CookieStorage ``` ## Implement a Custom Targeting Storage -Basically, a targeting storage is a class implementing the [`TargetingStorageInterface`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/Storage/TargetingStorageInterface.php) +Basically, a targeting storage is a class implementing the [`TargetingStorageInterface`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/Storage/TargetingStorageInterface.php) which is registered as service. Details how to handle data varies heavily on the underlying storage, but you can take the -[core storages](https://github.com/pimcore/pimcore/tree/11.x/lib/Targeting/Storage) as starting point. +[core storages](https://github.com/pimcore/personalization-bundle/tree/blob/main/src/Targeting/Storage) as starting point. ## Core Storage Implementations @@ -53,7 +53,7 @@ sure the cookie data isn't being tampered with. The cookie storage delegates the | `JWT` (default) | Stores cookie data as JWT signed JSON using the `kernel.secret` parameter to sign and verify the data. This is done to make sure the data can't be altered on the client side to inject malicious data into the targeting engine. | | | `JSON` | Stores cookie data as JSON string. | Use only for testing! | -To change the save handler, override the [service definition](https://github.com/pimcore/pimcore/blob/11.x/bundles/CoreBundle/Resources/config/targeting.yaml#L24) +To change the save handler, override the [service definition](https://github.com/pimcore/personalization-bundle/blob/main/config/targeting.yaml#L24) and set your own handler.
@@ -96,7 +96,7 @@ Cons ### Redis Stores data in a redis DB. To use this storage, define a service using the storage implementation as class and add connection -details to the service definition. An example is shipped with the [core service definitions](https://github.com/pimcore/pimcore/blob/11.x/bundles/CoreBundle/Resources/config/targeting.yaml#L35). +details to the service definition. An example is shipped with the [core service definitions](https://github.com/pimcore/personalization-bundle/blob/main/config/targeting.yaml#L35). Default session scope timeout: 30 minutes @@ -121,14 +121,14 @@ To use the session storage, an additional config entry is needed as the session performance reasons: ```yaml -pimcore: +pimcore_personalization: targeting: # enable session support session: enabled: true # use the session storage - storage_id: Pimcore\Targeting\Storage\SessionStorage + storage_id: Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\SessionStorage ``` Pros diff --git a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/11_Frontend_Javascript.md b/bundles/PersonalizationBundle/doc/Development_Documentation/11_Frontend_Javascript.md similarity index 87% rename from doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/11_Frontend_Javascript.md rename to bundles/PersonalizationBundle/doc/Development_Documentation/11_Frontend_Javascript.md index d9f3d80ae75..3731587ca9b 100644 --- a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/11_Frontend_Javascript.md +++ b/bundles/PersonalizationBundle/doc/Development_Documentation/11_Frontend_Javascript.md @@ -2,7 +2,7 @@ When targeting is enabled, a snippet of JavaScript in injected into every response. This snippet contains some information needed by the frontend regarding the application state (e.g. if debug mode is enabled) and includes the script -[`pimcore/static6/js/frontend/targeting.js`](https://github.com/pimcore/pimcore/blob/11.x/bundles/CoreBundle/Resources/public/js/targeting.js) +[`pimcore/static6/js/frontend/targeting.js`](https://github.com/pimcore/personalization-bundle/blob/main/public/js/targeting.js) which handles the frontend behaviour of the targeting engine (e.g. exposes an API to set the visitor ID). The whole targeting logic is handled inside the `window._ptg` object. @@ -25,8 +25,8 @@ Make sure to use a unique visitor ID for each visitor! ## Change/extend the code snippet injected into the Response -The code which is injected into the response is generated by the [`TargetingCodeGenerator`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/Code/TargetingCodeGenerator.php) -which fires a [TargetingEvents::TARGETING_CODE](https://github.com/pimcore/pimcore/blob/11.x/lib/Event/TargetingEvents.php#L30) +The code which is injected into the response is generated by the [`TargetingCodeGenerator`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/Code/TargetingCodeGenerator.php) +which fires a [TargetingEvents::TARGETING_CODE](https://github.com/pimcore/personalization-bundle/blob/main/src/Event/TargetingEvents.php#L30) event. This event can be used to influence data and the used template which is used to render the code snippet: @@ -37,9 +37,9 @@ event. This event can be used to influence data and the used template which is u namespace App\EventListener; -use Pimcore\Event\Targeting\TargetingCodeEvent; -use Pimcore\Event\TargetingEvents; -use Pimcore\Targeting\Code\TargetingCodeGenerator; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingCodeEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\TargetingEvents; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Code\TargetingCodeGenerator; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class TargetingCodeListener implements EventSubscriberInterface @@ -72,7 +72,7 @@ The listener above sets a custom template which can either extend the core one o ```twig {# templates/Targeting/targetingCode.html.twig #} -{% extends '@PimcoreCore/Targeting/targetingCode.html.twig' %} +{% extends '@PimcorePersonalization/Targeting/targetingCode.html.twig' %} {% block beforeScriptTag %} {{ parent() }} @@ -90,7 +90,7 @@ call `$visitorInfo->addFrontendDataProvider()` during the matching process to in a specific provider. These frontend data providers need to be implemented and registered to the frontend JS and are expected to deliver their data to the backend in some way (e.g. by storing data in a cookie or by sending it through an async request). -Currently, this feature is only sparsely used, but the [`GeoLocation`](https://github.com/pimcore/pimcore/blob/11.x/lib/Targeting/DataProvider/GeoLocation.php) +Currently, this feature is only sparsely used, but the [`GeoLocation`](https://github.com/pimcore/personalization-bundle/blob/main/src/Targeting/DataProvider/GeoLocation.php) data provider which can read the visitor location from browser geolocation data informs the frontend that it needs data from the `geolocation` frontend data provider. This information is added to the browser response, triggering the `targeting.js` to execute this frontend data provider. The data provider in turn stores its data as cookie which is consumed by the (backend) diff --git a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/README.md b/bundles/PersonalizationBundle/doc/Development_Documentation/README.md similarity index 98% rename from doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/README.md rename to bundles/PersonalizationBundle/doc/Development_Documentation/README.md index 7acc0e22998..44e03b5da4b 100644 --- a/doc/Development_Documentation/18_Tools_and_Features/37_Targeting_and_Personalization/README.md +++ b/bundles/PersonalizationBundle/doc/Development_Documentation/README.md @@ -1,6 +1,6 @@ # Targeting and Personalization -The following section describes the technical concepts and aspects of the Pimcore targeting enginge. For usage +The following section describes the technical concepts and aspects of the Pimcore targeting engine. For usage description and feature listing see your [user docs](../../../User_Documentation/08_Targeting_and_Personalization/README.md) first. @@ -110,7 +110,7 @@ namespace App\Controller; use Pimcore\Controller\FrontendController; use Pimcore\Model\Document; -use Pimcore\Targeting\Document\DocumentTargetingConfigurator; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Document\DocumentTargetingConfigurator; class ContentController extends FrontendController { diff --git a/doc/User_Documentation/08_Targeting_and_Personalization/01_Concepts.md b/bundles/PersonalizationBundle/doc/User_Documentation/01_Concepts.md similarity index 100% rename from doc/User_Documentation/08_Targeting_and_Personalization/01_Concepts.md rename to bundles/PersonalizationBundle/doc/User_Documentation/01_Concepts.md diff --git a/doc/User_Documentation/08_Targeting_and_Personalization/03_How_to_Personalize_Content/01_Define_Target_Groups.md b/bundles/PersonalizationBundle/doc/User_Documentation/03_How_to_Personalize_Content/01_Define_Target_Groups.md similarity index 100% rename from doc/User_Documentation/08_Targeting_and_Personalization/03_How_to_Personalize_Content/01_Define_Target_Groups.md rename to bundles/PersonalizationBundle/doc/User_Documentation/03_How_to_Personalize_Content/01_Define_Target_Groups.md diff --git a/doc/User_Documentation/08_Targeting_and_Personalization/03_How_to_Personalize_Content/03_Visitor_Profiling.md b/bundles/PersonalizationBundle/doc/User_Documentation/03_How_to_Personalize_Content/03_Visitor_Profiling.md similarity index 100% rename from doc/User_Documentation/08_Targeting_and_Personalization/03_How_to_Personalize_Content/03_Visitor_Profiling.md rename to bundles/PersonalizationBundle/doc/User_Documentation/03_How_to_Personalize_Content/03_Visitor_Profiling.md diff --git a/doc/User_Documentation/08_Targeting_and_Personalization/03_How_to_Personalize_Content/05_Create_Personalized_Content.md b/bundles/PersonalizationBundle/doc/User_Documentation/03_How_to_Personalize_Content/05_Create_Personalized_Content.md similarity index 100% rename from doc/User_Documentation/08_Targeting_and_Personalization/03_How_to_Personalize_Content/05_Create_Personalized_Content.md rename to bundles/PersonalizationBundle/doc/User_Documentation/03_How_to_Personalize_Content/05_Create_Personalized_Content.md diff --git a/doc/User_Documentation/08_Targeting_and_Personalization/03_How_to_Personalize_Content/07_Deliver_Personalized_Content_and_Debug.md b/bundles/PersonalizationBundle/doc/User_Documentation/03_How_to_Personalize_Content/07_Deliver_Personalized_Content_and_Debug.md similarity index 100% rename from doc/User_Documentation/08_Targeting_and_Personalization/03_How_to_Personalize_Content/07_Deliver_Personalized_Content_and_Debug.md rename to bundles/PersonalizationBundle/doc/User_Documentation/03_How_to_Personalize_Content/07_Deliver_Personalized_Content_and_Debug.md diff --git a/doc/User_Documentation/08_Targeting_and_Personalization/03_How_to_Personalize_Content/README.md b/bundles/PersonalizationBundle/doc/User_Documentation/03_How_to_Personalize_Content/README.md similarity index 100% rename from doc/User_Documentation/08_Targeting_and_Personalization/03_How_to_Personalize_Content/README.md rename to bundles/PersonalizationBundle/doc/User_Documentation/03_How_to_Personalize_Content/README.md diff --git a/doc/User_Documentation/08_Targeting_and_Personalization/05_Examples/README.md b/bundles/PersonalizationBundle/doc/User_Documentation/05_Examples/README.md similarity index 100% rename from doc/User_Documentation/08_Targeting_and_Personalization/05_Examples/README.md rename to bundles/PersonalizationBundle/doc/User_Documentation/05_Examples/README.md diff --git a/bundles/PersonalizationBundle/gpl-3.0.txt b/bundles/PersonalizationBundle/gpl-3.0.txt new file mode 100644 index 00000000000..9e419e04214 --- /dev/null +++ b/bundles/PersonalizationBundle/gpl-3.0.txt @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/bundles/PersonalizationBundle/public/css/icons.css b/bundles/PersonalizationBundle/public/css/icons.css new file mode 100644 index 00000000000..55f336a3a8f --- /dev/null +++ b/bundles/PersonalizationBundle/public/css/icons.css @@ -0,0 +1,27 @@ +.pimcore_nav_icon_targeting { + background: url(/bundles/pimcoreadmin/img/flat-white-icons/person.svg) center center no-repeat !important; +} + +.pimcore_nav_icon_target_groups { + background: url(/bundles/pimcoreadmin/img/flat-white-icons/targetgroup.svg) center center no-repeat !important; +} + +.pimcore_nav_icon_targeting_toolbar { + background: url(/bundles/pimcoreadmin/img/flat-white-icons/ok.svg) center center no-repeat !important; +} + +.pimcore_icon_targeting { + background: url(/bundles/pimcoreadmin/img/flat-color-icons/person.svg) center center no-repeat !important; +} + +.pimcore_icon_targeting_toolbar_enable { + background: url(/bundles/pimcoreadmin/img/flat-color-icons/ok.svg) center center no-repeat !important; +} + +.pimcore_icon_targeting_toolbar_disable { + background: url(/bundles/pimcoreadmin/img/flat-color-icons/stop-circle.svg) center center no-repeat !important; +} + +.pimcore_icon_targeting_toolbar { + background: url(/bundles/pimcoreadmin/img/flat-color-icons/list.svg) center center no-repeat !important; +} diff --git a/bundles/PersonalizationBundle/public/css/targeting.css b/bundles/PersonalizationBundle/public/css/targeting.css new file mode 100644 index 00000000000..4f1e146604e --- /dev/null +++ b/bundles/PersonalizationBundle/public/css/targeting.css @@ -0,0 +1,25 @@ +.pimcore_targeting_bracket { + position: absolute; + top: 64px; + cursor: pointer; + + color: #CCCCCC; + font-family: sans-serif; + font-size: 50px; +} + +.pimcore_targeting_bracket:hover { + color: #B4B4B4; +} + +.pimcore_targeting_bracket_active { + color: #000 !important; +} + +.pimcore_targeting_bracket_left { + left: 5px; +} + +.pimcore_targeting_bracket_right { + right: 5px; +} \ No newline at end of file diff --git a/bundles/PersonalizationBundle/public/js/document/areatoolbar.js b/bundles/PersonalizationBundle/public/js/document/areatoolbar.js new file mode 100644 index 00000000000..054e7cfef06 --- /dev/null +++ b/bundles/PersonalizationBundle/public/js/document/areatoolbar.js @@ -0,0 +1,125 @@ +/** + * Pimcore + * + * This source file is available under two different licenses: + * - GNU General Public License version 3 (GPLv3) + * - Pimcore Commercial License (PCL) + * Full copyright and license information is available in + * LICENSE.md which is distributed with this source code. + * + * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org) + * @license http://www.pimcore.org/license GPLv3 and PCL + */ + +pimcore.registerNS("pimcore.bundle.personalization.document.areatoolbar"); +/** + * @private + */ +pimcore.bundle.personalization.document.areatoolbar = Class.create({ + + initialize: function (document , lbar) { + this.addTargetingPanel(document , lbar); + }, + + addTargetingPanel: function (document , lbar) { + if (!Ext.Array.contains(['page', 'snippet'], document.getType())) { + return; + } + + if (pimcore.globalmanager.get("target_group_store").getCount() === 0) { + return; + } + + var cleanupFunction = function () { + + Ext.Ajax.request({ + url: Routing.generate('pimcore_bundle_personalization_clear_targeting_page_editable_data'), + method: "PUT", + params: { + targetGroup: this["targetGroup"] ? this.targetGroup.getValue() : "", + id: document.id + }, + success: function () { + docEdit.reload(true); + }.bind(this) + }); + }; + + var docEdit = pimcore.globalmanager.get("document_" + document.id).edit; + + this.targetGroupText = Ext.create('Ext.toolbar.TextItem', { + scale: "medium", + style: "-webkit-transform: rotate(270deg); -moz-transform: rotate(270deg); -o-transform: rotate(270deg); writing-mode: lr-tb;" + }); + + this.targetGroupStore = Ext.create('Ext.data.JsonStore', { + proxy: { + type: 'ajax', + url: Routing.generate('pimcore_bundle_personalization_targeting_targetgrouplist', {'add-default': true}) + }, + fields: ["id", "text"], + listeners: { + load: function () { + this.updateTargetGroupText(this.targetGroup.getValue()); + }.bind(this) + } + }); + + // add target group selection to toolbar + this.targetGroup = new Ext.form.ComboBox({ + displayField: 'text', + valueField: "id", + store: this.targetGroupStore, + editable: false, + triggerAction: 'all', + width: 240, + listeners: { + select: function (el) { + if (document.isDirty()) { + Ext.Msg.confirm(t('warning'), t('you_have_unsaved_changes') + + "
" + t("continue") + "?", + function (btn) { + if (btn === 'yes') { + docEdit.reload(true); + this.updateTargetGroupText(this.targetGroup.getValue()); + } + }.bind(this) + ); + } else { + docEdit.reload(true); + this.updateTargetGroupText(this.targetGroup.getValue()); + } + }.bind(this) + } + }); + + this.targetGroupStore.load(); + + lbar.push("->", + this.targetGroupText, + { + tooltip: t("edit_content_for_target_group"), + iconCls: "pimcore_icon_target_groups", + arrowVisible: false, + menuAlign: "tl", + menu: [this.targetGroup] + }, + { + tooltip: t("clear_content_of_selected_target_group"), + iconCls: "pimcore_icon_cleanup", + handler: cleanupFunction.bind(this) + } + ); + }, + updateTargetGroupText: function (targetgroup) { + var record = this.targetGroupStore.getById(targetgroup); + + if (record) { + this.targetGroupText.update('    ' + + record.data.text); + } else { + this.targetGroupText.update(''); + } + }, + +}); diff --git a/bundles/PersonalizationBundle/public/js/ecommerce/pricing/conditions/targetGroup.js b/bundles/PersonalizationBundle/public/js/ecommerce/pricing/conditions/targetGroup.js new file mode 100644 index 00000000000..b80bcd94117 --- /dev/null +++ b/bundles/PersonalizationBundle/public/js/ecommerce/pricing/conditions/targetGroup.js @@ -0,0 +1,82 @@ +/** + * Pimcore + * + * This source file is available under two different licenses: + * - GNU General Public License version 3 (GPLv3) + * - Pimcore Commercial License (PCL) + * Full copyright and license information is available in + * LICENSE.md which is distributed with this source code. + * + * @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org) + * @license http://www.pimcore.org/license GPLv3 and PCL + */ + +/** + * @param panel + * @param data + * @param getName + * @returns Ext.form.FormPanel + */ +pimcore.bundle.EcommerceFramework.pricing.conditions.conditionTargetGroup = function (panel, data, getName) { + var niceName = t("bundle_ecommerce_pricing_config_condition_targetgroup"); + if (typeof getName !== "undefined" && getName) { + return niceName; + } + + // check params + if (typeof data === "undefined") { + data = {}; + } + + + this.targetGroupStore = Ext.create('Ext.data.JsonStore', { + autoLoad: true, + proxy: { + type: 'ajax', + url: Routing.generate('pimcore_bundle_personalization_targeting_targetgrouplist') + }, + fields: ["id", "text"], + listeners: { + load: function() { + this.targetGroup.setValue(data.targetGroupId); + }.bind(this) + } + }); + + this.targetGroup = new Ext.form.ComboBox({ + displayField:'text', + valueField: "id", + name: "targetGroupId", + fieldLabel: t("bundle_ecommerce_pricing_config_condition_targetgroup"), + store: this.targetGroupStore, + editable: false, + triggerAction: 'all', + width: 500, + listeners: { + } + }); + + + // create item + var myId = Ext.id(); + var item = new Ext.form.FormPanel({ + id: myId, + type: 'TargetGroup', + forceLayout: true, + style: "margin: 10px 0 0 0", + bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", + tbar: this.getTopBar(niceName, myId, panel, data, "bundle_ecommerce_pricing_icon_conditionTargetGroup"), + items: [ + this.targetGroup, + { + xtype: "numberfield", + fieldLabel: t("bundle_ecommerce_pricing_config_condition_targetgroup_threshold"), + name: "threshold", + width: 200, + value: data.threshold + } + ] + }); + + return item; +}; diff --git a/bundles/AdminBundle/public/js/pimcore/object/classes/data/targetGroup.js b/bundles/PersonalizationBundle/public/js/object/classes/data/targetGroup.js similarity index 100% rename from bundles/AdminBundle/public/js/pimcore/object/classes/data/targetGroup.js rename to bundles/PersonalizationBundle/public/js/object/classes/data/targetGroup.js diff --git a/bundles/AdminBundle/public/js/pimcore/object/classes/data/targetGroupMultiselect.js b/bundles/PersonalizationBundle/public/js/object/classes/data/targetGroupMultiselect.js similarity index 100% rename from bundles/AdminBundle/public/js/pimcore/object/classes/data/targetGroupMultiselect.js rename to bundles/PersonalizationBundle/public/js/object/classes/data/targetGroupMultiselect.js diff --git a/bundles/AdminBundle/public/js/pimcore/object/tags/targetGroup.js b/bundles/PersonalizationBundle/public/js/object/tags/targetGroup.js similarity index 100% rename from bundles/AdminBundle/public/js/pimcore/object/tags/targetGroup.js rename to bundles/PersonalizationBundle/public/js/object/tags/targetGroup.js diff --git a/bundles/AdminBundle/public/js/pimcore/object/tags/targetGroupMultiselect.js b/bundles/PersonalizationBundle/public/js/object/tags/targetGroupMultiselect.js similarity index 100% rename from bundles/AdminBundle/public/js/pimcore/object/tags/targetGroupMultiselect.js rename to bundles/PersonalizationBundle/public/js/object/tags/targetGroupMultiselect.js diff --git a/bundles/AdminBundle/public/js/pimcore/settings/targeting/action/abstract.js b/bundles/PersonalizationBundle/public/js/settings/action/abstract.js similarity index 82% rename from bundles/AdminBundle/public/js/pimcore/settings/targeting/action/abstract.js rename to bundles/PersonalizationBundle/public/js/settings/action/abstract.js index f3eb10db491..21fa6c5c985 100644 --- a/bundles/AdminBundle/public/js/pimcore/settings/targeting/action/abstract.js +++ b/bundles/PersonalizationBundle/public/js/settings/action/abstract.js @@ -11,11 +11,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -pimcore.registerNS("pimcore.settings.targeting.action.abstract"); +pimcore.registerNS("pimcore.bundle.personalization.settings.action.abstract"); /** * @private */ -pimcore.settings.targeting.action.abstract = Class.create({ +pimcore.bundle.personalization.settings.action.abstract = Class.create({ getName: function () { console.error('Name is not set for action', this); }, diff --git a/bundles/AdminBundle/public/js/pimcore/settings/targeting/actions.js b/bundles/PersonalizationBundle/public/js/settings/actions.js similarity index 93% rename from bundles/AdminBundle/public/js/pimcore/settings/targeting/actions.js rename to bundles/PersonalizationBundle/public/js/settings/actions.js index f1e4f4284db..c15c3b889cb 100644 --- a/bundles/AdminBundle/public/js/pimcore/settings/targeting/actions.js +++ b/bundles/PersonalizationBundle/public/js/settings/actions.js @@ -14,13 +14,13 @@ /** * ACTION TYPES */ -pimcore.registerNS("pimcore.settings.targeting.actions"); +pimcore.registerNS("pimcore.bundle.personalization.settings.actions"); /** * @private */ -pimcore.settings.targeting.actions = (function () { +pimcore.bundle.personalization.settings.actions = (function () { var actions = { - redirect: Class.create(pimcore.settings.targeting.action.abstract, { + redirect: Class.create(pimcore.bundle.personalization.settings.action.abstract, { getName: function () { return t("redirect"); }, @@ -34,7 +34,7 @@ pimcore.settings.targeting.actions = (function () { border: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.actions.getTopBar(this, id, panel), + tbar: pimcore.bundle.personalization.settings.actions.getTopBar(this, id, panel), items: [ { xtype: "textfield", @@ -84,7 +84,7 @@ pimcore.settings.targeting.actions = (function () { } }), - codesnippet: Class.create(pimcore.settings.targeting.action.abstract, { + codesnippet: Class.create(pimcore.bundle.personalization.settings.action.abstract, { getName: function () { return t("code_snippet"); }, @@ -98,7 +98,7 @@ pimcore.settings.targeting.actions = (function () { border: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.actions.getTopBar(this, id, panel), + tbar: pimcore.bundle.personalization.settings.actions.getTopBar(this, id, panel), items: [ { xtype: "textarea", @@ -142,7 +142,7 @@ pimcore.settings.targeting.actions = (function () { } }), - assign_target_group: Class.create(pimcore.settings.targeting.action.abstract, { + assign_target_group: Class.create(pimcore.bundle.personalization.settings.action.abstract, { getName: function () { return t('assign_target_group'); }, @@ -156,7 +156,7 @@ pimcore.settings.targeting.actions = (function () { border: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.actions.getTopBar(this, id, panel), + tbar: pimcore.bundle.personalization.settings.actions.getTopBar(this, id, panel), items: [ { xtype: "combo", diff --git a/bundles/AdminBundle/public/js/pimcore/settings/targeting/condition/abstract.js b/bundles/PersonalizationBundle/public/js/settings/condition/abstract.js similarity index 84% rename from bundles/AdminBundle/public/js/pimcore/settings/targeting/condition/abstract.js rename to bundles/PersonalizationBundle/public/js/settings/condition/abstract.js index 57b26494f17..e00cdc3fd45 100644 --- a/bundles/AdminBundle/public/js/pimcore/settings/targeting/condition/abstract.js +++ b/bundles/PersonalizationBundle/public/js/settings/condition/abstract.js @@ -11,11 +11,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -pimcore.registerNS("pimcore.settings.targeting.condition.abstract"); +pimcore.registerNS("pimcore.bundle.personalization.settings.condition.abstract"); /** * @private */ -pimcore.settings.targeting.condition.abstract = Class.create({ +pimcore.bundle.personalization.settings.condition.abstract = Class.create({ matchesScope: function (scope) { return 'targeting_rule' === scope; }, diff --git a/bundles/AdminBundle/public/js/pimcore/settings/targeting/conditions.js b/bundles/PersonalizationBundle/public/js/settings/conditions.js similarity index 91% rename from bundles/AdminBundle/public/js/pimcore/settings/targeting/conditions.js rename to bundles/PersonalizationBundle/public/js/settings/conditions.js index 3b94ade98c9..f6abb27190e 100644 --- a/bundles/AdminBundle/public/js/pimcore/settings/targeting/conditions.js +++ b/bundles/PersonalizationBundle/public/js/settings/conditions.js @@ -15,13 +15,13 @@ /** * CONDITION TYPES */ -pimcore.registerNS("pimcore.settings.targeting.conditions"); +pimcore.registerNS("pimcore.bundle.personalization.settings.conditions"); /** * @private */ -pimcore.settings.targeting.conditions = (function () { +pimcore.bundle.personalization.settings.conditions = (function () { var conditions = { - url: Class.create(pimcore.settings.targeting.condition.abstract, { + url: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t('targeting_condition_url_pattern'); }, @@ -34,7 +34,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: "textfield", fieldLabel: t('targeting_condition_url_pattern'), @@ -50,7 +50,7 @@ pimcore.settings.targeting.conditions = (function () { } }), - browser: Class.create(pimcore.settings.targeting.condition.abstract, { + browser: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t("browser"); }, @@ -67,7 +67,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: "combo", fieldLabel: t("browser"), @@ -93,7 +93,7 @@ pimcore.settings.targeting.conditions = (function () { } }), - country: Class.create(pimcore.settings.targeting.condition.abstract, { + country: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { isAvailable : function () { return pimcore.settings['maxmind_geoip_installed']; @@ -115,7 +115,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: 'combo', fieldLabel: t('country'), @@ -155,7 +155,7 @@ pimcore.settings.targeting.conditions = (function () { } }), - language: Class.create(pimcore.settings.targeting.condition.abstract, { + language: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t("language"); }, @@ -172,7 +172,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: 'combo', fieldLabel: t('language'), @@ -212,7 +212,7 @@ pimcore.settings.targeting.conditions = (function () { } }), - geopoint: Class.create(pimcore.settings.targeting.condition.abstract, { + geopoint: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { isAvailable : function () { return pimcore.settings['maxmind_geoip_installed']; @@ -260,7 +260,7 @@ pimcore.settings.targeting.conditions = (function () { var searchHandler = function() { var address = searchfield.getValue(); Ext.Ajax.request({ - url: pimcore.settings.targeting.conditions.getSearchUrl(address), + url: pimcore.bundle.personalization.settings.conditions.getSearchUrl(address), method: "GET", success: function (response, opts) { var data = Ext.decode(response.responseText); @@ -409,13 +409,13 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: items }); } }), - referringsite: Class.create(pimcore.settings.targeting.condition.abstract, { + referringsite: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t("referring_site"); }, @@ -432,7 +432,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: 'textfield', fieldLabel: t('referrer') + ' (' + t("regex") + ')', @@ -449,7 +449,7 @@ pimcore.settings.targeting.conditions = (function () { } }), - searchengine: Class.create(pimcore.settings.targeting.condition.abstract, { + searchengine: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t("searchengine"); }, @@ -466,7 +466,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: 'combo', fieldLabel: t('searchengine'), @@ -486,7 +486,7 @@ pimcore.settings.targeting.conditions = (function () { } }), - visitedpagebefore: Class.create(pimcore.settings.targeting.condition.abstract, { + visitedpagebefore: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t("visited_page_before"); }, @@ -537,13 +537,13 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: items }); } }), - visitedpagesbefore: Class.create(pimcore.settings.targeting.condition.abstract, { + visitedpagesbefore: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t("visited_pages_before_number"); }, @@ -556,7 +556,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: 'numberfield', fieldLabel: t("number"), @@ -572,7 +572,7 @@ pimcore.settings.targeting.conditions = (function () { } }), - timeonsite: Class.create(pimcore.settings.targeting.condition.abstract, { + timeonsite: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t("time_on_site"); }, @@ -585,7 +585,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: 'numberfield', fieldLabel: t("hours"), @@ -613,7 +613,7 @@ pimcore.settings.targeting.conditions = (function () { } }), - hardwareplatform: Class.create(pimcore.settings.targeting.condition.abstract, { + hardwareplatform: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t("hardware_platform"); }, @@ -630,7 +630,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: 'combo', fieldLabel: t('hardware_platform'), @@ -650,7 +650,7 @@ pimcore.settings.targeting.conditions = (function () { } }), - operatingsystem: Class.create(pimcore.settings.targeting.condition.abstract, { + operatingsystem: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t("operating_system"); }, @@ -667,7 +667,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: 'combo', fieldLabel: t('operating_system'), @@ -688,7 +688,7 @@ pimcore.settings.targeting.conditions = (function () { } }), - target_group: Class.create(pimcore.settings.targeting.condition.abstract, { + target_group: Class.create(pimcore.bundle.personalization.settings.condition.abstract, { getName: function () { return t("target_group"); }, @@ -701,7 +701,7 @@ pimcore.settings.targeting.conditions = (function () { forceLayout: true, style: "margin: 10px 0 0 0", bodyStyle: "padding: 10px 30px 10px 30px; min-height:40px;", - tbar: pimcore.settings.targeting.conditions.getTopBar(this, id, panel, data), + tbar: pimcore.bundle.personalization.settings.conditions.getTopBar(this, id, panel, data), items: [{ xtype: "combo", name: "targetGroup", diff --git a/bundles/AdminBundle/public/js/pimcore/settings/targeting/rules/item.js b/bundles/PersonalizationBundle/public/js/settings/rules/item.js similarity index 94% rename from bundles/AdminBundle/public/js/pimcore/settings/targeting/rules/item.js rename to bundles/PersonalizationBundle/public/js/settings/rules/item.js index c1622cdf330..d76f2b404e4 100644 --- a/bundles/AdminBundle/public/js/pimcore/settings/targeting/rules/item.js +++ b/bundles/PersonalizationBundle/public/js/settings/rules/item.js @@ -11,11 +11,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -pimcore.registerNS("pimcore.settings.targeting.rules.item"); +pimcore.registerNS("pimcore.bundle.personalization.settings.rules.item"); /** * @private */ -pimcore.settings.targeting.rules.item = Class.create({ +pimcore.bundle.personalization.settings.rules.item = Class.create({ initialize: function(parent, data) { this.parent = parent; this.data = data; @@ -54,7 +54,7 @@ pimcore.settings.targeting.rules.item = Class.create({ if (this.data.conditions && this.data.conditions.length > 0) { for (var i = 0; i < this.data.conditions.length; i++) { try { - condition = pimcore.settings.targeting.conditions.create(this.data.conditions[i].type); + condition = pimcore.bundle.personalization.settings.conditions.create(this.data.conditions[i].type); } catch (e) { console.error(e); continue; @@ -75,7 +75,7 @@ pimcore.settings.targeting.rules.item = Class.create({ if (this.data.actions && this.data.actions.length > 0) { for (var i = 0; i < this.data.actions.length; i++) { try { - action = pimcore.settings.targeting.actions.create(this.data.actions[i].type); + action = pimcore.bundle.personalization.settings.actions.create(this.data.actions[i].type); } catch (e) { console.error(e); continue; @@ -137,11 +137,11 @@ pimcore.settings.targeting.rules.item = Class.create({ }.bind(this); var addMenu = []; - Ext.Array.forEach(pimcore.settings.targeting.conditions.getKeys(), function(key) { + Ext.Array.forEach(pimcore.bundle.personalization.settings.conditions.getKeys(), function(key) { var condition; try { - condition = pimcore.settings.targeting.conditions.create(key); + condition = pimcore.bundle.personalization.settings.conditions.create(key); } catch (e) { console.error(e); return; @@ -181,11 +181,11 @@ pimcore.settings.targeting.rules.item = Class.create({ }.bind(this); var addMenu = []; - Ext.Array.forEach(pimcore.settings.targeting.actions.getKeys(), function(key) { + Ext.Array.forEach(pimcore.bundle.personalization.settings.actions.getKeys(), function(key) { var action; try { - action = pimcore.settings.targeting.actions.create(key); + action = pimcore.bundle.personalization.settings.actions.create(key); } catch (e) { console.error(e); return; @@ -305,7 +305,7 @@ pimcore.settings.targeting.rules.item = Class.create({ }; Ext.Ajax.request({ - url: Routing.generate('pimcore_admin_targeting_rulesave'), + url: Routing.generate('pimcore_bundle_personalization_targeting_rulesave'), method: 'PUT', params: { id: this.data.id, diff --git a/bundles/AdminBundle/public/js/pimcore/settings/targeting/rules/panel.js b/bundles/PersonalizationBundle/public/js/settings/rules/panel.js similarity index 91% rename from bundles/AdminBundle/public/js/pimcore/settings/targeting/rules/panel.js rename to bundles/PersonalizationBundle/public/js/settings/rules/panel.js index a111b2f52db..16a5f29d199 100644 --- a/bundles/AdminBundle/public/js/pimcore/settings/targeting/rules/panel.js +++ b/bundles/PersonalizationBundle/public/js/settings/rules/panel.js @@ -11,14 +11,14 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -pimcore.registerNS("pimcore.settings.targeting.rules.panel"); +pimcore.registerNS("pimcore.bundle.personalization.settings.rules.panel"); /** * @private */ -pimcore.settings.targeting.rules.panel= Class.create({ +pimcore.bundle.personalization.settings.rules.panel= Class.create({ initialize: function() { - this.treeDataUrl = Routing.generate('pimcore_admin_targeting_rulelist'); + this.treeDataUrl = Routing.generate('pimcore_bundle_personalization_targeting_rulelist'); }, @@ -63,7 +63,7 @@ pimcore.settings.targeting.rules.panel= Class.create({ // save order Ext.Ajax.request({ - url: Routing.generate('pimcore_admin_targeting_ruleorder'), + url: Routing.generate('pimcore_bundle_personalization_targeting_ruleorder'), params: { rules: Ext.encode(rules) }, @@ -162,7 +162,7 @@ pimcore.settings.targeting.rules.panel= Class.create({ var regresult = value.match(/[a-zA-Z0-9_\-]+/); if (button == "ok" && value.length > 2 && regresult == value) { Ext.Ajax.request({ - url: Routing.generate('pimcore_admin_targeting_ruleadd'), + url: Routing.generate('pimcore_bundle_personalization_targeting_ruleadd'), method: 'POST', params: { name: value @@ -197,7 +197,7 @@ pimcore.settings.targeting.rules.panel= Class.create({ deleteTarget: function (tree, record) { pimcore.helpers.deleteConfirm(t('global_targeting_rule'), record.data.text, function () { Ext.Ajax.request({ - url: Routing.generate('pimcore_admin_targeting_ruledelete'), + url: Routing.generate('pimcore_bundle_personalization_targeting_ruledelete'), method: 'DELETE', params: { id: record.data.id @@ -238,14 +238,14 @@ pimcore.settings.targeting.rules.panel= Class.create({ } Ext.Ajax.request({ - url: Routing.generate('pimcore_admin_targeting_ruleget'), + url: Routing.generate('pimcore_bundle_personalization_targeting_ruleget'), params: { id: node }, success: function (response) { try { var res = Ext.decode(response.responseText); - var item = new pimcore.settings.targeting.rules.item(this, res); + var item = new pimcore.bundle.personalization.settings.rules.item(this, res); } catch (e) { console.log(e); } diff --git a/bundles/AdminBundle/public/js/pimcore/settings/targeting/targetGroups/item.js b/bundles/PersonalizationBundle/public/js/settings/targetGroups/item.js similarity index 91% rename from bundles/AdminBundle/public/js/pimcore/settings/targeting/targetGroups/item.js rename to bundles/PersonalizationBundle/public/js/settings/targetGroups/item.js index 489156fb732..1967aef1ce6 100644 --- a/bundles/AdminBundle/public/js/pimcore/settings/targeting/targetGroups/item.js +++ b/bundles/PersonalizationBundle/public/js/settings/targetGroups/item.js @@ -11,11 +11,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -pimcore.registerNS("pimcore.settings.targeting.targetGroups.item"); +pimcore.registerNS("pimcore.bundle.personalization.settings.targetGroups.item"); /** * @private */ -pimcore.settings.targeting.targetGroups.item = Class.create({ +pimcore.bundle.personalization.settings.targetGroups.item = Class.create({ initialize: function(parent, data) { this.parent = parent; @@ -82,7 +82,7 @@ pimcore.settings.targeting.targetGroups.item = Class.create({ }; Ext.Ajax.request({ - url: Routing.generate('pimcore_admin_targeting_targetgroupsave'), + url: Routing.generate('pimcore_bundle_personalization_targeting_targetgroupsave'), method: 'PUT', params: { id: this.data.id, diff --git a/bundles/AdminBundle/public/js/pimcore/settings/targeting/targetGroups/panel.js b/bundles/PersonalizationBundle/public/js/settings/targetGroups/panel.js similarity index 90% rename from bundles/AdminBundle/public/js/pimcore/settings/targeting/targetGroups/panel.js rename to bundles/PersonalizationBundle/public/js/settings/targetGroups/panel.js index 13babd53682..a3a98fc5a47 100644 --- a/bundles/AdminBundle/public/js/pimcore/settings/targeting/targetGroups/panel.js +++ b/bundles/PersonalizationBundle/public/js/settings/targetGroups/panel.js @@ -11,14 +11,14 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -pimcore.registerNS("pimcore.settings.targeting.targetGroups.panel"); +pimcore.registerNS("pimcore.bundle.personalization.settings.targetGroups.panel"); /** * @private */ -pimcore.settings.targeting.targetGroups.panel= Class.create({ +pimcore.bundle.personalization.settings.targetGroups.panel = Class.create({ initialize: function() { - this.treeDataUrl = Routing.generate('pimcore_admin_targeting_targetgrouplist'); + this.treeDataUrl = Routing.generate('pimcore_bundle_personalization_targeting_targetgrouplist'); }, getLayout: function () { @@ -136,7 +136,7 @@ pimcore.settings.targeting.targetGroups.panel= Class.create({ if (button == "ok" && value.length > 2) { Ext.Ajax.request({ - url: Routing.generate('pimcore_admin_targeting_targetgroupadd'), + url: Routing.generate('pimcore_bundle_personalization_targeting_targetgroupadd'), method: 'POST', params: { name: value @@ -166,7 +166,7 @@ pimcore.settings.targeting.targetGroups.panel= Class.create({ deleteTargetGroup: function (tree, record) { pimcore.helpers.deleteConfirm(t('target_group'), record.data.text, function () { Ext.Ajax.request({ - url: Routing.generate('pimcore_admin_targeting_targetgroupdelete'), + url: Routing.generate('pimcore_bundle_personalization_targeting_targetgroupdelete'), method: 'DELETE', params: { id: record.data.id @@ -194,13 +194,13 @@ pimcore.settings.targeting.targetGroups.panel= Class.create({ } Ext.Ajax.request({ - url: Routing.generate('pimcore_admin_targeting_targetgroupget'), + url: Routing.generate('pimcore_bundle_personalization_targeting_targetgroupget'), params: { id: node }, success: function (response) { var res = Ext.decode(response.responseText); - var item = new pimcore.settings.targeting.targetGroups.item(this, res); + var item = new pimcore.bundle.personalization.settings.targetGroups.item(this, res); }.bind(this) }); diff --git a/bundles/AdminBundle/public/js/pimcore/settings/targeting_toolbar.js b/bundles/PersonalizationBundle/public/js/settings/targetingtoolbar.js similarity index 92% rename from bundles/AdminBundle/public/js/pimcore/settings/targeting_toolbar.js rename to bundles/PersonalizationBundle/public/js/settings/targetingtoolbar.js index 9e8fa3f8861..0dbd6ed7308 100644 --- a/bundles/AdminBundle/public/js/pimcore/settings/targeting_toolbar.js +++ b/bundles/PersonalizationBundle/public/js/settings/targetingtoolbar.js @@ -11,11 +11,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -pimcore.registerNS("pimcore.settings.targetingToolbar"); +pimcore.registerNS("pimcore.bundle.personalization.settings.targetingtoolbar"); /** * @private */ -pimcore.settings.targetingToolbar = Class.create({ +pimcore.bundle.personalization.settings.targetingtoolbar = Class.create({ initialize: function () { var that = this; var cookieName = "pimcore_targeting_debug"; diff --git a/bundles/PersonalizationBundle/public/js/startup.js b/bundles/PersonalizationBundle/public/js/startup.js new file mode 100644 index 00000000000..259408684e9 --- /dev/null +++ b/bundles/PersonalizationBundle/public/js/startup.js @@ -0,0 +1,142 @@ +pimcore.registerNS("pimcore.bundle.personalization.startup"); + +pimcore.bundle.personalization.startup = Class.create({ + initialize: function () { + + // target groups + Ext.define('pimcore.model.target_groups', { + extend: 'Ext.data.Model', + fields: ["id", "text"] + }); + + var targetGroupStore = Ext.create('Ext.data.JsonStore', { + model: "pimcore.model.target_groups", + proxy: { + type: 'ajax', + url: Routing.generate('pimcore_bundle_personalization_targeting_targetgrouplist'), + reader: { + type: 'json' + } + } + }); + + targetGroupStore.load(); + pimcore.globalmanager.add("target_group_store", targetGroupStore); + + document.addEventListener(pimcore.events.preMenuBuild, this.preMenuBuild.bind(this)); + + document.addEventListener(pimcore.events.prepareDocumentPageSettingsLayout, this.assignTargetGroupToPage.bind(this)); + }, + + + preMenuBuild: function (e) { + let menu = e.detail.menu; + const user = pimcore.globalmanager.get('user'); + const perspectiveCfg = pimcore.globalmanager.get("perspective"); + + if (user.isAllowed("targeting") && perspectiveCfg.inToolbar("marketing.targeting")) { + menu.marketing.items.push({ + text: t("personalization") + " / " + t("targeting"), + iconCls: "pimcore_nav_icon_usergroup", + itemId: 'pimcore_menu_marketing_personalization', + hideOnClick: false, + menu: { + cls: "pimcore_navigation_flyout", + shadow: false, + items: [ + { + text: t("global_targeting_rules"), + iconCls: "pimcore_nav_icon_targeting", + itemId: 'pimcore_menu_marketing_personalization_global_targeting_rules', + handler: this.showTargetingRules + }, { + text: t('target_groups'), + iconCls: "pimcore_nav_icon_target_groups", + itemId: 'pimcore_menu_marketing_personalization_target_groups', + handler: this.showTargetGroups + }, { + text: t("targeting_toolbar"), + iconCls: "pimcore_nav_icon_targeting_toolbar", + itemId: 'pimcore_menu_marketing_personalization_targeting_toolbar', + handler: this.showTargetingToolbarSettings + } + ] + } + }); + } + }, + + showTargetingRules: function () { + var tabPanel = Ext.getCmp("pimcore_panel_tabs"); + try { + tabPanel.setActiveTab(pimcore.globalmanager.get("targeting").getLayout()); + } catch (e) { + var targeting = new pimcore.bundle.personalization.settings.rules.panel(); + pimcore.globalmanager.add("targeting", targeting); + + tabPanel.add(targeting.getLayout()); + tabPanel.setActiveTab(targeting.getLayout()); + + targeting.getLayout().on("destroy", function () { + pimcore.globalmanager.remove("targeting"); + }.bind(this)); + + pimcore.layout.refresh(); + } + }, + + showTargetGroups: function () { + var tabPanel = Ext.getCmp("pimcore_panel_tabs"); + try { + tabPanel.setActiveTab(pimcore.globalmanager.get("targetGroupsPanel").getLayout()); + } catch (e) { + var targetGroups = new pimcore.bundle.personalization.settings.targetGroups.panel(); + pimcore.globalmanager.add("targetGroupsPanel", targetGroups); + + tabPanel.add(targetGroups.getLayout()); + tabPanel.setActiveTab(targetGroups.getLayout()); + + targetGroups.getLayout().on("destroy", function () { + pimcore.globalmanager.remove("targetGroupsPanel"); + }.bind(this)); + + pimcore.layout.refresh(); + } + }, + + showTargetingToolbarSettings: function () { + new pimcore.bundle.personalization.settings.targetingtoolbar(); + }, + + assignTargetGroupToPage: function (e) { + const document = e.detail.document; + + const assignTargetGroupBlock = { + xtype: 'fieldset', + title: t('assign_target_groups'), + collapsible: true, + autoHeight: true, + defaults: { + labelWidth: 300 + }, + defaultType: 'textfield', + items: [ + Ext.create('Ext.ux.form.MultiSelect', { + fieldLabel: t('visitors_of_this_page_will_be_automatically_associated_with_the_selected_target_groups'), + store: pimcore.globalmanager.get("target_group_store"), + displayField: "text", + valueField: "id", + name: 'targetGroupIds', + width: 700, + //listWidth: 200, + value: document.data["targetGroupIds"].split(',').map(Number).filter(item => item), + minHeight: 100 + }) + ] + }; + + e.detail.layout.add(assignTargetGroupBlock); + } +}) + +const personalization = new pimcore.bundle.personalization.startup(); diff --git a/bundles/CoreBundle/public/js/targeting.js b/bundles/PersonalizationBundle/public/js/targeting.js similarity index 100% rename from bundles/CoreBundle/public/js/targeting.js rename to bundles/PersonalizationBundle/public/js/targeting.js diff --git a/bundles/AdminBundle/src/Controller/Admin/TargetingController.php b/bundles/PersonalizationBundle/src/Controller/Admin/TargetingController.php similarity index 85% rename from bundles/AdminBundle/src/Controller/Admin/TargetingController.php rename to bundles/PersonalizationBundle/src/Controller/Admin/TargetingController.php index 9f07f0ddcc7..c73d289753d 100644 --- a/bundles/AdminBundle/src/Controller/Admin/TargetingController.php +++ b/bundles/PersonalizationBundle/src/Controller/Admin/TargetingController.php @@ -14,18 +14,17 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\AdminBundle\Controller\Admin; +namespace Pimcore\Bundle\PersonalizationBundle\Controller\Admin; use Pimcore\Bundle\AdminBundle\Controller\AdminController; use Pimcore\Cache\Core\CoreCacheHandler; use Pimcore\Controller\KernelControllerEventInterface; -use Pimcore\Model\Tool\Targeting; -use Pimcore\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\ControllerEvent; use Symfony\Component\Routing\Annotation\Route; - /** * @Route("/targeting") * @@ -41,7 +40,7 @@ private function correctName(string $name): string } /** - * @Route("/rule/list", name="pimcore_admin_targeting_rulelist", methods={"GET"}) + * @Route("/rule/list", name="pimcore_bundle_personalization_targeting_rulelist", methods={"GET"}) * * @param Request $request * @@ -68,7 +67,7 @@ public function ruleListAction(Request $request): JsonResponse } /** - * @Route("/rule/add", name="pimcore_admin_targeting_ruleadd", methods={"POST"}) + * @Route("/rule/add", name="pimcore_bundle_personalization_targeting_ruleadd", methods={"POST"}) * * @param Request $request * @@ -84,7 +83,7 @@ public function ruleAddAction(Request $request): JsonResponse } /** - * @Route("/rule/delete", name="pimcore_admin_targeting_ruledelete", methods={"DELETE"}) + * @Route("/rule/delete", name="pimcore_bundle_personalization_targeting_ruledelete", methods={"DELETE"}) * * @param Request $request * @@ -104,7 +103,7 @@ public function ruleDeleteAction(Request $request): JsonResponse } /** - * @Route("/rule/get", name="pimcore_admin_targeting_ruleget", methods={"GET"}) + * @Route("/rule/get", name="pimcore_bundle_personalization_targeting_ruleget", methods={"GET"}) * * @param Request $request * @@ -122,7 +121,7 @@ public function ruleGetAction(Request $request): JsonResponse } /** - * @Route("/rule/save", name="pimcore_admin_targeting_rulesave", methods={"PUT"}) + * @Route("/rule/save", name="pimcore_bundle_personalization_targeting_rulesave", methods={"PUT"}) * * @param Request $request * @@ -146,7 +145,7 @@ public function ruleSaveAction(Request $request): JsonResponse } /** - * @Route("/rule/order", name="pimcore_admin_targeting_ruleorder", methods={"POST"}) + * @Route("/rule/order", name="pimcore_bundle_personalization_targeting_ruleorder", methods={"POST"}) * * @param Request $request * @@ -192,7 +191,7 @@ public function ruleOrderAction(Request $request): JsonResponse // TARGET GROUPS /** - * @Route("/target-group/list", name="pimcore_admin_targeting_targetgrouplist", methods={"GET"}) + * @Route("/target-group/list", name="pimcore_bundle_personalization_targeting_targetgrouplist", methods={"GET"}) * * @param Request $request * @@ -227,7 +226,7 @@ public function targetGroupListAction(Request $request): JsonResponse } /** - * @Route("/target-group/add", name="pimcore_admin_targeting_targetgroupadd", methods={"POST"}) + * @Route("/target-group/add", name="pimcore_bundle_personalization_targeting_targetgroupadd", methods={"POST"}) * * @param Request $request * @param CoreCacheHandler $cache @@ -247,7 +246,7 @@ public function targetGroupAddAction(Request $request, CoreCacheHandler $cache): } /** - * @Route("/target-group/delete", name="pimcore_admin_targeting_targetgroupdelete", methods={"DELETE"}) + * @Route("/target-group/delete", name="pimcore_bundle_personalization_targeting_targetgroupdelete", methods={"DELETE"}) * * @param Request $request * @param CoreCacheHandler $cache @@ -270,7 +269,7 @@ public function targetGroupDeleteAction(Request $request, CoreCacheHandler $cach } /** - * @Route("/target-group/get", name="pimcore_admin_targeting_targetgroupget", methods={"GET"}) + * @Route("/target-group/get", name="pimcore_bundle_personalization_targeting_targetgroupget", methods={"GET"}) * * @param Request $request * @@ -288,7 +287,7 @@ public function targetGroupGetAction(Request $request): JsonResponse } /** - * @Route("/target-group/save", name="pimcore_admin_targeting_targetgroupsave", methods={"PUT"}) + * @Route("/target-group/save", name="pimcore_bundle_personalization_targeting_targetgroupsave", methods={"PUT"}) * * @param Request $request * @param CoreCacheHandler $cache diff --git a/bundles/PersonalizationBundle/src/Controller/Admin/TargetingPageController.php b/bundles/PersonalizationBundle/src/Controller/Admin/TargetingPageController.php new file mode 100644 index 00000000000..bfafb95a11f --- /dev/null +++ b/bundles/PersonalizationBundle/src/Controller/Admin/TargetingPageController.php @@ -0,0 +1,108 @@ +request->getInt('targetGroup'); + $docId = $request->request->getInt('id'); + + $doc = Document\PageSnippet::getById($docId); + + if (!$doc) { + throw $this->createNotFoundException('Document not found'); + } + + foreach ($doc->getEditables() as $editable) { + + if ($targetGroupId && $doc instanceof TargetingDocumentInterface) { + + // remove target group specific elements + if (preg_match ('/^' . preg_quote ($doc->getTargetGroupEditablePrefix($targetGroupId), '/') . '/', $editable->getName())) { + $doc->removeEditable($editable->getName()); + } + } + } + + $this->saveToSession($doc, $request->getSession(), true); + + return $this->adminJson([ + 'success' => true, + ]); + } + + /** + * @Route("/save", name="pimcore_admin_document_page_save", methods={"PUT", "POST"}) + * + * @param Request $request + * @param StaticPageGenerator $staticPageGenerator + * + * @return JsonResponse + * + * @throws \Exception + */ + public function saveAction(Request $request, StaticPageGenerator $staticPageGenerator): JsonResponse + { + return parent::saveAction($request, $staticPageGenerator); + } + + protected function addDataToDocument(Request $request, Document $document): void + { + if ($document instanceof Document\PageSnippet) { + // if a target group variant get's saved, we have to load all other editables first, otherwise they will get deleted + + if ($request->get('appendEditables') + || ($document instanceof TargetingDocumentInterface)) { // ensure editable are loaded + $document->getEditables(); + } else { + // ensure no editables (e.g. from session, version, ...) are still referenced + $document->setEditables(null); + } + + if ($request->get('data')) { + $data = $this->decodeJson($request->get('data')); + foreach ($data as $name => $value) { + $data = $value['data'] ?? null; + $type = $value['type']; + $document->setRawEditable($name, $type, $data); + } + } + } + } +} diff --git a/bundles/PersonalizationBundle/src/Controller/Admin/TargetingSnippetController.php b/bundles/PersonalizationBundle/src/Controller/Admin/TargetingSnippetController.php new file mode 100644 index 00000000000..7bc249b964c --- /dev/null +++ b/bundles/PersonalizationBundle/src/Controller/Admin/TargetingSnippetController.php @@ -0,0 +1,105 @@ +request->getInt('targetGroup'); + $docId = $request->request->getInt('id'); + + $doc = Document\PageSnippet::getById($docId); + + if (!$doc) { + throw $this->createNotFoundException('Document not found'); + } + + foreach ($doc->getEditables() as $editable) { + if ($targetGroupId && $doc instanceof TargetingDocumentInterface) { + + // remove target group specific elements + if (preg_match ('/^' . preg_quote ($doc->getTargetGroupEditablePrefix($targetGroupId), '/') . '/', $editable->getName())) { + $doc->removeEditable($editable->getName()); + } + } + } + + $this->saveToSession($doc, $request->getSession(), true); + + return $this->adminJson([ + 'success' => true, + ]); + } + + /** + * @Route("/save", name="pimcore_admin_document_snippet_save", methods={"PUT", "POST"}) + * + * @param Request $request + * + * @return JsonResponse + * + * @throws \Exception + */ + public function saveAction(Request $request): JsonResponse + { + return parent::saveAction($request); + } + + protected function addDataToDocument(Request $request, Document $document): void + { + if ($document instanceof Document\PageSnippet) { + // if a target group variant get's saved, we have to load all other editables first, otherwise they will get deleted + + if ($request->get('appendEditables') + || ($document instanceof TargetingDocumentInterface)) { // ensure editable are loaded + $document->getEditables(); + } else { + // ensure no editables (e.g. from session, version, ...) are still referenced + $document->setEditables(null); + } + + if ($request->get('data')) { + $data = $this->decodeJson($request->get('data')); + foreach ($data as $name => $value) { + $data = $value['data'] ?? null; + $type = $value['type']; + $document->setRawEditable($name, $type, $data); + } + } + } + } +} diff --git a/bundles/CoreBundle/src/DataCollector/PimcoreTargetingDataCollector.php b/bundles/PersonalizationBundle/src/DataCollector/PimcoreTargetingDataCollector.php similarity index 88% rename from bundles/CoreBundle/src/DataCollector/PimcoreTargetingDataCollector.php rename to bundles/PersonalizationBundle/src/DataCollector/PimcoreTargetingDataCollector.php index 51f65f010ae..52fbee5b9c1 100644 --- a/bundles/CoreBundle/src/DataCollector/PimcoreTargetingDataCollector.php +++ b/bundles/PersonalizationBundle/src/DataCollector/PimcoreTargetingDataCollector.php @@ -15,14 +15,15 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\CoreBundle\DataCollector; +namespace Pimcore\Bundle\PersonalizationBundle\DataCollector; use Pimcore\Http\Request\Resolver\DocumentResolver; -use Pimcore\Targeting\Debug\TargetingDataCollector; -use Pimcore\Targeting\VisitorInfoStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\TargetingDataCollector; +use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Contracts\Service\ResetInterface; /** @@ -81,12 +82,12 @@ public function getStorage(): array return $this->data['storage']; } - public function getRules(): array + public function getRules(): array|Data { return $this->data['rules']; } - public function getTargetGroups(): array + public function getTargetGroups(): array|Data { return $this->data['target_groups']; } diff --git a/bundles/CoreBundle/src/DependencyInjection/Compiler/DebugStopwatchPass.php b/bundles/PersonalizationBundle/src/DependencyInjection/Compiler/DebugStopwatchPass.php similarity index 83% rename from bundles/CoreBundle/src/DependencyInjection/Compiler/DebugStopwatchPass.php rename to bundles/PersonalizationBundle/src/DependencyInjection/Compiler/DebugStopwatchPass.php index 40582e36b03..e9f621da6bd 100644 --- a/bundles/CoreBundle/src/DependencyInjection/Compiler/DebugStopwatchPass.php +++ b/bundles/PersonalizationBundle/src/DependencyInjection/Compiler/DebugStopwatchPass.php @@ -15,12 +15,12 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler; +namespace Pimcore\Bundle\PersonalizationBundle\DependencyInjection\Compiler; -use Pimcore\Targeting\DataLoader; -use Pimcore\Targeting\Debug\TargetingDataCollector; -use Pimcore\Targeting\EventListener\TargetingListener; -use Pimcore\Targeting\VisitorInfoResolver; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataLoader; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\TargetingDataCollector; +use Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\TargetingListener; +use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoResolver; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; diff --git a/bundles/CoreBundle/src/DependencyInjection/Compiler/TargetingOverrideHandlersPass.php b/bundles/PersonalizationBundle/src/DependencyInjection/Compiler/TargetingOverrideHandlersPass.php similarity index 79% rename from bundles/CoreBundle/src/DependencyInjection/Compiler/TargetingOverrideHandlersPass.php rename to bundles/PersonalizationBundle/src/DependencyInjection/Compiler/TargetingOverrideHandlersPass.php index cf90f5ff258..2ae5ec19161 100644 --- a/bundles/CoreBundle/src/DependencyInjection/Compiler/TargetingOverrideHandlersPass.php +++ b/bundles/PersonalizationBundle/src/DependencyInjection/Compiler/TargetingOverrideHandlersPass.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler; +namespace Pimcore\Bundle\PersonalizationBundle\DependencyInjection\Compiler; -use Pimcore\Targeting\Debug\OverrideHandler; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\OverrideHandler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -31,7 +31,7 @@ final class TargetingOverrideHandlersPass implements CompilerPassInterface public function process(ContainerBuilder $container): void { - $handlers = $this->findAndSortTaggedServices('pimcore.targeting.override_handler', $container); + $handlers = $this->findAndSortTaggedServices('pimcore_personalization.targeting.override_handler', $container); $overrideHandler = $container->getDefinition(OverrideHandler::class); $overrideHandler->setArgument('$overrideHandlers', $handlers); diff --git a/bundles/PersonalizationBundle/src/DependencyInjection/Configuration.php b/bundles/PersonalizationBundle/src/DependencyInjection/Configuration.php new file mode 100644 index 00000000000..1af80a8202a --- /dev/null +++ b/bundles/PersonalizationBundle/src/DependencyInjection/Configuration.php @@ -0,0 +1,57 @@ +getRootNode (); + + $rootNode + ->children() + ->arrayNode('targeting') + ->canBeDisabled() + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('storage_id') + ->info('Service ID of the targeting storage which should be used. This ID will be aliased to ' . TargetingStorageInterface::class) + ->defaultValue(CookieStorage::class) + ->cannotBeEmpty() + ->end() + ->arrayNode ('session') + ->info ('Enables HTTP session support by configuring session bags and the full page cache') + ->canBeEnabled() + ->end() + ->arrayNode('data_providers') + ->useAttributeAsKey('key') + ->prototype('scalar') + ->end() + ->end() + ->arrayNode('conditions') + ->useAttributeAsKey('key') + ->prototype('scalar') + ->end() + ->end() + ->arrayNode('action_handlers') + ->useAttributeAsKey('name') + ->prototype('scalar') + ->end() + ->end() + ->end() + ->end() + ->end(); + + return $treeBuilder; + } +} diff --git a/bundles/PersonalizationBundle/src/DependencyInjection/PimcorePersonalizationExtension.php b/bundles/PersonalizationBundle/src/DependencyInjection/PimcorePersonalizationExtension.php new file mode 100644 index 00000000000..9158ca9fab6 --- /dev/null +++ b/bundles/PersonalizationBundle/src/DependencyInjection/PimcorePersonalizationExtension.php @@ -0,0 +1,94 @@ +configureTargeting($container, $loader, $config['targeting']); + } + + private function configureTargeting (ContainerBuilder $container, LoaderInterface $loader, array $config): void + { + $container->setParameter('pimcore_personalization.targeting.enabled', $config['enabled']); + $container->setParameter ('pimcore_personalization.targeting.conditions', $config['conditions']); + // @phpstan-ignore-next-line + if (!$container->hasParameter('pimcore.geoip.db_file')) { + $container->setParameter('pimcore.geoip.db_file', ''); + } + + $loader->load ('targeting.yaml'); + + // set TargetingStorageInterface type hint to the configured service ID + $container->setAlias (TargetingStorageInterface::class, $config['storage_id']); + + if ($config['enabled']) { + // enable targeting by registering listeners + $loader->load('targeting/services.yaml'); + $loader->load('targeting/listeners.yaml'); + } + + $dataProviders = []; + foreach ($config['data_providers'] as $dataProviderKey => $dataProviderServiceId) { + $dataProviders[$dataProviderKey] = new Reference($dataProviderServiceId); + } + + $dataProviderLocator = new Definition(ServiceLocator::class, [$dataProviders]); + $dataProviderLocator + ->setPublic (false) + ->addTag ('container.service_locator'); + + $container + ->findDefinition (DataLoaderInterface::class) + ->setArgument ('$dataProviders', $dataProviderLocator); + + $actionHandlers = []; + foreach ($config['action_handlers'] as $actionHandlerKey => $actionHandlerServiceId) { + $actionHandlers[$actionHandlerKey] = new Reference($actionHandlerServiceId); + } + + $actionHandlerLocator = new Definition(ServiceLocator::class, [$actionHandlers]); + $actionHandlerLocator + ->setPublic (false) + ->addTag ('container.service_locator'); + + $container + ->getDefinition (DelegatingActionHandler::class) + ->setArgument ('$actionHandlers', $actionHandlerLocator); + + $container->setParameter ('pimcore_personalization.targeting.session.enabled', $config['session']['enabled'] ?? false); + + } +} diff --git a/bundles/PersonalizationBundle/src/Document/Newsletter/AddressSourceAdapter/DefaultAdapter.php b/bundles/PersonalizationBundle/src/Document/Newsletter/AddressSourceAdapter/DefaultAdapter.php new file mode 100644 index 00000000000..add77f239d2 --- /dev/null +++ b/bundles/PersonalizationBundle/src/Document/Newsletter/AddressSourceAdapter/DefaultAdapter.php @@ -0,0 +1,104 @@ +targetGroups = $params['target_groups'] ?? []; + + parent::__construct($params); + } + + protected function getListing(): ?Listing + { + if (empty($this->list)) { + $objectList = '\\Pimcore\\Model\\DataObject\\' . ucfirst($this->class) . '\\Listing'; + $this->list = new $objectList(); + + $conditions = ['(newsletterActive = 1 AND newsletterConfirmed = 1)']; + if ($this->condition) { + $conditions[] = '(' . $this->condition . ')'; + } + + if ($this->targetGroups) { + $class = ClassDefinition::getByName($this->class); + + if ($class) { + $conditions = $this->addTargetGroupConditions($class, $conditions); + } + } + + $this->list->setCondition(implode(' AND ', $conditions)); + $this->list->setOrderKey('email'); + $this->list->setOrder('ASC'); + + $this->elementsTotal = $this->list->getTotalCount(); + } + + return $this->list; + } + + /** + * Handle target group filters + * + * @param ClassDefinition $class + * @param array $conditions + * + * @return array + */ + protected function addTargetGroupConditions(ClassDefinition $class, array $conditions): array + { + if (!$class->getFieldDefinition('targetGroup')) { + return $conditions; + } + + $fieldDefinition = $class->getFieldDefinition('targetGroup'); + if ($fieldDefinition instanceof ClassDefinition\Data\TargetGroup) { + $targetGroups = []; + foreach ($this->targetGroups as $value) { + if (!empty($value)) { + $targetGroups[] = $this->list->quote($value); + } + } + + $conditions[] = 'targetGroup IN (' . implode(',', $targetGroups) . ')'; + } elseif ($fieldDefinition instanceof ClassDefinition\Data\TargetGroupMultiselect) { + $targetGroupsCondition = []; + foreach ($this->targetGroups as $value) { + $targetGroupsCondition[] = 'targetGroup LIKE ' . $this->list->quote('%,' . $value . ',%'); + } + + $conditions[] = '(' . implode(' OR ', $targetGroupsCondition) . ')'; + } + + return $conditions; + } +} diff --git a/bundles/EcommerceFrameworkBundle/src/PricingManager/Condition/TargetGroup.php b/bundles/PersonalizationBundle/src/Ecommerce/PricingManager/Condition/TargetGroup.php similarity index 81% rename from bundles/EcommerceFrameworkBundle/src/PricingManager/Condition/TargetGroup.php rename to bundles/PersonalizationBundle/src/Ecommerce/PricingManager/Condition/TargetGroup.php index 46024b000ce..2e7d02db6a6 100644 --- a/bundles/EcommerceFrameworkBundle/src/PricingManager/Condition/TargetGroup.php +++ b/bundles/PersonalizationBundle/src/Ecommerce/PricingManager/Condition/TargetGroup.php @@ -14,16 +14,17 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Bundle\EcommerceFrameworkBundle\PricingManager\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Ecommerce\PricingManager\Condition; use Pimcore\Bundle\EcommerceFrameworkBundle\PricingManager\ConditionInterface; use Pimcore\Bundle\EcommerceFrameworkBundle\PricingManager\EnvironmentInterface; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup as ToolTargetGroup; class TargetGroup implements ConditionInterface { protected ?int $targetGroupId = null; - protected ?\Pimcore\Model\Tool\Targeting\TargetGroup $targetGroup = null; + protected ?ToolTargetGroup $targetGroup = null; protected int $threshold = 0; @@ -58,7 +59,7 @@ public function __sleep(): array public function __wakeup(): void { if ($this->targetGroupId) { - $this->targetGroup = \Pimcore\Model\Tool\Targeting\TargetGroup::getById($this->targetGroupId); + $this->targetGroup = ToolTargetGroup::getById($this->targetGroupId); } } @@ -95,18 +96,18 @@ public function setTargetGroupId(int $targetGroupId): void { $this->targetGroupId = $targetGroupId; if ($this->targetGroupId) { - $this->targetGroup = \Pimcore\Model\Tool\Targeting\TargetGroup::getById($this->targetGroupId); + $this->targetGroup = ToolTargetGroup::getById($this->targetGroupId); } else { $this->targetGroup = null; } } - public function getTargetGroup(): \Pimcore\Model\Tool\Targeting\TargetGroup + public function getTargetGroup(): ToolTargetGroup { return $this->targetGroup; } - public function setTargetGroup(\Pimcore\Model\Tool\Targeting\TargetGroup $targetGroup): void + public function setTargetGroup(ToolTargetGroup $targetGroup): void { $this->targetGroup = $targetGroup; $this->targetGroupId = $targetGroup->getId(); @@ -122,3 +123,5 @@ public function setThreshold(int $threshold): void $this->threshold = $threshold; } } + +class_alias(TargetGroup::class, 'Pimcore\Bundle\EcommerceFrameworkBundle\PricingManager\Condition\TargetGroup'); diff --git a/lib/Event/Model/TargetGroupEvent.php b/bundles/PersonalizationBundle/src/Event/Model/TargetGroupEvent.php similarity index 90% rename from lib/Event/Model/TargetGroupEvent.php rename to bundles/PersonalizationBundle/src/Event/Model/TargetGroupEvent.php index a0d750f52c2..c5b5c56115c 100644 --- a/lib/Event/Model/TargetGroupEvent.php +++ b/bundles/PersonalizationBundle/src/Event/Model/TargetGroupEvent.php @@ -14,9 +14,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event\Model; +namespace Pimcore\Bundle\PersonalizationBundle\Event\Model; -use Pimcore\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; use Symfony\Contracts\EventDispatcher\Event; class TargetGroupEvent extends Event diff --git a/lib/Event/TargetGroupEvents.php b/bundles/PersonalizationBundle/src/Event/TargetGroupEvents.php similarity index 72% rename from lib/Event/TargetGroupEvents.php rename to bundles/PersonalizationBundle/src/Event/TargetGroupEvents.php index 63da13d0c10..a0699cd43b7 100644 --- a/lib/Event/TargetGroupEvents.php +++ b/bundles/PersonalizationBundle/src/Event/TargetGroupEvents.php @@ -14,26 +14,26 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event; +namespace Pimcore\Bundle\PersonalizationBundle\Event; final class TargetGroupEvents { /** - * @Event("Pimcore\Event\Model\TargetGroupEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Model\TargetGroupEvent") * * @var string */ const POST_ADD = 'pimcore.targetgroup.postAdd'; /** - * @Event("Pimcore\Event\Model\TargetGroupEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Model\TargetGroupEvent") * * @var string */ const POST_UPDATE = 'pimcore.targetgroup.postUpdate'; /** - * @Event("Pimcore\Event\Model\TargetGroupEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Model\TargetGroupEvent") * * @var string */ diff --git a/lib/Event/Targeting/AssignDocumentTargetGroupEvent.php b/bundles/PersonalizationBundle/src/Event/Targeting/AssignDocumentTargetGroupEvent.php similarity index 83% rename from lib/Event/Targeting/AssignDocumentTargetGroupEvent.php rename to bundles/PersonalizationBundle/src/Event/Targeting/AssignDocumentTargetGroupEvent.php index 07ddf00246a..c4509f5987c 100644 --- a/lib/Event/Targeting/AssignDocumentTargetGroupEvent.php +++ b/bundles/PersonalizationBundle/src/Event/Targeting/AssignDocumentTargetGroupEvent.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Event\Targeting; use Pimcore\Model\Document; -use Pimcore\Model\Tool\Targeting\TargetGroup; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class AssignDocumentTargetGroupEvent extends TargetingEvent { diff --git a/lib/Event/Targeting/BuildConditionEvent.php b/bundles/PersonalizationBundle/src/Event/Targeting/BuildConditionEvent.php similarity index 90% rename from lib/Event/Targeting/BuildConditionEvent.php rename to bundles/PersonalizationBundle/src/Event/Targeting/BuildConditionEvent.php index 7d68a96803c..892b7626e64 100644 --- a/lib/Event/Targeting/BuildConditionEvent.php +++ b/bundles/PersonalizationBundle/src/Event/Targeting/BuildConditionEvent.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Event\Targeting; -use Pimcore\Targeting\Condition\ConditionInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\ConditionInterface; use Symfony\Contracts\EventDispatcher\Event; class BuildConditionEvent extends Event diff --git a/lib/Event/Targeting/OverrideEvent.php b/bundles/PersonalizationBundle/src/Event/Targeting/OverrideEvent.php similarity index 93% rename from lib/Event/Targeting/OverrideEvent.php rename to bundles/PersonalizationBundle/src/Event/Targeting/OverrideEvent.php index 38fbe54d9ec..c271f9a67df 100644 --- a/lib/Event/Targeting/OverrideEvent.php +++ b/bundles/PersonalizationBundle/src/Event/Targeting/OverrideEvent.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Event\Targeting; use Symfony\Contracts\EventDispatcher\Event; diff --git a/lib/Event/Targeting/RenderToolbarEvent.php b/bundles/PersonalizationBundle/src/Event/Targeting/RenderToolbarEvent.php similarity index 94% rename from lib/Event/Targeting/RenderToolbarEvent.php rename to bundles/PersonalizationBundle/src/Event/Targeting/RenderToolbarEvent.php index 013c1b62229..12807c0ef98 100644 --- a/lib/Event/Targeting/RenderToolbarEvent.php +++ b/bundles/PersonalizationBundle/src/Event/Targeting/RenderToolbarEvent.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Event\Targeting; use Symfony\Contracts\EventDispatcher\Event; diff --git a/lib/Event/Targeting/TargetingCodeEvent.php b/bundles/PersonalizationBundle/src/Event/Targeting/TargetingCodeEvent.php similarity index 96% rename from lib/Event/Targeting/TargetingCodeEvent.php rename to bundles/PersonalizationBundle/src/Event/Targeting/TargetingCodeEvent.php index 1cd349af8f1..ccf86f18fbc 100644 --- a/lib/Event/Targeting/TargetingCodeEvent.php +++ b/bundles/PersonalizationBundle/src/Event/Targeting/TargetingCodeEvent.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Event\Targeting; use Pimcore\Analytics\Code\CodeBlock; use Symfony\Contracts\EventDispatcher\Event; diff --git a/lib/Event/Targeting/TargetingEvent.php b/bundles/PersonalizationBundle/src/Event/Targeting/TargetingEvent.php similarity index 87% rename from lib/Event/Targeting/TargetingEvent.php rename to bundles/PersonalizationBundle/src/Event/Targeting/TargetingEvent.php index b7654758fd7..b98b3eef594 100644 --- a/lib/Event/Targeting/TargetingEvent.php +++ b/bundles/PersonalizationBundle/src/Event/Targeting/TargetingEvent.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Event\Targeting; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Symfony\Component\HttpFoundation\Request; use Symfony\Contracts\EventDispatcher\Event; diff --git a/lib/Event/Targeting/TargetingResolveVisitorInfoEvent.php b/bundles/PersonalizationBundle/src/Event/Targeting/TargetingResolveVisitorInfoEvent.php similarity index 82% rename from lib/Event/Targeting/TargetingResolveVisitorInfoEvent.php rename to bundles/PersonalizationBundle/src/Event/Targeting/TargetingResolveVisitorInfoEvent.php index eb7b648f4f1..4300286f0e4 100644 --- a/lib/Event/Targeting/TargetingResolveVisitorInfoEvent.php +++ b/bundles/PersonalizationBundle/src/Event/Targeting/TargetingResolveVisitorInfoEvent.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Event\Targeting; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class TargetingResolveVisitorInfoEvent extends TargetingEvent { diff --git a/lib/Event/Targeting/TargetingRuleEvent.php b/bundles/PersonalizationBundle/src/Event/Targeting/TargetingRuleEvent.php similarity index 79% rename from lib/Event/Targeting/TargetingRuleEvent.php rename to bundles/PersonalizationBundle/src/Event/Targeting/TargetingRuleEvent.php index 45843a765d5..af7a0791f40 100644 --- a/lib/Event/Targeting/TargetingRuleEvent.php +++ b/bundles/PersonalizationBundle/src/Event/Targeting/TargetingRuleEvent.php @@ -15,10 +15,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Event\Targeting; -use Pimcore\Model\Tool\Targeting\Rule; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class TargetingRuleEvent extends TargetingEvent { diff --git a/lib/Event/TargetingEvents.php b/bundles/PersonalizationBundle/src/Event/TargetingEvents.php similarity index 77% rename from lib/Event/TargetingEvents.php rename to bundles/PersonalizationBundle/src/Event/TargetingEvents.php index 54a16736589..a1b1c8b3d0a 100644 --- a/lib/Event/TargetingEvents.php +++ b/bundles/PersonalizationBundle/src/Event/TargetingEvents.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Event; +namespace Pimcore\Bundle\PersonalizationBundle\Event; final class TargetingEvents { @@ -23,7 +23,7 @@ final class TargetingEvents * Fired when the targeting code is rendered. Allows to add data to the targeting * code or to change the template completely. * - * @Event("Pimcore\Event\Targeting\TargetingCodeEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingCodeEvent") * * @var string */ @@ -33,7 +33,7 @@ final class TargetingEvents * Fired when the VisitorInfo object was built for a request before * any matching and action handling is applied. * - * @Event("Pimcore\Event\Targeting\TargetingEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingEvent") * * @var string */ @@ -42,7 +42,7 @@ final class TargetingEvents /** * Fired after all targeting rules were matched and applied * - * @Event("Pimcore\Event\Targeting\TargetingEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingEvent") * * @var string */ @@ -51,7 +51,7 @@ final class TargetingEvents /** * Fired when a rule matches before any actions are applied * - * @Event("Pimcore\Event\Targeting\TargetingRuleEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingRuleEvent") * * @var string */ @@ -60,7 +60,7 @@ final class TargetingEvents /** * Fired when a rule matches after all actions were applied * - * @Event("Pimcore\Event\Targeting\TargetingRuleEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingRuleEvent") * * @var string */ @@ -71,7 +71,7 @@ final class TargetingEvents * build the condition in a custom manner instead of relying on the * default factory. * - * @Event("Pimcore\Event\Targeting\BuildConditionEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Targeting\BuildConditionEvent") * * @var string */ @@ -81,7 +81,7 @@ final class TargetingEvents * Fired when a target group which is configured on document settings * is assigned to a visitor info. * - * @Event("Pimcore\Event\Targeting\AssignDocumentTargetGroupEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Targeting\AssignDocumentTargetGroupEvent") * * @var string */ @@ -101,7 +101,7 @@ final class TargetingEvents /** * Fired before the targeting debug toolbar is rendered * - * @Event("Pimcore\Event\Targeting\RenderToolbarEvent") + * @Event("Pimcore\Bundle\PersonalizationBundle\Event\Targeting\RenderToolbarEvent") * * @var string */ diff --git a/bundles/PersonalizationBundle/src/EventListener/IndexSettingsListener.php b/bundles/PersonalizationBundle/src/EventListener/IndexSettingsListener.php new file mode 100644 index 00000000000..2906ba05130 --- /dev/null +++ b/bundles/PersonalizationBundle/src/EventListener/IndexSettingsListener.php @@ -0,0 +1,28 @@ +addSetting('maxmind_geoip_installed', (bool) \Pimcore::getContainer()->getParameter('pimcore.geoip.db_file')); + } +} diff --git a/bundles/PersonalizationBundle/src/Installer.php b/bundles/PersonalizationBundle/src/Installer.php new file mode 100644 index 00000000000..8a88d77c531 --- /dev/null +++ b/bundles/PersonalizationBundle/src/Installer.php @@ -0,0 +1,105 @@ +installDatabaseTable(); + $this->addUserPermission(); + parent::install(); + } + + public function uninstall(): void + { + // Cleanup should be done manually + + $output = new ConsoleOutput(); + $style = new SymfonyStyle(new StringInput(''), $output); + + if(!($style->confirm( + "[WARNING] Before Uninstalling the bundle, 'Target Group' references must be removed from DataObject classes,\n" . + "Custom services and Ecommerce Pricing Rules manually.\n\n" . + "Do you want to continue the uninstall?" + ,false))){ + $output->writeln("Uninstall Aborted."); + exit; + } + + $this->uninstallDatabaseTable(); + $this->removeUserPermission(); + parent::uninstall(); + } + + private function addUserPermission(): void + { + $db = \Pimcore\Db::get(); + + foreach(self::USER_PERMISSIONS as $permission) { + $db->insert('users_permission_definitions', [ + $db->quoteIdentifier('key') => $permission, + $db->quoteIdentifier('category') => self::USER_PERMISSIONS_CATEGORY, + ]); + } + } + + private function removeUserPermission(): void + { + $db = \Pimcore\Db::get(); + + foreach(self::USER_PERMISSIONS as $permission) { + $db->delete('users_permission_definitions', [ + $db->quoteIdentifier('key') => $permission, + ]); + } + } + + private function installDatabaseTable(): void + { + $sqlPath = __DIR__ . '/Resources/install/'; + $sqlFileNames = ['install.sql']; + $db = \Pimcore\Db::get(); + + foreach($sqlFileNames as $fileName) { + $statement = file_get_contents($sqlPath . $fileName); + $db->executeQuery($statement); + } + } + + private function uninstallDatabaseTable(): void + { + $sqlPath = __DIR__ . '/Resources/uninstall/'; + $sqlFileNames = ['uninstall.sql']; + $db = \Pimcore\Db::get(); + + foreach($sqlFileNames as $fileName) { + $statement = file_get_contents($sqlPath . $fileName); + $db->executeQuery($statement); + } + } +} diff --git a/bundles/PersonalizationBundle/src/Model/Document/Page.php b/bundles/PersonalizationBundle/src/Model/Document/Page.php new file mode 100644 index 00000000000..157c7553437 --- /dev/null +++ b/bundles/PersonalizationBundle/src/Model/Document/Page.php @@ -0,0 +1,117 @@ +targetGroupIds = $targetGroupIds; + } + + /** + * Get serialized list of Target Group IDs + * + * @return string + */ + public function getTargetGroupIds (): string + { + return $this->targetGroupIds; + } + + /** + * Set assigned target groups + * + * @param TargetGroup[]|int[] $targetGroups + */ + public function setTargetGroups (array $targetGroups): void + { + $ids = array_map (function ($targetGroup) { + if (is_numeric ($targetGroup)) { + return (int)$targetGroup; + } elseif ($targetGroup instanceof TargetGroup) { + return $targetGroup->getId (); + } + }, $targetGroups); + + $ids = array_filter ($ids, function ($id) { + return null !== $id && $id > 0; + }); + + $this->setTargetGroupIds ($ids); + } + + /** + * Return list of assigned target groups (via properties panel) + * + * @return TargetGroup[] + */ + public function getTargetGroups (): array + { + $ids = explode (',', $this->targetGroupIds); + + $targetGroups = array_map (function ($id) { + $id = trim ($id); + if (!empty($id)) { + $targetGroup = TargetGroup::getById ((int)$id); + if ($targetGroup) { + return $targetGroup; + } + } + }, $ids); + + $targetGroups = array_filter ($targetGroups); + + return $targetGroups; + } + +} diff --git a/bundles/PersonalizationBundle/src/Model/Document/Page/Dao.php b/bundles/PersonalizationBundle/src/Model/Document/Page/Dao.php new file mode 100644 index 00000000000..729f863c743 --- /dev/null +++ b/bundles/PersonalizationBundle/src/Model/Document/Page/Dao.php @@ -0,0 +1,80 @@ +model->setId ($id); + } + + $data = $this->db->fetchAssociative ("SELECT documents.*, documents_page.*, tree_locks.locked FROM documents + LEFT JOIN documents_page ON documents.id = documents_page.id + LEFT JOIN tree_locks ON documents.id = tree_locks.id AND tree_locks.type = 'document' + WHERE documents.id = ?", [$this->model->getId ()]); + + if (!empty($data['id'])) { + if (is_string ($data['metaData'])) { + $data['metaData'] = @unserialize ($data['metaData']); + } + if (!is_array ($data['metaData'])) { + $data['metaData'] = []; + } + $this->assignVariablesToModel ($data); + } else { + throw new Model\Exception\NotFoundException('Page with the ID ' . $this->model->getId () . " doesn't exists"); + } + } + + public function create (): void + { + parent::create (); + + $this->db->insert ('documents_page', [ + 'id' => $this->model->getId (), + ]); + } + + /** + * @throws \Exception + */ + public function delete (): void + { + $this->deleteAllProperties (); + + parent::delete (); + } +} diff --git a/bundles/PersonalizationBundle/src/Model/Document/Snippet.php b/bundles/PersonalizationBundle/src/Model/Document/Snippet.php new file mode 100644 index 00000000000..3ef0b9ac58d --- /dev/null +++ b/bundles/PersonalizationBundle/src/Model/Document/Snippet.php @@ -0,0 +1,32 @@ +model->setId($id); + } + + $data = $this->db->fetchAssociative("SELECT documents.*, documents_snippet.*, tree_locks.locked FROM documents + LEFT JOIN documents_snippet ON documents.id = documents_snippet.id + LEFT JOIN tree_locks ON documents.id = tree_locks.id AND tree_locks.type = 'document' + WHERE documents.id = ?", [$this->model->getId()]); + + if (!empty($data['id'])) { + $this->assignVariablesToModel($data); + } else { + throw new Model\Exception\NotFoundException('Snippet with the ID ' . $this->model->getId() . " doesn't exists"); + } + } + + public function create(): void + { + parent::create(); + + $this->db->insert('documents_snippet', [ + 'id' => $this->model->getId(), + ]); + } +} diff --git a/models/Document/Targeting/TargetingDocumentDaoInterface.php b/bundles/PersonalizationBundle/src/Model/Document/Targeting/TargetingDocumentDaoInterface.php similarity index 91% rename from models/Document/Targeting/TargetingDocumentDaoInterface.php rename to bundles/PersonalizationBundle/src/Model/Document/Targeting/TargetingDocumentDaoInterface.php index 14942f49e24..ca6518d851a 100644 --- a/models/Document/Targeting/TargetingDocumentDaoInterface.php +++ b/bundles/PersonalizationBundle/src/Model/Document/Targeting/TargetingDocumentDaoInterface.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Document\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Document\Targeting; interface TargetingDocumentDaoInterface { diff --git a/models/Document/Targeting/TargetingDocumentDaoTrait.php b/bundles/PersonalizationBundle/src/Model/Document/Targeting/TargetingDocumentDaoTrait.php similarity index 95% rename from models/Document/Targeting/TargetingDocumentDaoTrait.php rename to bundles/PersonalizationBundle/src/Model/Document/Targeting/TargetingDocumentDaoTrait.php index e1643496d4c..1a68dc4190c 100644 --- a/models/Document/Targeting/TargetingDocumentDaoTrait.php +++ b/bundles/PersonalizationBundle/src/Model/Document/Targeting/TargetingDocumentDaoTrait.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Document\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Document\Targeting; use Pimcore\Model\Document\PageSnippet; diff --git a/models/Document/Targeting/TargetingDocumentInterface.php b/bundles/PersonalizationBundle/src/Model/Document/Targeting/TargetingDocumentInterface.php similarity index 96% rename from models/Document/Targeting/TargetingDocumentInterface.php rename to bundles/PersonalizationBundle/src/Model/Document/Targeting/TargetingDocumentInterface.php index 781b8f84819..823bea635c6 100644 --- a/models/Document/Targeting/TargetingDocumentInterface.php +++ b/bundles/PersonalizationBundle/src/Model/Document/Targeting/TargetingDocumentInterface.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Document\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Document\Targeting; use Pimcore\Model\Element\ElementInterface; diff --git a/models/Document/TargetingDocument.php b/bundles/PersonalizationBundle/src/Model/Document/Traits/TargetDocumentTrait.php similarity index 52% rename from models/Document/TargetingDocument.php rename to bundles/PersonalizationBundle/src/Model/Document/Traits/TargetDocumentTrait.php index 302a7bb9876..1943352064a 100644 --- a/models/Document/TargetingDocument.php +++ b/bundles/PersonalizationBundle/src/Model/Document/Traits/TargetDocumentTrait.php @@ -1,5 +1,4 @@ useTargetGroup = $useTargetGroup; } @@ -37,7 +43,7 @@ public function setUseTargetGroup(int $useTargetGroup = null): void /** * {@inheritdoc} */ - public function getUseTargetGroup(): ?int + public function getUseTargetGroup (): ?int { return $this->useTargetGroup; } @@ -45,12 +51,12 @@ public function getUseTargetGroup(): ?int /** * {@inheritdoc} */ - public function getTargetGroupEditablePrefix(int $targetGroupId = null): string + public function getTargetGroupEditablePrefix (int $targetGroupId = null): string { $prefix = ''; if (!$targetGroupId) { - $targetGroupId = $this->getUseTargetGroup(); + $targetGroupId = $this->getUseTargetGroup (); } if ($targetGroupId) { @@ -63,14 +69,14 @@ public function getTargetGroupEditablePrefix(int $targetGroupId = null): string /** * {@inheritdoc} */ - public function getTargetGroupEditableName(string $name): string + public function getTargetGroupEditableName (string $name): string { - if (!$this->getUseTargetGroup()) { + if (!$this->getUseTargetGroup ()) { return $name; } - $prefix = $this->getTargetGroupEditablePrefix(); - if (!preg_match('/^' . preg_quote($prefix, '/') . '/', $name)) { + $prefix = $this->getTargetGroupEditablePrefix (); + if (!preg_match ('/^' . preg_quote ($prefix, '/') . '/', $name)) { $name = $prefix . $name; } @@ -80,30 +86,30 @@ public function getTargetGroupEditableName(string $name): string /** * {@inheritdoc} */ - public function hasTargetGroupSpecificEditables(): bool + public function hasTargetGroupSpecificEditables (): bool { - return $this->getDao()->hasTargetGroupSpecificEditables(); + return $this->getDao()->hasTargetGroupSpecificEditables (); } /** * {@inheritdoc} */ - public function getTargetGroupSpecificEditableNames(): array + public function getTargetGroupSpecificEditableNames (): array { - return $this->getDao()->getTargetGroupSpecificEditableNames(); + return $this->getDao()->getTargetGroupSpecificEditableNames (); } /** * {@inheritdoc} */ - public function setEditable(Editable $editable): static + public function setEditable (Editable $editable): static { - if ($this->getUseTargetGroup()) { - $name = $this->getTargetGroupEditableName($editable->getName()); - $editable->setName($name); + if ($this->getUseTargetGroup ()) { + $name = $this->getTargetGroupEditableName ($editable->getName ()); + $editable->setName ($name); } - parent::setEditable($editable); + parent::setEditable ($editable); return $this; } @@ -115,28 +121,28 @@ public function setEditable(Editable $editable): static * * @return Editable|null */ - public function getEditable(string $name): ?Editable + public function getEditable (string $name): ?Editable { // check if a target group is requested for this page, if yes deliver a different version of the editable (prefixed) - if ($this->getUseTargetGroup()) { - $targetGroupEditableName = $this->getTargetGroupEditableName($name); + if ($this->getUseTargetGroup ()) { + $targetGroupEditableName = $this->getTargetGroupEditableName ($name); - if ($editable = parent::getEditable($targetGroupEditableName)) { + if ($editable = parent::getEditable ($targetGroupEditableName)) { return $editable; } else { // if there's no dedicated content for this target group, inherit from the "original" content (unprefixed) // and mark it as inherited so it is clear in the ui that the content is not specific to the selected target group // replace all occurrences of the target group prefix, this is needed because of block-prefixes - $inheritedName = str_replace($this->getTargetGroupEditablePrefix(), '', $name); - $inheritedEditable = parent::getEditable($inheritedName); + $inheritedName = str_replace ($this->getTargetGroupEditablePrefix (), '', $name); + $inheritedEditable = parent::getEditable ($inheritedName); if ($inheritedEditable) { $inheritedEditable = clone $inheritedEditable; - $inheritedEditable->setDao(null); - $inheritedEditable->setName($targetGroupEditableName); - $inheritedEditable->setInherited(true); + $inheritedEditable->setDao (null); + $inheritedEditable->setName ($targetGroupEditableName); + $inheritedEditable->setInherited (true); - $this->setEditable($inheritedEditable); + $this->setEditable ($inheritedEditable); return $inheritedEditable; } @@ -144,21 +150,21 @@ public function getEditable(string $name): ?Editable } // delegate to default - return parent::getEditable($name); + return parent::getEditable ($name); } /** * {@inheritdoc} */ - public function __sleep(): array + public function __sleep (): array { $finalVars = []; - $parentVars = parent::__sleep(); + $parentVars = parent::__sleep (); $blockedVars = ['useTargetGroup']; foreach ($parentVars as $key) { - if (!in_array($key, $blockedVars)) { + if (!in_array ($key, $blockedVars)) { $finalVars[] = $key; } } diff --git a/models/Tool/Targeting/Rule.php b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule.php similarity index 97% rename from models/Tool/Targeting/Rule.php rename to bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule.php index 86dc8737989..26da262672b 100644 --- a/models/Tool/Targeting/Rule.php +++ b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule.php @@ -14,7 +14,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Tool\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting; use Pimcore\Model; @@ -54,7 +54,7 @@ class Rule extends Model\AbstractModel public static function inTarget(mixed $target): bool { - if ($target instanceof Model\Tool\Targeting\Rule) { + if ($target instanceof Rule) { $targetId = $target->getId(); } elseif (is_string($target)) { $target = self::getByName($target); diff --git a/models/Tool/Targeting/Rule/Dao.php b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule/Dao.php similarity index 94% rename from models/Tool/Targeting/Rule/Dao.php rename to bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule/Dao.php index 43a74b72e91..ba6b571e97f 100644 --- a/models/Tool/Targeting/Rule/Dao.php +++ b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule/Dao.php @@ -13,16 +13,16 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Tool\Targeting\Rule; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; use Pimcore\Model; -use Pimcore\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; use Pimcore\Tool\Serialize; /** * @internal * - * @property Rule|Model\Tool\Targeting\Rule\Dao $model + * @property Rule|Dao $model */ class Dao extends Model\Dao\AbstractDao { diff --git a/models/Tool/Targeting/Rule/Listing.php b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule/Listing.php similarity index 87% rename from models/Tool/Targeting/Rule/Listing.php rename to bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule/Listing.php index 16d828c8e6a..a0c72a44df5 100644 --- a/models/Tool/Targeting/Rule/Listing.php +++ b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule/Listing.php @@ -14,10 +14,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Tool\Targeting\Rule; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; use Pimcore\Model; -use Pimcore\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; /** * @internal diff --git a/models/Tool/Targeting/Rule/Listing/Dao.php b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule/Listing/Dao.php similarity index 83% rename from models/Tool/Targeting/Rule/Listing/Dao.php rename to bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule/Listing/Dao.php index 5f226c5a46f..86ca8c654ee 100644 --- a/models/Tool/Targeting/Rule/Listing/Dao.php +++ b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/Rule/Listing/Dao.php @@ -13,15 +13,16 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Tool\Targeting\Rule\Listing; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule\Listing; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule\Listing; use Pimcore\Model; -use Pimcore\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; /** * @internal * - * @property \Pimcore\Model\Tool\Targeting\Rule\Listing $model + * @property Listing $model */ class Dao extends Model\Listing\Dao\AbstractDao { diff --git a/models/Tool/Targeting/TargetGroup.php b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup.php similarity index 90% rename from models/Tool/Targeting/TargetGroup.php rename to bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup.php index f80f82e396d..2198b38e66a 100644 --- a/models/Tool/Targeting/TargetGroup.php +++ b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup.php @@ -14,10 +14,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Tool\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting; -use Pimcore\Event\Model\TargetGroupEvent; -use Pimcore\Event\TargetGroupEvents; +use Pimcore\Bundle\PersonalizationBundle\Event\Model\TargetGroupEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\TargetGroupEvents; use Pimcore\Event\Traits\RecursionBlockingEventDispatchHelperTrait; use Pimcore\Model; @@ -66,7 +66,7 @@ public static function getByName(string $name): ?TargetGroup public static function isIdActive(int $id): bool { - $targetGroup = Model\Tool\Targeting\TargetGroup::getById($id); + $targetGroup = TargetGroup::getById($id); if ($targetGroup) { return $targetGroup->getActive(); @@ -153,3 +153,5 @@ public function save(): void } } } + +@class_alias (TargetGroup::class, 'Pimcore\Model\Tool\Targeting\TargetGroup'); diff --git a/models/Tool/Targeting/TargetGroup/Dao.php b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup/Dao.php similarity index 95% rename from models/Tool/Targeting/TargetGroup/Dao.php rename to bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup/Dao.php index 12f5a788394..a50139aeb0e 100644 --- a/models/Tool/Targeting/TargetGroup/Dao.php +++ b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup/Dao.php @@ -13,10 +13,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Tool\Targeting\TargetGroup; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; use Pimcore\Model; -use Pimcore\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; use Pimcore\Tool\Serialize; /** diff --git a/models/Tool/Targeting/TargetGroup/Listing.php b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup/Listing.php similarity index 86% rename from models/Tool/Targeting/TargetGroup/Listing.php rename to bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup/Listing.php index c65ba40455f..be57dea3850 100644 --- a/models/Tool/Targeting/TargetGroup/Listing.php +++ b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup/Listing.php @@ -14,10 +14,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Tool\Targeting\TargetGroup; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; use Pimcore\Model; -use Pimcore\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; /** * @internal diff --git a/models/Tool/Targeting/TargetGroup/Listing/Dao.php b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup/Listing/Dao.php similarity index 89% rename from models/Tool/Targeting/TargetGroup/Listing/Dao.php rename to bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup/Listing/Dao.php index 224b1cb461e..34f2405950a 100644 --- a/models/Tool/Targeting/TargetGroup/Listing/Dao.php +++ b/bundles/PersonalizationBundle/src/Model/Tool/Targeting/TargetGroup/Listing/Dao.php @@ -13,10 +13,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Model\Tool\Targeting\TargetGroup\Listing; +namespace Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup\Listing; use Pimcore\Model; -use Pimcore\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; /** * @internal diff --git a/models/DataObject/ClassDefinition/Data/TargetGroup.php b/bundles/PersonalizationBundle/src/Pimcore/Model/DataObject/ClassDefinition/Data/TargetGroup.php similarity index 98% rename from models/DataObject/ClassDefinition/Data/TargetGroup.php rename to bundles/PersonalizationBundle/src/Pimcore/Model/DataObject/ClassDefinition/Data/TargetGroup.php index 7a35a27cf9b..0f2f20bb0b1 100644 --- a/models/DataObject/ClassDefinition/Data/TargetGroup.php +++ b/bundles/PersonalizationBundle/src/Pimcore/Model/DataObject/ClassDefinition/Data/TargetGroup.php @@ -19,7 +19,7 @@ use Pimcore\Model; use Pimcore\Model\DataObject; use Pimcore\Model\DataObject\ClassDefinition\Service; -use Pimcore\Model\Tool; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool; class TargetGroup extends Model\DataObject\ClassDefinition\Data\Select { diff --git a/models/DataObject/ClassDefinition/Data/TargetGroupMultiselect.php b/bundles/PersonalizationBundle/src/Pimcore/Model/DataObject/ClassDefinition/Data/TargetGroupMultiselect.php similarity index 97% rename from models/DataObject/ClassDefinition/Data/TargetGroupMultiselect.php rename to bundles/PersonalizationBundle/src/Pimcore/Model/DataObject/ClassDefinition/Data/TargetGroupMultiselect.php index f2a21c175f3..074915803ba 100644 --- a/models/DataObject/ClassDefinition/Data/TargetGroupMultiselect.php +++ b/bundles/PersonalizationBundle/src/Pimcore/Model/DataObject/ClassDefinition/Data/TargetGroupMultiselect.php @@ -18,7 +18,7 @@ use Pimcore\Model; use Pimcore\Model\DataObject\ClassDefinition\Service; -use Pimcore\Model\Tool; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool; class TargetGroupMultiselect extends Model\DataObject\ClassDefinition\Data\Multiselect { diff --git a/bundles/PersonalizationBundle/src/PimcorePersonalizationBundle.php b/bundles/PersonalizationBundle/src/PimcorePersonalizationBundle.php new file mode 100644 index 00000000000..aa4fd32c1d9 --- /dev/null +++ b/bundles/PersonalizationBundle/src/PimcorePersonalizationBundle.php @@ -0,0 +1,87 @@ +container->get (Installer::class); + } + + /** + * {@inheritdoc} + */ + public function build (ContainerBuilder $container): void + { + $container->addCompilerPass (new TargetingOverrideHandlersPass()); + $container->addCompilerPass(new DebugStopwatchPass()); + } + + public function getPath (): string + { + return \dirname (__DIR__); + } +} diff --git a/bundles/PersonalizationBundle/src/Resources/install/install.sql b/bundles/PersonalizationBundle/src/Resources/install/install.sql new file mode 100644 index 00000000000..e110104d5e8 --- /dev/null +++ b/bundles/PersonalizationBundle/src/Resources/install/install.sql @@ -0,0 +1,35 @@ +CREATE TABLE IF NOT EXISTS `targeting_rules` +( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL DEFAULT '', + `description` text, + `scope` varchar(50) DEFAULT NULL, + `active` tinyint(1) DEFAULT NULL, + `prio` smallint(5) unsigned NOT NULL DEFAULT '0', + `conditions` longtext, + `actions` longtext, + PRIMARY KEY (`id`) +) DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `targeting_storage` +( + `visitorId` varchar(100) NOT NULL, + `scope` varchar(50) NOT NULL, + `name` varchar(100) NOT NULL, + `value` text, + `creationDate` datetime DEFAULT NULL, + `modificationDate` datetime DEFAULT NULL, + PRIMARY KEY (`visitorId`, `scope`, `name`), + KEY `targeting_storage_scope_index` (`scope`), + KEY `targeting_storage_name_index` (`name`) +) DEFAULT CHARSET=utf8mb4; + +CREATE TABLE IF NOT EXISTS `targeting_target_groups` +( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL DEFAULT '', + `description` text, + `threshold` int(11) DEFAULT NULL, + `active` tinyint(1) DEFAULT NULL, + PRIMARY KEY (`id`) +) DEFAULT CHARSET=utf8mb4; diff --git a/bundles/PersonalizationBundle/src/Resources/uninstall/uninstall.sql b/bundles/PersonalizationBundle/src/Resources/uninstall/uninstall.sql new file mode 100644 index 00000000000..7d86300b578 --- /dev/null +++ b/bundles/PersonalizationBundle/src/Resources/uninstall/uninstall.sql @@ -0,0 +1,3 @@ +DROP TABLE IF EXISTS `targeting_rules`; +DROP TABLE IF EXISTS `targeting_storage`; +DROP TABLE IF EXISTS `targeting_target_groups`; \ No newline at end of file diff --git a/lib/Targeting/ActionHandler/ActionHandlerInterface.php b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/ActionHandlerInterface.php similarity index 75% rename from lib/Targeting/ActionHandler/ActionHandlerInterface.php rename to bundles/PersonalizationBundle/src/Targeting/ActionHandler/ActionHandlerInterface.php index 31c35590ee7..d368036457d 100644 --- a/lib/Targeting/ActionHandler/ActionHandlerInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/ActionHandlerInterface.php @@ -15,10 +15,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\ActionHandler; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler; -use Pimcore\Model\Tool\Targeting\Rule; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; interface ActionHandlerInterface { diff --git a/lib/Targeting/ActionHandler/AssignTargetGroup.php b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/AssignTargetGroup.php similarity index 89% rename from lib/Targeting/ActionHandler/AssignTargetGroup.php rename to bundles/PersonalizationBundle/src/Targeting/ActionHandler/AssignTargetGroup.php index d289e17afbc..b1cd6e68f97 100644 --- a/lib/Targeting/ActionHandler/AssignTargetGroup.php +++ b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/AssignTargetGroup.php @@ -15,13 +15,13 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\ActionHandler; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler; -use Pimcore\Model\Tool\Targeting\Rule; -use Pimcore\Model\Tool\Targeting\TargetGroup; -use Pimcore\Targeting\ConditionMatcherInterface; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Storage\TargetingStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ConditionMatcherInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\TargetingStorageInterface; class AssignTargetGroup implements ActionHandlerInterface { diff --git a/lib/Targeting/ActionHandler/CodeSnippet.php b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/CodeSnippet.php similarity index 89% rename from lib/Targeting/ActionHandler/CodeSnippet.php rename to bundles/PersonalizationBundle/src/Targeting/ActionHandler/CodeSnippet.php index 56797101dda..9733a87b887 100644 --- a/lib/Targeting/ActionHandler/CodeSnippet.php +++ b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/CodeSnippet.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\ActionHandler; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler; use Pimcore\Http\Response\CodeInjector; -use Pimcore\Model\Tool\Targeting\Rule; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Symfony\Component\HttpFoundation\Response; class CodeSnippet implements ActionHandlerInterface, ResponseTransformingActionHandlerInterface diff --git a/lib/Targeting/ActionHandler/DelegatingActionHandler.php b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/DelegatingActionHandler.php similarity index 85% rename from lib/Targeting/ActionHandler/DelegatingActionHandler.php rename to bundles/PersonalizationBundle/src/Targeting/ActionHandler/DelegatingActionHandler.php index 56ae7616a08..f56fc916a73 100644 --- a/lib/Targeting/ActionHandler/DelegatingActionHandler.php +++ b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/DelegatingActionHandler.php @@ -15,12 +15,12 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\ActionHandler; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler; -use Pimcore\Model\Tool\Targeting\Rule; -use Pimcore\Targeting\DataLoaderInterface; -use Pimcore\Targeting\DataProviderDependentInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataLoaderInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProviderDependentInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Psr\Container\ContainerInterface; class DelegatingActionHandler implements ActionHandlerInterface diff --git a/lib/Targeting/ActionHandler/Redirect.php b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/Redirect.php similarity index 90% rename from lib/Targeting/ActionHandler/Redirect.php rename to bundles/PersonalizationBundle/src/Targeting/ActionHandler/Redirect.php index a08de2f880c..cc78e9eee78 100644 --- a/lib/Targeting/ActionHandler/Redirect.php +++ b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/Redirect.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\ActionHandler; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler; use Pimcore\Model\Document; -use Pimcore\Model\Tool\Targeting\Rule; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Symfony\Component\HttpFoundation\RedirectResponse; class Redirect implements ActionHandlerInterface diff --git a/lib/Targeting/ActionHandler/ResponseTransformingActionHandlerInterface.php b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/ResponseTransformingActionHandlerInterface.php similarity index 84% rename from lib/Targeting/ActionHandler/ResponseTransformingActionHandlerInterface.php rename to bundles/PersonalizationBundle/src/Targeting/ActionHandler/ResponseTransformingActionHandlerInterface.php index 15f4e830e1b..996169af0ef 100644 --- a/lib/Targeting/ActionHandler/ResponseTransformingActionHandlerInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/ActionHandler/ResponseTransformingActionHandlerInterface.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\ActionHandler; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Symfony\Component\HttpFoundation\Response; interface ResponseTransformingActionHandlerInterface diff --git a/lib/Targeting/Code/TargetingCodeGenerator.php b/bundles/PersonalizationBundle/src/Targeting/Code/TargetingCodeGenerator.php similarity index 87% rename from lib/Targeting/Code/TargetingCodeGenerator.php rename to bundles/PersonalizationBundle/src/Targeting/Code/TargetingCodeGenerator.php index 67168fbe3d4..07ee79238cc 100644 --- a/lib/Targeting/Code/TargetingCodeGenerator.php +++ b/bundles/PersonalizationBundle/src/Targeting/Code/TargetingCodeGenerator.php @@ -15,12 +15,12 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Code; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Code; use Pimcore\Analytics\Code\CodeBlock; -use Pimcore\Event\Targeting\TargetingCodeEvent; -use Pimcore\Event\TargetingEvents; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingCodeEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\TargetingEvents; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Symfony\Component\Templating\EngineInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; @@ -61,7 +61,7 @@ public function generateCode(VisitorInfo $visitorInfo): string ]; $event = new TargetingCodeEvent( - '@PimcoreCore/Targeting/targetingCode.html.twig', + '@PimcorePersonalization/Targeting/targetingCode.html.twig', $this->buildCodeBlocks(), $data ); diff --git a/lib/Targeting/Condition/AbstractVariableCondition.php b/bundles/PersonalizationBundle/src/Targeting/Condition/AbstractVariableCondition.php similarity index 93% rename from lib/Targeting/Condition/AbstractVariableCondition.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/AbstractVariableCondition.php index 30769d6467e..43eb0658a52 100644 --- a/lib/Targeting/Condition/AbstractVariableCondition.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/AbstractVariableCondition.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; abstract class AbstractVariableCondition implements ConditionInterface, VariableConditionInterface { diff --git a/lib/Targeting/Condition/Browser.php b/bundles/PersonalizationBundle/src/Targeting/Condition/Browser.php similarity index 86% rename from lib/Targeting/Condition/Browser.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/Browser.php index 774f3192427..01aab592b5c 100644 --- a/lib/Targeting/Condition/Browser.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/Browser.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\DataProvider\Device; -use Pimcore\Targeting\DataProviderDependentInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\Device; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProviderDependentInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class Browser extends AbstractVariableCondition implements DataProviderDependentInterface { diff --git a/lib/Targeting/Condition/ConditionInterface.php b/bundles/PersonalizationBundle/src/Targeting/Condition/ConditionInterface.php similarity index 89% rename from lib/Targeting/Condition/ConditionInterface.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/ConditionInterface.php index 6f398ef542d..d1f1b30cadc 100644 --- a/lib/Targeting/Condition/ConditionInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/ConditionInterface.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; interface ConditionInterface { diff --git a/lib/Targeting/Condition/Country.php b/bundles/PersonalizationBundle/src/Targeting/Condition/Country.php similarity index 84% rename from lib/Targeting/Condition/Country.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/Country.php index 7dc2c42adde..293fb473cee 100644 --- a/lib/Targeting/Condition/Country.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/Country.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\DataProvider\GeoIp; -use Pimcore\Targeting\DataProviderDependentInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\GeoIp; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProviderDependentInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class Country extends AbstractVariableCondition implements DataProviderDependentInterface { diff --git a/lib/Targeting/Condition/EventDispatchingConditionInterface.php b/bundles/PersonalizationBundle/src/Targeting/Condition/EventDispatchingConditionInterface.php similarity index 86% rename from lib/Targeting/Condition/EventDispatchingConditionInterface.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/EventDispatchingConditionInterface.php index 701f4c6b57b..42d71801963 100644 --- a/lib/Targeting/Condition/EventDispatchingConditionInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/EventDispatchingConditionInterface.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Symfony\Component\EventDispatcher\EventDispatcherInterface; interface EventDispatchingConditionInterface diff --git a/lib/Targeting/Condition/GeoPoint.php b/bundles/PersonalizationBundle/src/Targeting/Condition/GeoPoint.php similarity index 87% rename from lib/Targeting/Condition/GeoPoint.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/GeoPoint.php index 351c908ce2b..08f942513ca 100644 --- a/lib/Targeting/Condition/GeoPoint.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/GeoPoint.php @@ -15,14 +15,14 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; use Location\Coordinate; use Location\Distance\Haversine; -use Pimcore\Targeting\DataProvider\GeoLocation; -use Pimcore\Targeting\DataProviderDependentInterface; -use Pimcore\Targeting\Model\GeoLocation as GeoLocationModel; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\GeoLocation; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProviderDependentInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\GeoLocation as GeoLocationModel; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class GeoPoint extends AbstractVariableCondition implements DataProviderDependentInterface { diff --git a/lib/Targeting/Condition/HardwarePlatform.php b/bundles/PersonalizationBundle/src/Targeting/Condition/HardwarePlatform.php similarity index 89% rename from lib/Targeting/Condition/HardwarePlatform.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/HardwarePlatform.php index a07c5f9dc25..ffc7e24aa5a 100644 --- a/lib/Targeting/Condition/HardwarePlatform.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/HardwarePlatform.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\DataProvider\Device; -use Pimcore\Targeting\DataProviderDependentInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\Device; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProviderDependentInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class HardwarePlatform extends AbstractVariableCondition implements DataProviderDependentInterface { diff --git a/lib/Targeting/Condition/Language.php b/bundles/PersonalizationBundle/src/Targeting/Condition/Language.php similarity index 90% rename from lib/Targeting/Condition/Language.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/Language.php index b2c64603ac3..d36f23fb168 100644 --- a/lib/Targeting/Condition/Language.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/Language.php @@ -15,10 +15,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\Debug\Util\OverrideAttributeResolver; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Util\OverrideAttributeResolver; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Symfony\Component\HttpFoundation\Request; class Language extends AbstractVariableCondition implements ConditionInterface diff --git a/lib/Targeting/Condition/OperatingSystem.php b/bundles/PersonalizationBundle/src/Targeting/Condition/OperatingSystem.php similarity index 88% rename from lib/Targeting/Condition/OperatingSystem.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/OperatingSystem.php index 317227d2e67..927bada6b3a 100644 --- a/lib/Targeting/Condition/OperatingSystem.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/OperatingSystem.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\DataProvider\Device; -use Pimcore\Targeting\DataProviderDependentInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\Device; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProviderDependentInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class OperatingSystem extends AbstractVariableCondition implements DataProviderDependentInterface { diff --git a/lib/Targeting/Condition/ReferringSite.php b/bundles/PersonalizationBundle/src/Targeting/Condition/ReferringSite.php similarity index 91% rename from lib/Targeting/Condition/ReferringSite.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/ReferringSite.php index 054a2388b4f..85b1fd62924 100644 --- a/lib/Targeting/Condition/ReferringSite.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/ReferringSite.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class ReferringSite extends AbstractVariableCondition implements ConditionInterface { diff --git a/lib/Targeting/Condition/SearchEngine.php b/bundles/PersonalizationBundle/src/Targeting/Condition/SearchEngine.php similarity index 94% rename from lib/Targeting/Condition/SearchEngine.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/SearchEngine.php index 7d5db4fdada..f117d2f6d50 100644 --- a/lib/Targeting/Condition/SearchEngine.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/SearchEngine.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class SearchEngine extends AbstractVariableCondition implements ConditionInterface { diff --git a/lib/Targeting/Condition/TargetGroup.php b/bundles/PersonalizationBundle/src/Targeting/Condition/TargetGroup.php similarity index 91% rename from lib/Targeting/Condition/TargetGroup.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/TargetGroup.php index ea34b15f845..62f0272847f 100644 --- a/lib/Targeting/Condition/TargetGroup.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/TargetGroup.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class TargetGroup extends AbstractVariableCondition implements ConditionInterface { diff --git a/lib/Targeting/Condition/TimeOnSite.php b/bundles/PersonalizationBundle/src/Targeting/Condition/TimeOnSite.php similarity index 84% rename from lib/Targeting/Condition/TimeOnSite.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/TimeOnSite.php index e59fb709b75..33764f38535 100644 --- a/lib/Targeting/Condition/TimeOnSite.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/TimeOnSite.php @@ -15,12 +15,12 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\DataProvider\TargetingStorage; -use Pimcore\Targeting\DataProviderDependentInterface; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Storage\TargetingStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\TargetingStorage; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProviderDependentInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\TargetingStorageInterface; class TimeOnSite implements ConditionInterface, DataProviderDependentInterface { diff --git a/lib/Targeting/Condition/Url.php b/bundles/PersonalizationBundle/src/Targeting/Condition/Url.php similarity index 91% rename from lib/Targeting/Condition/Url.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/Url.php index 8bb63d5aec7..a70440fda61 100644 --- a/lib/Targeting/Condition/Url.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/Url.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class Url extends AbstractVariableCondition implements ConditionInterface { diff --git a/lib/Targeting/Condition/VariableConditionInterface.php b/bundles/PersonalizationBundle/src/Targeting/Condition/VariableConditionInterface.php similarity index 94% rename from lib/Targeting/Condition/VariableConditionInterface.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/VariableConditionInterface.php index b7fcedcaf29..1d5c36a3c81 100644 --- a/lib/Targeting/Condition/VariableConditionInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/VariableConditionInterface.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; interface VariableConditionInterface { diff --git a/lib/Targeting/Condition/VisitedPagesBefore.php b/bundles/PersonalizationBundle/src/Targeting/Condition/VisitedPagesBefore.php similarity index 82% rename from lib/Targeting/Condition/VisitedPagesBefore.php rename to bundles/PersonalizationBundle/src/Targeting/Condition/VisitedPagesBefore.php index 500d9fe79bf..0ec6dd2f0be 100644 --- a/lib/Targeting/Condition/VisitedPagesBefore.php +++ b/bundles/PersonalizationBundle/src/Targeting/Condition/VisitedPagesBefore.php @@ -15,13 +15,13 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Condition; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Condition; -use Pimcore\Event\TargetingEvents; -use Pimcore\Targeting\DataProvider\VisitedPagesCounter; -use Pimcore\Targeting\DataProviderDependentInterface; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Service\VisitedPagesCounter as VisitedPagesCounterService; +use Pimcore\Bundle\PersonalizationBundle\Event\TargetingEvents; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\VisitedPagesCounter; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProviderDependentInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Service\VisitedPagesCounter as VisitedPagesCounterService; use Symfony\Component\EventDispatcher\GenericEvent; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; diff --git a/lib/Targeting/ConditionFactory.php b/bundles/PersonalizationBundle/src/Targeting/ConditionFactory.php similarity index 90% rename from lib/Targeting/ConditionFactory.php rename to bundles/PersonalizationBundle/src/Targeting/ConditionFactory.php index adad8edcf74..6cf619d523a 100644 --- a/lib/Targeting/ConditionFactory.php +++ b/bundles/PersonalizationBundle/src/Targeting/ConditionFactory.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; -use Pimcore\Event\Targeting\BuildConditionEvent; -use Pimcore\Event\TargetingEvents; -use Pimcore\Targeting\Condition\ConditionInterface; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\BuildConditionEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\TargetingEvents; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\ConditionInterface; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; class ConditionFactory implements ConditionFactoryInterface diff --git a/lib/Targeting/ConditionFactoryInterface.php b/bundles/PersonalizationBundle/src/Targeting/ConditionFactoryInterface.php similarity index 84% rename from lib/Targeting/ConditionFactoryInterface.php rename to bundles/PersonalizationBundle/src/Targeting/ConditionFactoryInterface.php index 8841c3e927c..07170da1320 100644 --- a/lib/Targeting/ConditionFactoryInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/ConditionFactoryInterface.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; -use Pimcore\Targeting\Condition\ConditionInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\ConditionInterface; interface ConditionFactoryInterface { diff --git a/lib/Targeting/ConditionMatcher.php b/bundles/PersonalizationBundle/src/Targeting/ConditionMatcher.php similarity index 90% rename from lib/Targeting/ConditionMatcher.php rename to bundles/PersonalizationBundle/src/Targeting/ConditionMatcher.php index 7ae0fe574f0..07b4da54d9e 100644 --- a/lib/Targeting/ConditionMatcher.php +++ b/bundles/PersonalizationBundle/src/Targeting/ConditionMatcher.php @@ -15,13 +15,13 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; -use Pimcore\Targeting\Condition\ConditionInterface; -use Pimcore\Targeting\Condition\EventDispatchingConditionInterface; -use Pimcore\Targeting\Condition\VariableConditionInterface; -use Pimcore\Targeting\ConditionMatcher\ExpressionBuilder; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\ConditionInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\EventDispatchingConditionInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Condition\VariableConditionInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ConditionMatcher\ExpressionBuilder; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Psr\Log\LoggerInterface; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; diff --git a/lib/Targeting/ConditionMatcher/ExpressionBuilder.php b/bundles/PersonalizationBundle/src/Targeting/ConditionMatcher/ExpressionBuilder.php similarity index 95% rename from lib/Targeting/ConditionMatcher/ExpressionBuilder.php rename to bundles/PersonalizationBundle/src/Targeting/ConditionMatcher/ExpressionBuilder.php index 1ca6b85079f..a0249a82f52 100644 --- a/lib/Targeting/ConditionMatcher/ExpressionBuilder.php +++ b/bundles/PersonalizationBundle/src/Targeting/ConditionMatcher/ExpressionBuilder.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\ConditionMatcher; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\ConditionMatcher; class ExpressionBuilder { diff --git a/lib/Targeting/ConditionMatcherInterface.php b/bundles/PersonalizationBundle/src/Targeting/ConditionMatcherInterface.php similarity index 88% rename from lib/Targeting/ConditionMatcherInterface.php rename to bundles/PersonalizationBundle/src/Targeting/ConditionMatcherInterface.php index 8ace59de889..e07afa43a55 100644 --- a/lib/Targeting/ConditionMatcherInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/ConditionMatcherInterface.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; interface ConditionMatcherInterface { diff --git a/lib/Targeting/DataLoader.php b/bundles/PersonalizationBundle/src/Targeting/DataLoader.php similarity index 92% rename from lib/Targeting/DataLoader.php rename to bundles/PersonalizationBundle/src/Targeting/DataLoader.php index 4a1b3f91444..6a4c6678444 100644 --- a/lib/Targeting/DataLoader.php +++ b/bundles/PersonalizationBundle/src/Targeting/DataLoader.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; use Pimcore\Debug\Traits\StopwatchTrait; -use Pimcore\Targeting\DataProvider\DataProviderInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\DataProviderInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Psr\Container\ContainerInterface; class DataLoader implements DataLoaderInterface diff --git a/lib/Targeting/DataLoaderInterface.php b/bundles/PersonalizationBundle/src/Targeting/DataLoaderInterface.php similarity index 82% rename from lib/Targeting/DataLoaderInterface.php rename to bundles/PersonalizationBundle/src/Targeting/DataLoaderInterface.php index ec10e8258d1..65355fbc197 100644 --- a/lib/Targeting/DataLoaderInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/DataLoaderInterface.php @@ -15,10 +15,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; -use Pimcore\Targeting\DataProvider\DataProviderInterface; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\DataProviderInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; interface DataLoaderInterface { diff --git a/lib/Targeting/DataProvider/DataProviderInterface.php b/bundles/PersonalizationBundle/src/Targeting/DataProvider/DataProviderInterface.php similarity index 81% rename from lib/Targeting/DataProvider/DataProviderInterface.php rename to bundles/PersonalizationBundle/src/Targeting/DataProvider/DataProviderInterface.php index edfa804c7c4..8240236bf7f 100644 --- a/lib/Targeting/DataProvider/DataProviderInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/DataProvider/DataProviderInterface.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\DataProvider; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; interface DataProviderInterface { diff --git a/lib/Targeting/DataProvider/Device.php b/bundles/PersonalizationBundle/src/Targeting/DataProvider/Device.php similarity index 95% rename from lib/Targeting/DataProvider/Device.php rename to bundles/PersonalizationBundle/src/Targeting/DataProvider/Device.php index 296247753f7..58f02bae23a 100644 --- a/lib/Targeting/DataProvider/Device.php +++ b/bundles/PersonalizationBundle/src/Targeting/DataProvider/Device.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\DataProvider; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider; use DeviceDetector\Cache\PSR6Bridge; use DeviceDetector\DeviceDetector; @@ -23,8 +23,8 @@ use DeviceDetector\Parser\OperatingSystem; use Pimcore\Cache\Core\CoreCacheHandler; -use Pimcore\Targeting\Debug\Util\OverrideAttributeResolver; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Util\OverrideAttributeResolver; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Psr\Log\LoggerInterface; use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface; use Symfony\Component\HttpFoundation\Request; diff --git a/lib/Targeting/DataProvider/GeoIp.php b/bundles/PersonalizationBundle/src/Targeting/DataProvider/GeoIp.php similarity index 94% rename from lib/Targeting/DataProvider/GeoIp.php rename to bundles/PersonalizationBundle/src/Targeting/DataProvider/GeoIp.php index e51ee2fd5ab..2f38bfce6d2 100644 --- a/lib/Targeting/DataProvider/GeoIp.php +++ b/bundles/PersonalizationBundle/src/Targeting/DataProvider/GeoIp.php @@ -15,13 +15,13 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\DataProvider; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider; use GeoIp2\Model\City; use GeoIp2\ProviderInterface; use Pimcore\Cache\Core\CoreCacheHandler; -use Pimcore\Targeting\Debug\Util\OverrideAttributeResolver; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Util\OverrideAttributeResolver; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; diff --git a/lib/Targeting/DataProvider/GeoLocation.php b/bundles/PersonalizationBundle/src/Targeting/DataProvider/GeoLocation.php similarity index 93% rename from lib/Targeting/DataProvider/GeoLocation.php rename to bundles/PersonalizationBundle/src/Targeting/DataProvider/GeoLocation.php index 4ee00a8760c..1f2b6e4e825 100644 --- a/lib/Targeting/DataProvider/GeoLocation.php +++ b/bundles/PersonalizationBundle/src/Targeting/DataProvider/GeoLocation.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\DataProvider; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider; -use Pimcore\Targeting\Debug\Util\OverrideAttributeResolver; -use Pimcore\Targeting\Model\GeoLocation as GeoLocationModel; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Util\OverrideAttributeResolver; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\GeoLocation as GeoLocationModel; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; diff --git a/lib/Targeting/DataProvider/TargetingStorage.php b/bundles/PersonalizationBundle/src/Targeting/DataProvider/TargetingStorage.php similarity index 79% rename from lib/Targeting/DataProvider/TargetingStorage.php rename to bundles/PersonalizationBundle/src/Targeting/DataProvider/TargetingStorage.php index cc3b81528b1..339d7d3c0df 100644 --- a/lib/Targeting/DataProvider/TargetingStorage.php +++ b/bundles/PersonalizationBundle/src/Targeting/DataProvider/TargetingStorage.php @@ -15,10 +15,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\DataProvider; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Storage\TargetingStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\TargetingStorageInterface; class TargetingStorage implements DataProviderInterface { diff --git a/lib/Targeting/DataProvider/VisitedPagesCounter.php b/bundles/PersonalizationBundle/src/Targeting/DataProvider/VisitedPagesCounter.php similarity index 78% rename from lib/Targeting/DataProvider/VisitedPagesCounter.php rename to bundles/PersonalizationBundle/src/Targeting/DataProvider/VisitedPagesCounter.php index a6166f7f809..5517582b3c4 100644 --- a/lib/Targeting/DataProvider/VisitedPagesCounter.php +++ b/bundles/PersonalizationBundle/src/Targeting/DataProvider/VisitedPagesCounter.php @@ -15,10 +15,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\DataProvider; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Service\VisitedPagesCounter as VisitedPagesCounterService; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Service\VisitedPagesCounter as VisitedPagesCounterService; class VisitedPagesCounter implements DataProviderInterface { diff --git a/lib/Targeting/DataProviderDependentInterface.php b/bundles/PersonalizationBundle/src/Targeting/DataProviderDependentInterface.php similarity index 93% rename from lib/Targeting/DataProviderDependentInterface.php rename to bundles/PersonalizationBundle/src/Targeting/DataProviderDependentInterface.php index f17fb2a8cbf..1ce1d63e170 100644 --- a/lib/Targeting/DataProviderDependentInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/DataProviderDependentInterface.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; /** * Defines a component which depends on data providers. Currently supported for diff --git a/lib/Targeting/Debug/Form/DeviceType.php b/bundles/PersonalizationBundle/src/Targeting/Debug/Form/DeviceType.php similarity index 96% rename from lib/Targeting/Debug/Form/DeviceType.php rename to bundles/PersonalizationBundle/src/Targeting/Debug/Form/DeviceType.php index 621ad2ce2e0..55cf22424b8 100644 --- a/lib/Targeting/Debug/Form/DeviceType.php +++ b/bundles/PersonalizationBundle/src/Targeting/Debug/Form/DeviceType.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Debug\Form; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; diff --git a/lib/Targeting/Debug/Form/LocationType.php b/bundles/PersonalizationBundle/src/Targeting/Debug/Form/LocationType.php similarity index 94% rename from lib/Targeting/Debug/Form/LocationType.php rename to bundles/PersonalizationBundle/src/Targeting/Debug/Form/LocationType.php index 7a683ea82a1..e68f9f12561 100644 --- a/lib/Targeting/Debug/Form/LocationType.php +++ b/bundles/PersonalizationBundle/src/Targeting/Debug/Form/LocationType.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Debug\Form; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CountryType; diff --git a/lib/Targeting/Debug/Override/DeviceOverrideHandler.php b/bundles/PersonalizationBundle/src/Targeting/Debug/Override/DeviceOverrideHandler.php similarity index 79% rename from lib/Targeting/Debug/Override/DeviceOverrideHandler.php rename to bundles/PersonalizationBundle/src/Targeting/Debug/Override/DeviceOverrideHandler.php index 7d88177d3d8..bef4b260c92 100644 --- a/lib/Targeting/Debug/Override/DeviceOverrideHandler.php +++ b/bundles/PersonalizationBundle/src/Targeting/Debug/Override/DeviceOverrideHandler.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Debug\Override; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Override; -use Pimcore\Targeting\Debug\Form\DeviceType; -use Pimcore\Targeting\Debug\Util\OverrideAttributeResolver; -use Pimcore\Targeting\OverrideHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Form\DeviceType; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Util\OverrideAttributeResolver; +use Pimcore\Bundle\PersonalizationBundle\Targeting\OverrideHandlerInterface; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\HttpFoundation\Request; diff --git a/lib/Targeting/Debug/Override/DocumentTargetingOverrideHandler.php b/bundles/PersonalizationBundle/src/Targeting/Debug/Override/DocumentTargetingOverrideHandler.php similarity index 86% rename from lib/Targeting/Debug/Override/DocumentTargetingOverrideHandler.php rename to bundles/PersonalizationBundle/src/Targeting/Debug/Override/DocumentTargetingOverrideHandler.php index b456429462c..c9ec4b8ec24 100644 --- a/lib/Targeting/Debug/Override/DocumentTargetingOverrideHandler.php +++ b/bundles/PersonalizationBundle/src/Targeting/Debug/Override/DocumentTargetingOverrideHandler.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Debug\Override; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Override; -use Pimcore\Model\Tool\Targeting\TargetGroup; -use Pimcore\Targeting\Document\DocumentTargetingConfigurator; -use Pimcore\Targeting\OverrideHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Document\DocumentTargetingConfigurator; +use Pimcore\Bundle\PersonalizationBundle\Targeting\OverrideHandlerInterface; use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader; use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; diff --git a/lib/Targeting/Debug/Override/LanguageOverrideHandler.php b/bundles/PersonalizationBundle/src/Targeting/Debug/Override/LanguageOverrideHandler.php similarity index 83% rename from lib/Targeting/Debug/Override/LanguageOverrideHandler.php rename to bundles/PersonalizationBundle/src/Targeting/Debug/Override/LanguageOverrideHandler.php index e096dc9df23..8de41809da9 100644 --- a/lib/Targeting/Debug/Override/LanguageOverrideHandler.php +++ b/bundles/PersonalizationBundle/src/Targeting/Debug/Override/LanguageOverrideHandler.php @@ -15,10 +15,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Debug\Override; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Override; -use Pimcore\Targeting\Debug\Util\OverrideAttributeResolver; -use Pimcore\Targeting\OverrideHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Util\OverrideAttributeResolver; +use Pimcore\Bundle\PersonalizationBundle\Targeting\OverrideHandlerInterface; use Symfony\Component\Form\Extension\Core\Type\LanguageType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\HttpFoundation\Request; diff --git a/lib/Targeting/Debug/Override/LocationOverrideHandler.php b/bundles/PersonalizationBundle/src/Targeting/Debug/Override/LocationOverrideHandler.php similarity index 80% rename from lib/Targeting/Debug/Override/LocationOverrideHandler.php rename to bundles/PersonalizationBundle/src/Targeting/Debug/Override/LocationOverrideHandler.php index 280aad4553a..51910f32997 100644 --- a/lib/Targeting/Debug/Override/LocationOverrideHandler.php +++ b/bundles/PersonalizationBundle/src/Targeting/Debug/Override/LocationOverrideHandler.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Debug\Override; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Override; -use Pimcore\Targeting\Debug\Form\LocationType; -use Pimcore\Targeting\Debug\Util\OverrideAttributeResolver; -use Pimcore\Targeting\OverrideHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Form\LocationType; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Util\OverrideAttributeResolver; +use Pimcore\Bundle\PersonalizationBundle\Targeting\OverrideHandlerInterface; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\HttpFoundation\Request; diff --git a/lib/Targeting/Debug/OverrideHandler.php b/bundles/PersonalizationBundle/src/Targeting/Debug/OverrideHandler.php similarity index 94% rename from lib/Targeting/Debug/OverrideHandler.php rename to bundles/PersonalizationBundle/src/Targeting/Debug/OverrideHandler.php index 11228ca783e..5e385d1dbec 100644 --- a/lib/Targeting/Debug/OverrideHandler.php +++ b/bundles/PersonalizationBundle/src/Targeting/Debug/OverrideHandler.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Debug; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Debug; -use Pimcore\Targeting\OverrideHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\OverrideHandlerInterface; use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; diff --git a/lib/Targeting/Debug/TargetingDataCollector.php b/bundles/PersonalizationBundle/src/Targeting/Debug/TargetingDataCollector.php similarity index 89% rename from lib/Targeting/Debug/TargetingDataCollector.php rename to bundles/PersonalizationBundle/src/Targeting/Debug/TargetingDataCollector.php index 7b56dffddc6..fee8a278ea8 100644 --- a/lib/Targeting/Debug/TargetingDataCollector.php +++ b/bundles/PersonalizationBundle/src/Targeting/Debug/TargetingDataCollector.php @@ -15,17 +15,17 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Debug; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Debug; use Pimcore\Debug\Traits\StopwatchTrait; use Pimcore\Model\Document; -use Pimcore\Model\Document\Targeting\TargetingDocumentInterface; -use Pimcore\Model\Tool\Targeting\TargetGroup; -use Pimcore\Targeting\DataProvider\TargetingStorage; -use Pimcore\Targeting\DataProvider\VisitedPagesCounter; -use Pimcore\Targeting\Document\DocumentTargetingConfigurator; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Storage\TargetingStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Model\Document\Targeting\TargetingDocumentInterface; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\TargetingStorage; +use Pimcore\Bundle\PersonalizationBundle\Targeting\DataProvider\VisitedPagesCounter; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Document\DocumentTargetingConfigurator; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\TargetingStorageInterface; class TargetingDataCollector { diff --git a/lib/Targeting/Debug/Util/OverrideAttributeResolver.php b/bundles/PersonalizationBundle/src/Targeting/Debug/Util/OverrideAttributeResolver.php similarity index 89% rename from lib/Targeting/Debug/Util/OverrideAttributeResolver.php rename to bundles/PersonalizationBundle/src/Targeting/Debug/Util/OverrideAttributeResolver.php index e820a66145e..aeb23aa1ee3 100644 --- a/lib/Targeting/Debug/Util/OverrideAttributeResolver.php +++ b/bundles/PersonalizationBundle/src/Targeting/Debug/Util/OverrideAttributeResolver.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Debug\Util; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\Util; -use Pimcore\Targeting\OverrideHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\OverrideHandlerInterface; use Symfony\Component\HttpFoundation\Request; class OverrideAttributeResolver diff --git a/lib/Targeting/Document/DocumentTargetingConfigurator.php b/bundles/PersonalizationBundle/src/Targeting/Document/DocumentTargetingConfigurator.php similarity index 94% rename from lib/Targeting/Document/DocumentTargetingConfigurator.php rename to bundles/PersonalizationBundle/src/Targeting/Document/DocumentTargetingConfigurator.php index f604e249f50..5f6b84b36f4 100644 --- a/lib/Targeting/Document/DocumentTargetingConfigurator.php +++ b/bundles/PersonalizationBundle/src/Targeting/Document/DocumentTargetingConfigurator.php @@ -15,15 +15,16 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Document; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Document; use Pimcore\Bundle\AdminBundle\Security\User\UserLoader; use Pimcore\Cache\Core\CoreCacheHandler; use Pimcore\Http\RequestHelper; use Pimcore\Model\Document; -use Pimcore\Model\Document\Targeting\TargetingDocumentInterface; -use Pimcore\Model\Tool\Targeting\TargetGroup; -use Pimcore\Targeting\VisitorInfoStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Model\Document\Targeting\TargetingDocumentInterface; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface; +use Pimcore\Model\Document\PageSnippet; class DocumentTargetingConfigurator { @@ -196,7 +197,8 @@ public function getTargetGroupsForDocument(Document $document): array if (!$document instanceof TargetingDocumentInterface) { return []; } - /** @var Document\TargetingDocument $document */ + + /** @var PageSnippet $document */ $cacheKey = sprintf('document_target_groups_%d', $document->getId()); if ($targetGroups = $this->cache->load($cacheKey)) { diff --git a/lib/Targeting/EventListener/DocumentTargetGroupListener.php b/bundles/PersonalizationBundle/src/Targeting/EventListener/DocumentTargetGroupListener.php similarity index 65% rename from lib/Targeting/EventListener/DocumentTargetGroupListener.php rename to bundles/PersonalizationBundle/src/Targeting/EventListener/DocumentTargetGroupListener.php index 687b537b6a6..cf3582f7cac 100644 --- a/lib/Targeting/EventListener/DocumentTargetGroupListener.php +++ b/bundles/PersonalizationBundle/src/Targeting/EventListener/DocumentTargetGroupListener.php @@ -15,18 +15,23 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\EventListener; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener; +use Pimcore\Bundle\PersonalizationBundle\Model\Document\Page; +use Pimcore\Bundle\PersonalizationBundle\Model\Document\Targeting\TargetingDocumentInterface; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; use Pimcore\Bundle\StaticRoutesBundle\Model\Staticroute; -use Pimcore\Event\Targeting\AssignDocumentTargetGroupEvent; -use Pimcore\Event\Targeting\TargetingEvent; -use Pimcore\Event\TargetingEvents; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\AssignDocumentTargetGroupEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\TargetingEvents; +use Pimcore\Event\DocumentEvents; use Pimcore\Http\Request\Resolver\DocumentResolver; use Pimcore\Model\Document; -use Pimcore\Targeting\ActionHandler\ActionHandlerInterface; -use Pimcore\Targeting\ActionHandler\DelegatingActionHandler; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\ActionHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\DelegatingActionHandler; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\EventDispatcher\GenericEvent; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** @@ -59,6 +64,7 @@ public static function getSubscribedEvents(): array { return [ TargetingEvents::PRE_RESOLVE => 'onVisitorInfoResolve', + DocumentEvents::EDITABLE_RENDERLET_PRE_RENDER => 'configureElementTargeting' ]; } @@ -74,7 +80,7 @@ public function onVisitorInfoResolve(TargetingEvent $event): void private function assignDocumentTargetGroups(Document $document, VisitorInfo $visitorInfo): void { - if (!$document instanceof Document\Page) { + if (!$document instanceof Page) { return; } @@ -101,4 +107,21 @@ private function assignDocumentTargetGroups(Document $document, VisitorInfo $vis ); } } + + public function configureElementTargeting(GenericEvent $event): void + { + $requestParams = $event->getArgument('requestParams'); + $element = $event->getArgument('element'); + if (!$element instanceof TargetingDocumentInterface) { + return; + } + + // set selected target group on element + if ($requestParams['_ptg'] ?? false) { + $targetGroup = TargetGroup::getById((int)$requestParams['_ptg']); + if ($targetGroup) { + $element->setUseTargetGroup($targetGroup->getId()); + } + } + } } diff --git a/lib/Targeting/EventListener/FullPageCacheCookieCleanupListener.php b/bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/FullPageCacheCookieCleanupListener.php similarity index 91% rename from lib/Targeting/EventListener/FullPageCacheCookieCleanupListener.php rename to bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/FullPageCacheCookieCleanupListener.php index 25f52814b9c..b46728f8c1c 100644 --- a/lib/Targeting/EventListener/FullPageCacheCookieCleanupListener.php +++ b/bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/FullPageCacheCookieCleanupListener.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\EventListener; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\Frontend; use Pimcore\Event\Cache\FullPage\PrepareResponseEvent; use Pimcore\Event\FullPageCacheEvents; -use Pimcore\Targeting\Storage\CookieStorage; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\CookieStorage; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Cookie; diff --git a/bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/TargetingDocumentRendererListener.php b/bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/TargetingDocumentRendererListener.php new file mode 100644 index 00000000000..d89d50bbec6 --- /dev/null +++ b/bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/TargetingDocumentRendererListener.php @@ -0,0 +1,55 @@ + 'onPreRender', + DocumentEvents::INCLUDERENDERER_PRE_RENDER => 'onPreRender' + ]; + } + + public function onPreRender(DocumentEvent $event): void + { + $document = $event->getDocument(); + $this->targetingConfigurator->configureTargetGroup($document); + } +} diff --git a/bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/TargetingElementListener.php b/bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/TargetingElementListener.php new file mode 100644 index 00000000000..1e07e0113e4 --- /dev/null +++ b/bundles/PersonalizationBundle/src/Targeting/EventListener/Frontend/TargetingElementListener.php @@ -0,0 +1,102 @@ + ['onKernelController', 30], // has to be after DocumentFallbackListener + ]; + } + + public function onKernelController (ControllerEvent $event): void + { + if ($event->isMainRequest ()) { + $request = $event->getRequest (); + if (!$this->matchesPimcoreContext ($request, PimcoreContextResolver::CONTEXT_DEFAULT)) { + return; + } + + if ($request->attributes->get ('_route') === 'fos_js_routing_js') { + return; + } + + $document = $this->documentResolver->getDocument ($request); + + if ($document) { + // apply target group configuration + $this->applyTargetGroups ($request, $document); + $this->documentResolver->setDocument ($request, $document); + } + } + } + + protected function applyTargetGroups (Request $request, Document $document): void + { + if (!$document instanceof TargetingDocumentInterface) { + return; + } + + if (class_exists (Staticroute::class) && null !== Staticroute::getCurrentRoute ()) { + return; + } + + // reset because of preview and editmode (saved in session) + $document->setUseTargetGroup (null); + + $this->targetingConfigurator->configureTargetGroup ($document); + + if ($document->getUseTargetGroup ()) { + $this->logger->info ('Setting target group to {targetGroup} for document {document}', [ + 'targetGroup' => $document->getUseTargetGroup (), + 'document' => $document->getFullPath (), + ]); + } + } +} diff --git a/bundles/PersonalizationBundle/src/Targeting/EventListener/TargetingFullPageCacheListener.php b/bundles/PersonalizationBundle/src/Targeting/EventListener/TargetingFullPageCacheListener.php new file mode 100644 index 00000000000..5abbb1f90a5 --- /dev/null +++ b/bundles/PersonalizationBundle/src/Targeting/EventListener/TargetingFullPageCacheListener.php @@ -0,0 +1,81 @@ +isMainRequest()) { + return; + } + + $request = $event->getRequest(); + if (!\Pimcore\Tool::isFrontend() || \Pimcore\Tool::isFrontendRequestByAdmin($request)) { + return; + } + + if (!$this->matchesPimcoreContext($request, PimcoreContextResolver::CONTEXT_DEFAULT)) { + return; + } + + // check if targeting matched anything and disable cache + if ($this->disabledByTargeting()) { + $this->disable('Targeting matched rules/target groups'); + + return; + } + + parent::onKernelResponse($event); + } + + public function disabledByTargeting(): bool + { + if (!$this->visitorInfoStorage->hasVisitorInfo()) { + return false; + } + + $visitorInfo = $this->visitorInfoStorage->getVisitorInfo(); + + if (!empty($visitorInfo->getMatchingTargetingRules())) { + return true; + } + + if (!empty($visitorInfo->getTargetGroupAssignments())) { + return true; + } + + return false; + } +} diff --git a/lib/Targeting/EventListener/TargetingListener.php b/bundles/PersonalizationBundle/src/Targeting/EventListener/TargetingListener.php similarity index 90% rename from lib/Targeting/EventListener/TargetingListener.php rename to bundles/PersonalizationBundle/src/Targeting/EventListener/TargetingListener.php index 88f32593bbf..67a053fb91f 100644 --- a/lib/Targeting/EventListener/TargetingListener.php +++ b/bundles/PersonalizationBundle/src/Targeting/EventListener/TargetingListener.php @@ -15,25 +15,25 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\EventListener; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener; use Pimcore\Bundle\CoreBundle\EventListener\Traits\EnabledTrait; use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait; use Pimcore\Bundle\CoreBundle\EventListener\Traits\ResponseInjectionTrait; use Pimcore\Bundle\CoreBundle\EventListener\Traits\StaticPageContextAwareTrait; use Pimcore\Debug\Traits\StopwatchTrait; -use Pimcore\Event\Targeting\TargetingEvent; -use Pimcore\Event\TargetingEvents; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\TargetingEvents; use Pimcore\Http\Request\Resolver\PimcoreContextResolver; use Pimcore\Http\RequestHelper; -use Pimcore\Targeting\ActionHandler\ActionHandlerInterface; -use Pimcore\Targeting\ActionHandler\AssignTargetGroup; -use Pimcore\Targeting\ActionHandler\DelegatingActionHandler; -use Pimcore\Targeting\ActionHandler\ResponseTransformingActionHandlerInterface; -use Pimcore\Targeting\Code\TargetingCodeGenerator; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\VisitorInfoResolver; -use Pimcore\Targeting\VisitorInfoStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\ActionHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\AssignTargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\DelegatingActionHandler; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\ResponseTransformingActionHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Code\TargetingCodeGenerator; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoResolver; +use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\RequestEvent; diff --git a/lib/Targeting/EventListener/TargetingSessionBagListener.php b/bundles/PersonalizationBundle/src/Targeting/EventListener/TargetingSessionBagListener.php similarity index 95% rename from lib/Targeting/EventListener/TargetingSessionBagListener.php rename to bundles/PersonalizationBundle/src/Targeting/EventListener/TargetingSessionBagListener.php index 33d3213aa77..a5152c09786 100644 --- a/lib/Targeting/EventListener/TargetingSessionBagListener.php +++ b/bundles/PersonalizationBundle/src/Targeting/EventListener/TargetingSessionBagListener.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\EventListener; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener; use Pimcore\Config; use Pimcore\Event\Cache\FullPage\IgnoredSessionKeysEvent; @@ -135,6 +135,7 @@ public function prepareFullPageCacheResponse(PrepareResponseEvent $event): void protected function isEnabled(): bool { - return $this->config['targeting']['session']['enabled']; + return \Pimcore::getKernel()->getContainer()->getParameter ('pimcore_personalization.targeting.session.enabled'); + } } diff --git a/lib/Targeting/EventListener/ToolbarListener.php b/bundles/PersonalizationBundle/src/Targeting/EventListener/ToolbarListener.php similarity index 89% rename from lib/Targeting/EventListener/ToolbarListener.php rename to bundles/PersonalizationBundle/src/Targeting/EventListener/ToolbarListener.php index 3db85cec390..e8d9763e3e5 100644 --- a/lib/Targeting/EventListener/ToolbarListener.php +++ b/bundles/PersonalizationBundle/src/Targeting/EventListener/ToolbarListener.php @@ -15,20 +15,20 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\EventListener; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener; use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait; -use Pimcore\Event\Targeting\RenderToolbarEvent; -use Pimcore\Event\Targeting\TargetingEvent; -use Pimcore\Event\TargetingEvents; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\RenderToolbarEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\TargetingEvents; use Pimcore\Http\Request\Resolver\DocumentResolver; use Pimcore\Http\Request\Resolver\PimcoreContextResolver; use Pimcore\Http\Response\CodeInjector; use Pimcore\Model\Document; -use Pimcore\Targeting\Debug\OverrideHandler; -use Pimcore\Targeting\Debug\TargetingDataCollector; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\VisitorInfoStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\OverrideHandler; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Debug\TargetingDataCollector; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\VisitorInfoStorageInterface; use Pimcore\Tool\Authentication; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; @@ -172,7 +172,7 @@ private function collectTemplateData(VisitorInfo $visitorInfo, Document $documen private function injectToolbar(Response $response, array $data): void { - $event = new RenderToolbarEvent('@PimcoreCore/Targeting/toolbar/toolbar.html.twig', $data); + $event = new RenderToolbarEvent('@PimcorePersonalization/Targeting/toolbar/toolbar.html.twig', $data); $this->eventDispatcher->dispatch($event, TargetingEvents::RENDER_TOOLBAR); diff --git a/lib/Targeting/EventListener/VisitedPagesCountListener.php b/bundles/PersonalizationBundle/src/Targeting/EventListener/VisitedPagesCountListener.php similarity index 87% rename from lib/Targeting/EventListener/VisitedPagesCountListener.php rename to bundles/PersonalizationBundle/src/Targeting/EventListener/VisitedPagesCountListener.php index 2e94f8f551f..91d711b2520 100644 --- a/lib/Targeting/EventListener/VisitedPagesCountListener.php +++ b/bundles/PersonalizationBundle/src/Targeting/EventListener/VisitedPagesCountListener.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\EventListener; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener; -use Pimcore\Event\Targeting\TargetingEvent; -use Pimcore\Event\TargetingEvents; -use Pimcore\Targeting\Service\VisitedPagesCounter; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\TargetingEvents; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Service\VisitedPagesCounter; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class VisitedPagesCountListener implements EventSubscriberInterface diff --git a/lib/Targeting/Maintenance/TargetingStorageTask.php b/bundles/PersonalizationBundle/src/Targeting/Maintenance/TargetingStorageTask.php similarity index 79% rename from lib/Targeting/Maintenance/TargetingStorageTask.php rename to bundles/PersonalizationBundle/src/Targeting/Maintenance/TargetingStorageTask.php index 30ab33cecaa..82bdb3ef045 100644 --- a/lib/Targeting/Maintenance/TargetingStorageTask.php +++ b/bundles/PersonalizationBundle/src/Targeting/Maintenance/TargetingStorageTask.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Maintenance; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Maintenance; use Pimcore\Maintenance\TaskInterface; -use Pimcore\Targeting\Storage\MaintenanceStorageInterface; -use Pimcore\Targeting\Storage\TargetingStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\MaintenanceStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\TargetingStorageInterface; class TargetingStorageTask implements TaskInterface { diff --git a/lib/Targeting/Model/GeoLocation.php b/bundles/PersonalizationBundle/src/Targeting/Model/GeoLocation.php similarity index 96% rename from lib/Targeting/Model/GeoLocation.php rename to bundles/PersonalizationBundle/src/Targeting/Model/GeoLocation.php index abf72c6ed93..19e16773296 100644 --- a/lib/Targeting/Model/GeoLocation.php +++ b/bundles/PersonalizationBundle/src/Targeting/Model/GeoLocation.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Model; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Model; class GeoLocation { diff --git a/lib/Targeting/Model/TargetGroupAssignment.php b/bundles/PersonalizationBundle/src/Targeting/Model/TargetGroupAssignment.php similarity index 89% rename from lib/Targeting/Model/TargetGroupAssignment.php rename to bundles/PersonalizationBundle/src/Targeting/Model/TargetGroupAssignment.php index 64e7d7e8192..3ccf3bc0c79 100644 --- a/lib/Targeting/Model/TargetGroupAssignment.php +++ b/bundles/PersonalizationBundle/src/Targeting/Model/TargetGroupAssignment.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Model; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Model; -use Pimcore\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; class TargetGroupAssignment { diff --git a/lib/Targeting/Model/VisitorInfo.php b/bundles/PersonalizationBundle/src/Targeting/Model/VisitorInfo.php similarity index 97% rename from lib/Targeting/Model/VisitorInfo.php rename to bundles/PersonalizationBundle/src/Targeting/Model/VisitorInfo.php index bc7be1b981a..38cfc651aae 100644 --- a/lib/Targeting/Model/VisitorInfo.php +++ b/bundles/PersonalizationBundle/src/Targeting/Model/VisitorInfo.php @@ -15,10 +15,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Model; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Model; -use Pimcore\Model\Tool\Targeting\Rule; -use Pimcore\Model\Tool\Targeting\TargetGroup; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\TargetGroup; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; diff --git a/lib/Targeting/OverrideHandlerInterface.php b/bundles/PersonalizationBundle/src/Targeting/OverrideHandlerInterface.php similarity index 95% rename from lib/Targeting/OverrideHandlerInterface.php rename to bundles/PersonalizationBundle/src/Targeting/OverrideHandlerInterface.php index c9e102fecce..abf6071752f 100644 --- a/lib/Targeting/OverrideHandlerInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/OverrideHandlerInterface.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\HttpFoundation\Request; diff --git a/lib/Targeting/Service/VisitedPagesCounter.php b/bundles/PersonalizationBundle/src/Targeting/Service/VisitedPagesCounter.php similarity index 88% rename from lib/Targeting/Service/VisitedPagesCounter.php rename to bundles/PersonalizationBundle/src/Targeting/Service/VisitedPagesCounter.php index cece9acbd6c..28284ce7e2f 100644 --- a/lib/Targeting/Service/VisitedPagesCounter.php +++ b/bundles/PersonalizationBundle/src/Targeting/Service/VisitedPagesCounter.php @@ -15,10 +15,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Service; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Service; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Storage\TargetingStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\TargetingStorageInterface; /** * Makes sure a page visit is counted only once per request. diff --git a/lib/Targeting/Storage/Cookie/AbstractCookieSaveHandler.php b/bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/AbstractCookieSaveHandler.php similarity index 97% rename from lib/Targeting/Storage/Cookie/AbstractCookieSaveHandler.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/AbstractCookieSaveHandler.php index d1b55051378..b0a58420641 100644 --- a/lib/Targeting/Storage/Cookie/AbstractCookieSaveHandler.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/AbstractCookieSaveHandler.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage\Cookie; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Cookie; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\Request; diff --git a/lib/Targeting/Storage/Cookie/CookieSaveHandlerInterface.php b/bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/CookieSaveHandlerInterface.php similarity index 92% rename from lib/Targeting/Storage/Cookie/CookieSaveHandlerInterface.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/CookieSaveHandlerInterface.php index 435f1b43c0d..6bea8dc7b8c 100644 --- a/lib/Targeting/Storage/Cookie/CookieSaveHandlerInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/CookieSaveHandlerInterface.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage\Cookie; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Cookie; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; diff --git a/lib/Targeting/Storage/Cookie/JWTCookieSaveHandler.php b/bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/JWTCookieSaveHandler.php similarity index 98% rename from lib/Targeting/Storage/Cookie/JWTCookieSaveHandler.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/JWTCookieSaveHandler.php index 1b1b2722e54..a5e3267ba00 100644 --- a/lib/Targeting/Storage/Cookie/JWTCookieSaveHandler.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/JWTCookieSaveHandler.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage\Cookie; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Cookie; use Lcobucci\JWT\Builder; use Lcobucci\JWT\Configuration; diff --git a/lib/Targeting/Storage/Cookie/JsonCookieSaveHandler.php b/bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/JsonCookieSaveHandler.php similarity index 94% rename from lib/Targeting/Storage/Cookie/JsonCookieSaveHandler.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/JsonCookieSaveHandler.php index 8daf545ddc9..e4898bf6c08 100644 --- a/lib/Targeting/Storage/Cookie/JsonCookieSaveHandler.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/Cookie/JsonCookieSaveHandler.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage\Cookie; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Cookie; /** * NOTE: using this save handler is inherently insecure and can open vulnerabilities by injecting malicious data into the diff --git a/lib/Targeting/Storage/CookieStorage.php b/bundles/PersonalizationBundle/src/Targeting/Storage/CookieStorage.php similarity index 95% rename from lib/Targeting/Storage/CookieStorage.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/CookieStorage.php index 0c877f26a5a..7acaf783dd9 100644 --- a/lib/Targeting/Storage/CookieStorage.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/CookieStorage.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Storage\Cookie\CookieSaveHandlerInterface; -use Pimcore\Targeting\Storage\Traits\TimestampsTrait; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Cookie\CookieSaveHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Traits\TimestampsTrait; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpKernel\Event\ResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; diff --git a/lib/Targeting/Storage/DbStorage.php b/bundles/PersonalizationBundle/src/Targeting/Storage/DbStorage.php similarity index 98% rename from lib/Targeting/Storage/DbStorage.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/DbStorage.php index 07e517e3f84..bc75e9e0816 100644 --- a/lib/Targeting/Storage/DbStorage.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/DbStorage.php @@ -15,14 +15,14 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver\Result; use Doctrine\DBAL\Query\QueryBuilder; use Doctrine\DBAL\Types\Types; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Storage\Traits\TimestampsTrait; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Traits\TimestampsTrait; use Symfony\Component\OptionsResolver\OptionsResolver; class DbStorage implements TargetingStorageInterface, MaintenanceStorageInterface diff --git a/lib/Targeting/Storage/FallbackStorage.php b/bundles/PersonalizationBundle/src/Targeting/Storage/FallbackStorage.php similarity index 97% rename from lib/Targeting/Storage/FallbackStorage.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/FallbackStorage.php index 2c23265defd..4e0fa4c614c 100644 --- a/lib/Targeting/Storage/FallbackStorage.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/FallbackStorage.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; use Psr\Log\LoggerInterface; use Symfony\Component\OptionsResolver\OptionsResolver; diff --git a/lib/Targeting/Storage/MaintenanceStorageInterface.php b/bundles/PersonalizationBundle/src/Targeting/Storage/MaintenanceStorageInterface.php similarity index 91% rename from lib/Targeting/Storage/MaintenanceStorageInterface.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/MaintenanceStorageInterface.php index 2c42b99109f..2fed274b296 100644 --- a/lib/Targeting/Storage/MaintenanceStorageInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/MaintenanceStorageInterface.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage; interface MaintenanceStorageInterface { diff --git a/lib/Targeting/Storage/RedisStorage.php b/bundles/PersonalizationBundle/src/Targeting/Storage/RedisStorage.php similarity index 96% rename from lib/Targeting/Storage/RedisStorage.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/RedisStorage.php index ecef8163767..82e405cad16 100644 --- a/lib/Targeting/Storage/RedisStorage.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/RedisStorage.php @@ -15,10 +15,10 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Storage\Traits\TimestampsTrait; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Traits\TimestampsTrait; class RedisStorage implements TargetingStorageInterface { diff --git a/lib/Targeting/Storage/SessionStorage.php b/bundles/PersonalizationBundle/src/Targeting/Storage/SessionStorage.php similarity index 95% rename from lib/Targeting/Storage/SessionStorage.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/SessionStorage.php index 206dc9f3e09..77b8cb4e812 100644 --- a/lib/Targeting/Storage/SessionStorage.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/SessionStorage.php @@ -15,11 +15,11 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage; -use Pimcore\Targeting\EventListener\TargetingSessionBagListener; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Storage\Traits\TimestampsTrait; +use Pimcore\Bundle\PersonalizationBundle\Targeting\EventListener\TargetingSessionBagListener; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Traits\TimestampsTrait; use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBag; class SessionStorage implements TargetingStorageInterface diff --git a/lib/Targeting/Storage/TargetingStorageInterface.php b/bundles/PersonalizationBundle/src/Targeting/Storage/TargetingStorageInterface.php similarity index 93% rename from lib/Targeting/Storage/TargetingStorageInterface.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/TargetingStorageInterface.php index 29035d98b50..7865f87ecfa 100644 --- a/lib/Targeting/Storage/TargetingStorageInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/TargetingStorageInterface.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; /** * This defines the interface for a persistent targeting storage (e.g. Session). The targeting storage needs to define diff --git a/lib/Targeting/Storage/Traits/TimestampsTrait.php b/bundles/PersonalizationBundle/src/Targeting/Storage/Traits/TimestampsTrait.php similarity index 93% rename from lib/Targeting/Storage/Traits/TimestampsTrait.php rename to bundles/PersonalizationBundle/src/Targeting/Storage/Traits/TimestampsTrait.php index 82d9e39f66d..c3976c205c7 100644 --- a/lib/Targeting/Storage/Traits/TimestampsTrait.php +++ b/bundles/PersonalizationBundle/src/Targeting/Storage/Traits/TimestampsTrait.php @@ -15,7 +15,7 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting\Storage\Traits; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\Traits; trait TimestampsTrait { diff --git a/lib/Targeting/VisitorInfoResolver.php b/bundles/PersonalizationBundle/src/Targeting/VisitorInfoResolver.php similarity index 90% rename from lib/Targeting/VisitorInfoResolver.php rename to bundles/PersonalizationBundle/src/Targeting/VisitorInfoResolver.php index 9f634238657..3ae732932f3 100644 --- a/lib/Targeting/VisitorInfoResolver.php +++ b/bundles/PersonalizationBundle/src/Targeting/VisitorInfoResolver.php @@ -15,19 +15,19 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; use Doctrine\DBAL\Connection; use Pimcore\Debug\Traits\StopwatchTrait; -use Pimcore\Event\Targeting\TargetingEvent; -use Pimcore\Event\Targeting\TargetingResolveVisitorInfoEvent; -use Pimcore\Event\Targeting\TargetingRuleEvent; -use Pimcore\Event\TargetingEvents; -use Pimcore\Model\Tool\Targeting\Rule; -use Pimcore\Targeting\ActionHandler\ActionHandlerInterface; -use Pimcore\Targeting\ActionHandler\DelegatingActionHandler; -use Pimcore\Targeting\Model\VisitorInfo; -use Pimcore\Targeting\Storage\TargetingStorageInterface; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingResolveVisitorInfoEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\Targeting\TargetingRuleEvent; +use Pimcore\Bundle\PersonalizationBundle\Event\TargetingEvents; +use Pimcore\Bundle\PersonalizationBundle\Model\Tool\Targeting\Rule; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\ActionHandlerInterface; +use Pimcore\Bundle\PersonalizationBundle\Targeting\ActionHandler\DelegatingActionHandler; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Storage\TargetingStorageInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; @@ -111,9 +111,11 @@ public function isTargetingConfigured(): bool return $this->targetingConfigured; } - $configuredRules = $this->db->fetchOne( - 'SELECT id FROM targeting_target_groups UNION SELECT id FROM targeting_rules LIMIT 1' - ); + try { + $configuredRules = $this->db->fetchOne('SELECT id FROM targeting_target_groups UNION SELECT id FROM targeting_rules LIMIT 1'); + } catch (\Exception $exception) { + return false; + } $this->targetingConfigured = $configuredRules && (int)$configuredRules > 0; diff --git a/lib/Targeting/VisitorInfoStorage.php b/bundles/PersonalizationBundle/src/Targeting/VisitorInfoStorage.php similarity index 87% rename from lib/Targeting/VisitorInfoStorage.php rename to bundles/PersonalizationBundle/src/Targeting/VisitorInfoStorage.php index 11fec04113a..6bc7255c6a9 100644 --- a/lib/Targeting/VisitorInfoStorage.php +++ b/bundles/PersonalizationBundle/src/Targeting/VisitorInfoStorage.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; class VisitorInfoStorage implements VisitorInfoStorageInterface { diff --git a/lib/Targeting/VisitorInfoStorageInterface.php b/bundles/PersonalizationBundle/src/Targeting/VisitorInfoStorageInterface.php similarity index 86% rename from lib/Targeting/VisitorInfoStorageInterface.php rename to bundles/PersonalizationBundle/src/Targeting/VisitorInfoStorageInterface.php index ac59e8cb5a6..388aebaed90 100644 --- a/lib/Targeting/VisitorInfoStorageInterface.php +++ b/bundles/PersonalizationBundle/src/Targeting/VisitorInfoStorageInterface.php @@ -15,9 +15,9 @@ * @license http://www.pimcore.org/license GPLv3 and PCL */ -namespace Pimcore\Targeting; +namespace Pimcore\Bundle\PersonalizationBundle\Targeting; -use Pimcore\Targeting\Model\VisitorInfo; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Model\VisitorInfo; /** * Similar to the TokenStorage for user objects, this contains the current diff --git a/bundles/CoreBundle/templates/Profiler/target.svg.twig b/bundles/PersonalizationBundle/templates/Profiler/target.svg.twig similarity index 100% rename from bundles/CoreBundle/templates/Profiler/target.svg.twig rename to bundles/PersonalizationBundle/templates/Profiler/target.svg.twig diff --git a/bundles/CoreBundle/templates/Profiler/targeting_data_collector.html.twig b/bundles/PersonalizationBundle/templates/Profiler/targeting_data_collector.html.twig similarity index 92% rename from bundles/CoreBundle/templates/Profiler/targeting_data_collector.html.twig rename to bundles/PersonalizationBundle/templates/Profiler/targeting_data_collector.html.twig index 8111d99dfe7..b30d0d2cedc 100644 --- a/bundles/CoreBundle/templates/Profiler/targeting_data_collector.html.twig +++ b/bundles/PersonalizationBundle/templates/Profiler/targeting_data_collector.html.twig @@ -3,7 +3,7 @@ {% block toolbar %} {% if collector.hasData %} {% set icon %} - {{ include("@PimcoreCore/Profiler/target.svg.twig") }} + {{ include("@PimcorePersonalization/Profiler/target.svg.twig") }} {% if collector.documentTargetGroup is not null %} {{ collector.documentTargetGroup.name }} @@ -51,7 +51,7 @@ {% block menu %} - {{ include("@PimcoreCore/Profiler/target.svg.twig") }} + {{ include("@PimcorePersonalization/Profiler/target.svg.twig") }} Targeting @@ -181,7 +181,7 @@

Visitor Info

- {{ include('@PimcoreCore/Profiler/key_value_table.html.twig', { data: collector.visitorInfo }, with_context = false) }} + {{ include('@PimcorePersonalization/Profiler/key_value_table.html.twig', { data: collector.visitorInfo }, with_context = false) }}
@@ -191,13 +191,13 @@

Session Storage

- {{ include('@PimcoreCore/Profiler/key_value_table.html.twig', { data: collector.storage.session }, with_context = false) }} + {{ include('@PimcorePersonalization/Profiler/key_value_table.html.twig', { data: collector.storage.session }, with_context = false) }}

Visitor Storage

- {{ include('@PimcoreCore/Profiler/key_value_table.html.twig', { data: collector.storage.visitor }, with_context = false) }} + {{ include('@PimcorePersonalization/Profiler/key_value_table.html.twig', { data: collector.storage.visitor }, with_context = false) }}
diff --git a/bundles/CoreBundle/templates/Targeting/targetingCode.html.twig b/bundles/PersonalizationBundle/templates/Targeting/targetingCode.html.twig similarity index 88% rename from bundles/CoreBundle/templates/Targeting/targetingCode.html.twig rename to bundles/PersonalizationBundle/templates/Targeting/targetingCode.html.twig index dd5fae17c36..1a18f7c0be4 100644 --- a/bundles/CoreBundle/templates/Targeting/targetingCode.html.twig +++ b/bundles/PersonalizationBundle/templates/Targeting/targetingCode.html.twig @@ -24,5 +24,5 @@ {% block afterScriptTag %}{{ blocks.afterScriptTag|raw }}{% endblock %} {% block targetingScript %} - + {% endblock %} diff --git a/bundles/CoreBundle/templates/Targeting/toolbar/icon/advanced_features.svg.twig b/bundles/PersonalizationBundle/templates/Targeting/toolbar/icon/advanced_features.svg.twig similarity index 100% rename from bundles/CoreBundle/templates/Targeting/toolbar/icon/advanced_features.svg.twig rename to bundles/PersonalizationBundle/templates/Targeting/toolbar/icon/advanced_features.svg.twig diff --git a/bundles/CoreBundle/templates/Targeting/toolbar/icon/close.svg.twig b/bundles/PersonalizationBundle/templates/Targeting/toolbar/icon/close.svg.twig similarity index 100% rename from bundles/CoreBundle/templates/Targeting/toolbar/icon/close.svg.twig rename to bundles/PersonalizationBundle/templates/Targeting/toolbar/icon/close.svg.twig diff --git a/bundles/CoreBundle/templates/Targeting/toolbar/icon/toolbar-collapse.svg.twig b/bundles/PersonalizationBundle/templates/Targeting/toolbar/icon/toolbar-collapse.svg.twig similarity index 100% rename from bundles/CoreBundle/templates/Targeting/toolbar/icon/toolbar-collapse.svg.twig rename to bundles/PersonalizationBundle/templates/Targeting/toolbar/icon/toolbar-collapse.svg.twig diff --git a/bundles/CoreBundle/templates/Targeting/toolbar/macros.html.twig b/bundles/PersonalizationBundle/templates/Targeting/toolbar/macros.html.twig similarity index 100% rename from bundles/CoreBundle/templates/Targeting/toolbar/macros.html.twig rename to bundles/PersonalizationBundle/templates/Targeting/toolbar/macros.html.twig diff --git a/bundles/CoreBundle/templates/Targeting/toolbar/toolbar.css b/bundles/PersonalizationBundle/templates/Targeting/toolbar/toolbar.css similarity index 100% rename from bundles/CoreBundle/templates/Targeting/toolbar/toolbar.css rename to bundles/PersonalizationBundle/templates/Targeting/toolbar/toolbar.css diff --git a/bundles/CoreBundle/templates/Targeting/toolbar/toolbar.html.twig b/bundles/PersonalizationBundle/templates/Targeting/toolbar/toolbar.html.twig similarity index 95% rename from bundles/CoreBundle/templates/Targeting/toolbar/toolbar.html.twig rename to bundles/PersonalizationBundle/templates/Targeting/toolbar/toolbar.html.twig index 9dc2579357e..c6add7611d5 100644 --- a/bundles/CoreBundle/templates/Targeting/toolbar/toolbar.html.twig +++ b/bundles/PersonalizationBundle/templates/Targeting/toolbar/toolbar.html.twig @@ -1,20 +1,20 @@ -{% import '@PimcoreCore/Targeting/toolbar/macros.html.twig' as toolbar %} +{% import '@PimcorePersonalization/Targeting/toolbar/macros.html.twig' as toolbar %} {% block toolbar %} {% apply spaceless %}
- {{ include('@PimcoreCore/Profiler/target.svg.twig') }} + {{ include('@PimcorePersonalization/Profiler/target.svg.twig') }} - {{ include('@PimcoreCore/Targeting/toolbar/icon/toolbar-collapse.svg.twig') }} + {{ include('@PimcorePersonalization/Targeting/toolbar/icon/toolbar-collapse.svg.twig') }}
- {{ include('@PimcoreCore/Targeting/toolbar/icon/close.svg.twig') }} + {{ include('@PimcorePersonalization/Targeting/toolbar/icon/close.svg.twig') }} - {{ include('@PimcoreCore/Targeting/toolbar/icon/advanced_features.svg.twig') }} + {{ include('@PimcorePersonalization/Targeting/toolbar/icon/advanced_features.svg.twig') }}
@@ -286,12 +286,12 @@ {%- apply spaceless -%} {%- endapply -%} {% endblock %} {% block js %} - {{ include('@PimcoreCore/Targeting/toolbar/toolbar_js.html.twig') }} + {{ include('@PimcorePersonalization/Targeting/toolbar/toolbar_js.html.twig') }} {% endblock %} diff --git a/bundles/CoreBundle/templates/Targeting/toolbar/toolbar.scss b/bundles/PersonalizationBundle/templates/Targeting/toolbar/toolbar.scss similarity index 100% rename from bundles/CoreBundle/templates/Targeting/toolbar/toolbar.scss rename to bundles/PersonalizationBundle/templates/Targeting/toolbar/toolbar.scss diff --git a/bundles/CoreBundle/templates/Targeting/toolbar/toolbar_js.html.twig b/bundles/PersonalizationBundle/templates/Targeting/toolbar/toolbar_js.html.twig similarity index 100% rename from bundles/CoreBundle/templates/Targeting/toolbar/toolbar_js.html.twig rename to bundles/PersonalizationBundle/templates/Targeting/toolbar/toolbar_js.html.twig diff --git a/bundles/PersonalizationBundle/tests/Readme.md b/bundles/PersonalizationBundle/tests/Readme.md new file mode 100644 index 00000000000..79861a42758 --- /dev/null +++ b/bundles/PersonalizationBundle/tests/Readme.md @@ -0,0 +1,8 @@ +# Running and creating tests + +Tests can be executed locally in a separate docker-compose. This docker-compose also setup database and elastic search +accordingly. + +To run, just execute [/bin/init-tests.sh](./bin/init-tests.sh) script and follow instructions there. + +Additional tests may be added following codeception best practises. \ No newline at end of file diff --git a/bundles/PersonalizationBundle/tests/Support/Data/.gitkeep b/bundles/PersonalizationBundle/tests/Support/Data/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/bundles/PersonalizationBundle/tests/Support/UnitTester.php b/bundles/PersonalizationBundle/tests/Support/UnitTester.php new file mode 100644 index 00000000000..91be028bcbd --- /dev/null +++ b/bundles/PersonalizationBundle/tests/Support/UnitTester.php @@ -0,0 +1,42 @@ +assertEquals($expected, $condition->match($visitorInfo)); + $this->assertEquals ($expected, $condition->match ($visitorInfo)); } /** @@ -75,55 +74,55 @@ public function testMatch(GeoPoint $condition, VisitorInfo $visitorInfo, bool $e */ public function testCannotMatchIfOptionsEmpty(GeoPoint $condition): void { - $this->assertFalse($condition->canMatch()); + $this->assertFalse ($condition->canMatch ()); } - public function matchProvider(): \Generator + public function matchProvider (): \Generator { yield [ - $this->createCondition('sbg', 110), - $this->createVisitorInfo('muc'), + $this->createCondition ('sbg', 110), + $this->createVisitorInfo ('muc'), false, ]; yield [ - $this->createCondition('sbg', 120), - $this->createVisitorInfo('muc'), + $this->createCondition ('sbg', 120), + $this->createVisitorInfo ('muc'), true, ]; yield [ - $this->createCondition('sbg', 500), - $this->createVisitorInfo('ber'), + $this->createCondition ('sbg', 500), + $this->createVisitorInfo ('ber'), false, ]; yield [ - $this->createCondition('sbg', 600), - $this->createVisitorInfo('ber'), + $this->createCondition ('sbg', 600), + $this->createVisitorInfo ('ber'), true, ]; yield [ - $this->createCondition('sbg', 100), - $this->createVisitorInfo('bkk'), + $this->createCondition ('sbg', 100), + $this->createVisitorInfo ('bkk'), false, ]; yield [ - $this->createCondition('sbg', 8000), - $this->createVisitorInfo('bkk'), + $this->createCondition ('sbg', 8000), + $this->createVisitorInfo ('bkk'), false, ]; yield [ - $this->createCondition('sbg', 9000), - $this->createVisitorInfo('bkk'), + $this->createCondition ('sbg', 9000), + $this->createVisitorInfo ('bkk'), true, ]; } - public function noMatchProvider(): \Generator + public function noMatchProvider (): \Generator { yield [new GeoPoint(1.2, 2.3, null)]; yield [new GeoPoint(1.2, null, 4)]; @@ -134,10 +133,10 @@ public function noMatchProvider(): \Generator yield [new GeoPoint(null, null, null)]; } - private function createCondition(string $point, int $radius): GeoPoint + private function createCondition (string $point, int $radius): GeoPoint { if (!isset($this->points[$point])) { - throw new \InvalidArgumentException(sprintf('Point "%s" is not defined', $point)); + throw new \InvalidArgumentException(sprintf ('Point "%s" is not defined', $point)); } return new GeoPoint( @@ -147,17 +146,17 @@ private function createCondition(string $point, int $radius): GeoPoint ); } - private function createVisitorInfo(string $point): VisitorInfo + private function createVisitorInfo (string $point): VisitorInfo { if (!isset($this->points[$point])) { - throw new \InvalidArgumentException(sprintf('Point "%s" is not defined', $point)); + throw new \InvalidArgumentException(sprintf ('Point "%s" is not defined', $point)); } $geoLocation = new GeoLocationModel($this->points[$point][0], $this->points[$point][1]); // create visitor info and set geolocation as GeoLocation provider key $visitorInfo = new VisitorInfo(new Request()); - $visitorInfo->set(GeoLocation::PROVIDER_KEY, $geoLocation); + $visitorInfo->set (GeoLocation::PROVIDER_KEY, $geoLocation); return $visitorInfo; } diff --git a/bundles/PersonalizationBundle/tests/_bootstrap.php b/bundles/PersonalizationBundle/tests/_bootstrap.php new file mode 100644 index 00000000000..73bf3e848f1 --- /dev/null +++ b/bundles/PersonalizationBundle/tests/_bootstrap.php @@ -0,0 +1,40 @@ +- + This condition fetches data synchronously from Piwik which can be quite slow. + Use with care! +targeting_condition_visited_page_before_piwik_not_configured_warning: >- + This condition cannot be matched as Piwik is not configured and will always + resolve to false. +targeting_condition_url_pattern: URL (RegExp) +targeting_toolbar_browser_note: >- + NOTE: Enabling the targeting toolbar affects only the browser you are + currently using. If you want to use the toolbar on another browser you need to + enable it again. See the + documentation for details. diff --git a/composer.json b/composer.json index 45db291ee03..3860ddf7825 100644 --- a/composer.json +++ b/composer.json @@ -194,7 +194,9 @@ "Pimcore\\Bundle\\StaticRoutesBundle\\": "bundles/StaticRoutesBundle/src/", "Pimcore\\Bundle\\WordExportBundle\\": "bundles/WordExportBundle/src/", "Pimcore\\Bundle\\FileExplorerBundle\\": "bundles/FileExplorerBundle/src/", - "Pimcore\\Bundle\\WebToPrintBundle\\": "bundles/WebToPrintBundle/src/" + "Pimcore\\Bundle\\WebToPrintBundle\\": "bundles/WebToPrintBundle/src/", + "Pimcore\\Bundle\\PersonalizationBundle\\": "bundles/PersonalizationBundle/src/", + "Pimcore\\Model\\DataObject\\": "bundles/PersonalizationBundle/src/Pimcore/Model/DataObject" }, "classmap": [ "lib/Pimcore.php" diff --git a/doc/Development_Documentation/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md b/doc/Development_Documentation/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md index ac74acfff9f..1ab4f53fadd 100644 --- a/doc/Development_Documentation/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md +++ b/doc/Development_Documentation/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md @@ -138,6 +138,8 @@ Please make sure to set your preferred storage location ***before*** migration. - [Application Logger] Application logger has been moved into `PimcoreApplicationLoggerBundle` - [Web2Print] has been moved into PimcoreWebToPrintBundle - Config `pimcore:documents:web_to_print` has been removed, please use `pimcore_web_to_print` in the PimcoreWebToPrintBundle instead. + - [Personalization and targeting] has been moved to `pimcore/personalization` package. + - Config `pimcore:targeting:` has been removed, please use `pimcore_personalization.targeting:` in the PimcoreStaticRoutesBundle instead. - [Codeception] Bumped `codeception/codeception` version to ^5.0. Now, Pimcore is using a new directory structure for tests (Codeception 5 directory structure). For details, please see [#13415](https://github.com/pimcore/pimcore/pull/13415) - [Session] - `AdminSessionHandler` requires session from request stack. diff --git a/lib/Document/Newsletter/AddressSourceAdapter/DefaultAdapter.php b/lib/Document/Newsletter/AddressSourceAdapter/DefaultAdapter.php index afc3a9d56a8..6729c1cf562 100644 --- a/lib/Document/Newsletter/AddressSourceAdapter/DefaultAdapter.php +++ b/lib/Document/Newsletter/AddressSourceAdapter/DefaultAdapter.php @@ -24,7 +24,7 @@ /** * @internal */ -final class DefaultAdapter implements AddressSourceAdapterInterface +class DefaultAdapter implements AddressSourceAdapterInterface { /** * @var string @@ -36,11 +36,6 @@ final class DefaultAdapter implements AddressSourceAdapterInterface */ protected mixed $condition = null; - /** - * @var int[] - */ - protected mixed $targetGroups = []; - protected int $elementsTotal; protected ?Listing $list = null; @@ -49,7 +44,6 @@ public function __construct(array $params) { $this->class = $params['class']; $this->condition = empty($params['condition']) ? $params['objectFilterSQL'] : $params['condition']; - $this->targetGroups = $params['target_groups'] ?? []; } protected function getListing(): ?Listing @@ -63,14 +57,6 @@ protected function getListing(): ?Listing $conditions[] = '(' . $this->condition . ')'; } - if ($this->targetGroups) { - $class = ClassDefinition::getByName($this->class); - - if ($class) { - $conditions = $this->addTargetGroupConditions($class, $conditions); - } - } - $this->list->setCondition(implode(' AND ', $conditions)); $this->list->setOrderKey('email'); $this->list->setOrder('ASC'); @@ -81,42 +67,6 @@ protected function getListing(): ?Listing return $this->list; } - /** - * Handle target group filters - * - * @param ClassDefinition $class - * @param array $conditions - * - * @return array - */ - protected function addTargetGroupConditions(ClassDefinition $class, array $conditions): array - { - if (!$class->getFieldDefinition('targetGroup')) { - return $conditions; - } - - $fieldDefinition = $class->getFieldDefinition('targetGroup'); - if ($fieldDefinition instanceof ClassDefinition\Data\TargetGroup) { - $targetGroups = []; - foreach ($this->targetGroups as $value) { - if (!empty($value)) { - $targetGroups[] = $this->list->quote($value); - } - } - - $conditions[] = 'targetGroup IN (' . implode(',', $targetGroups) . ')'; - } elseif ($fieldDefinition instanceof ClassDefinition\Data\TargetGroupMultiselect) { - $targetGroupsCondition = []; - foreach ($this->targetGroups as $value) { - $targetGroupsCondition[] = 'targetGroup LIKE ' . $this->list->quote('%,' . $value . ',%'); - } - - $conditions[] = '(' . implode(' OR ', $targetGroupsCondition) . ')'; - } - - return $conditions; - } - /** * {@inheritdoc} */ diff --git a/lib/Document/Renderer/DocumentRenderer.php b/lib/Document/Renderer/DocumentRenderer.php index 1968607c09b..e7890e72205 100644 --- a/lib/Document/Renderer/DocumentRenderer.php +++ b/lib/Document/Renderer/DocumentRenderer.php @@ -23,7 +23,6 @@ use Pimcore\Localization\LocaleService; use Pimcore\Model\Document; use Pimcore\Routing\Dynamic\DocumentRouteHandler; -use Pimcore\Targeting\Document\DocumentTargetingConfigurator; use Pimcore\Templating\Renderer\ActionRenderer; use Pimcore\Twig\Extension\Templating\Placeholder\ContainerService; use Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface; @@ -40,8 +39,6 @@ class DocumentRenderer implements DocumentRendererInterface private DocumentRouteHandler $documentRouteHandler; - private DocumentTargetingConfigurator $targetingConfigurator; - private EventDispatcherInterface $eventDispatcher; private LocaleService $localeService; @@ -51,7 +48,6 @@ public function __construct( ActionRenderer $actionRenderer, FragmentRendererInterface $fragmentRenderer, DocumentRouteHandler $documentRouteHandler, - DocumentTargetingConfigurator $targetingConfigurator, EventDispatcherInterface $eventDispatcher, LocaleService $localeService ) { @@ -59,7 +55,6 @@ public function __construct( $this->actionRenderer = $actionRenderer; $this->fragmentRenderer = $fragmentRenderer; $this->documentRouteHandler = $documentRouteHandler; - $this->targetingConfigurator = $targetingConfigurator; $this->eventDispatcher = $eventDispatcher; $this->localeService = $localeService; } @@ -83,9 +78,6 @@ public function render(Document\PageSnippet $document, array $attributes = [], a DocumentEvents::RENDERER_PRE_RENDER ); - // apply best matching target group (if any) - $this->targetingConfigurator->configureTargetGroup($document); - // add document route to request if no route is set // this is needed for logic relying on the current route (e.g. pimcoreUrl helper) if (!isset($attributes['_route'])) { diff --git a/lib/Event/DocumentEvents.php b/lib/Event/DocumentEvents.php index 7f3f3b6221e..9a33628d14f 100644 --- a/lib/Event/DocumentEvents.php +++ b/lib/Event/DocumentEvents.php @@ -243,4 +243,24 @@ final class DocumentEvents * @var string */ const NEWSLETTER_POST_SEND = 'pimcore.document.newsletter.post_send'; + + /** + * The INCLUDERENDERER_PRE_RENDER event is triggered before the IncludeRenderer renders an include + * + * @Event("Pimcore\Event\Model\DocumentEvent") + * + * @var string + */ + const INCLUDERENDERER_PRE_RENDER = 'pimcore.document.IncludeRenderer.pre_render'; + + /** + * Arguments: + * - element | \Pimcore\Mail | the pimcore mail instance + * - requestParams | contains the request parameters + * + * @Event("Symfony\Component\EventDispatcher\GenericEvent") + * + * @var string + */ + const EDITABLE_RENDERLET_PRE_RENDER = 'pimcore.document.editable.renderlet.pre_render'; } diff --git a/lib/Templating/Renderer/IncludeRenderer.php b/lib/Templating/Renderer/IncludeRenderer.php index da11b04c359..4929d6dbb35 100644 --- a/lib/Templating/Renderer/IncludeRenderer.php +++ b/lib/Templating/Renderer/IncludeRenderer.php @@ -17,30 +17,25 @@ namespace Pimcore\Templating\Renderer; use Pimcore\Cache; +use Pimcore\Event\DocumentEvents; +use Pimcore\Event\Model\DocumentEvent; use Pimcore\Model; use Pimcore\Model\Document\PageSnippet; -use Pimcore\Model\Document\Targeting\TargetingDocumentInterface; use Pimcore\Model\Element; -use Pimcore\Targeting\Document\DocumentTargetingConfigurator; use Pimcore\Tool\DeviceDetector; use Pimcore\Tool\DomCrawler; use Pimcore\Tool\Frontend; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; /** * @internal */ class IncludeRenderer { - protected ActionRenderer $actionRenderer; - - private DocumentTargetingConfigurator $targetingConfigurator; - public function __construct( - ActionRenderer $actionRenderer, - DocumentTargetingConfigurator $targetingConfigurator + protected ActionRenderer $actionRenderer, + protected EventDispatcherInterface $eventDispatcher, ) { - $this->actionRenderer = $actionRenderer; - $this->targetingConfigurator = $targetingConfigurator; } /** @@ -81,8 +76,10 @@ public function render(mixed $include, array $params = [], bool $editmode = fals } if ($include instanceof PageSnippet && $include->isPublished()) { - // apply best matching target group (if any) - $this->targetingConfigurator->configureTargetGroup($include); + $this->eventDispatcher->dispatch( + new DocumentEvent($include, $params), + DocumentEvents::INCLUDERENDERER_PRE_RENDER + ); } // check if output-cache is enabled, if so, we're also using the cache here @@ -103,7 +100,7 @@ public function render(mixed $include, array $params = [], bool $editmode = fals }); // TODO is this enough for cache or should we disable caching completely? - if ($include instanceof TargetingDocumentInterface && $include->getUseTargetGroup()) { + if (method_exists($include, 'getUseTargetGroup') && $include->getUseTargetGroup()) { $cacheParams['target_group'] = $include->getUseTargetGroup(); } diff --git a/models/Document/Editable.php b/models/Document/Editable.php index 648634110b9..cb666a2d91b 100644 --- a/models/Document/Editable.php +++ b/models/Document/Editable.php @@ -25,7 +25,7 @@ use Pimcore\Logger; use Pimcore\Model; use Pimcore\Model\Document; -use Pimcore\Model\Document\Targeting\TargetingDocumentInterface; +use Pimcore\Bundle\PersonalizationBundle\Model\Document\Targeting\TargetingDocumentInterface; use Pimcore\Tool\HtmlUtils; /** @@ -521,7 +521,7 @@ public static function buildEditableName(string $type, string $name, Document $d // targeting prefix if configured on the document. hasBlocks() determines if // there are any parent blocks for the current element $targetGroupEditableName = null; - if ($document && $document instanceof TargetingDocumentInterface) { + if ($document && class_exists (TargetingDocumentInterface::class) && $document instanceof TargetingDocumentInterface) { $targetGroupEditableName = $document->getTargetGroupEditableName($name); if (!$blockState->hasBlocks()) { @@ -637,7 +637,7 @@ public static function buildEditableRealName(string $name, Document $document): // if element not nested inside a hierarchical element (e.g. block), add the // targeting prefix if configured on the document. hasBlocks() determines if // there are any parent blocks for the current element - if ($document instanceof TargetingDocumentInterface && !$blockState->hasBlocks()) { + if (class_exists (TargetingDocumentInterface::class) && $document instanceof TargetingDocumentInterface && !$blockState->hasBlocks()) { $name = $document->getTargetGroupEditableName($name); } diff --git a/models/Document/Editable/Renderlet.php b/models/Document/Editable/Renderlet.php index 27ab12c201f..f1014ac391e 100644 --- a/models/Document/Editable/Renderlet.php +++ b/models/Document/Editable/Renderlet.php @@ -23,7 +23,8 @@ use Pimcore\Model\DataObject; use Pimcore\Model\Document; use Pimcore\Model\Element; -use Pimcore\Targeting\Document\DocumentTargetingConfigurator; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Document\DocumentTargetingConfigurator; +use Pimcore\Bundle\PersonalizationBundle\Model\Document\Targeting\TargetingDocumentInterface; /** * @method \Pimcore\Model\Document\Editable\Dao getDao() @@ -132,10 +133,13 @@ public function frontend() } } + //Personalization & Targeting Specific // apply best matching target group (if any) - if ($this->o instanceof Document\Targeting\TargetingDocumentInterface) { - $targetingConfigurator = $container->get(DocumentTargetingConfigurator::class); - $targetingConfigurator->configureTargetGroup($this->o); + // @phpstan-ignore-next-line + if ($container->has(DocumentTargetingConfigurator::class) + && $this->o instanceof TargetingDocumentInterface) { + $targetingConfigurator = $container->get(DocumentTargetingConfigurator::class); + $targetingConfigurator->configureTargetGroup($this->o); } $blockparams = ['controller', 'template']; diff --git a/models/Document/Editable/Snippet.php b/models/Document/Editable/Snippet.php index 9164540f059..cc787e38d3d 100644 --- a/models/Document/Editable/Snippet.php +++ b/models/Document/Editable/Snippet.php @@ -21,7 +21,7 @@ use Pimcore\Model; use Pimcore\Model\Document; use Pimcore\Model\Site; -use Pimcore\Targeting\Document\DocumentTargetingConfigurator; +use Pimcore\Bundle\PersonalizationBundle\Targeting\Document\DocumentTargetingConfigurator; use Pimcore\Tool\DeviceDetector; /** @@ -29,6 +29,7 @@ */ class Snippet extends Model\Document\Editable implements IdRewriterInterface, EditmodeDataInterface, LazyLoadingInterface { + /** * Contains the ID of the linked snippet * @@ -93,7 +94,7 @@ public function frontend() $container = \Pimcore::getContainer(); $editableHandler = $container->get(EditableHandler::class); - $targetingConfigurator = $container->get(DocumentTargetingConfigurator::class); + if (!$this->snippet instanceof Document\Snippet) { return ''; @@ -103,8 +104,13 @@ public function frontend() return ''; } - // apply best matching target group (if any) - $targetingConfigurator->configureTargetGroup($this->snippet); + //Personalization & Targeting Specific + // @phpstan-ignore-next-line + if ($container->has(DocumentTargetingConfigurator::class)) { + $targetingConfigurator = $container->get(DocumentTargetingConfigurator::class); + // apply best matching target group (if any) + $targetingConfigurator->configureTargetGroup($this->snippet); + } $params = $this->config; $params['document'] = $this->snippet; @@ -122,7 +128,7 @@ public function frontend() }); // TODO is this enough for cache or should we disable caching completely? - if ($this->snippet->getUseTargetGroup()) { + if (method_exists($this->snippet, 'getUseTargetGroup') && $this->snippet->getUseTargetGroup()) { $cacheParams['target_group'] = $this->snippet->getUseTargetGroup(); } diff --git a/models/Document/Page.php b/models/Document/Page.php index 4d6fac35fe7..0157047bfa7 100644 --- a/models/Document/Page.php +++ b/models/Document/Page.php @@ -18,12 +18,11 @@ use Pimcore\Messenger\GeneratePagePreviewMessage; use Pimcore\Model\Redirect; -use Pimcore\Model\Tool\Targeting\TargetGroup; /** * @method \Pimcore\Model\Document\Page\Dao getDao() */ -class Page extends TargetingDocument +class Page extends PageSnippet { /** * Contains the title of the page (meta-title) @@ -62,15 +61,6 @@ class Page extends TargetingDocument */ protected ?string $prettyUrl = null; - /** - * Comma separated IDs of target groups - * - * @internal - * - * @var string - */ - protected string $targetGroupIds = ''; - /** * {@inheritdoc} */ @@ -159,82 +149,6 @@ public function getPrettyUrl(): ?string return $this->prettyUrl; } - /** - * Set linked Target Groups as set in properties panel as list of IDs - * - * @param array|string $targetGroupIds - */ - public function setTargetGroupIds(array|string $targetGroupIds): void - { - if (is_array($targetGroupIds)) { - $targetGroupIds = implode(',', $targetGroupIds); - } - - $targetGroupIds = trim($targetGroupIds, ' ,'); - - if (!empty($targetGroupIds)) { - $targetGroupIds = ',' . $targetGroupIds . ','; - } - - $this->targetGroupIds = $targetGroupIds; - } - - /** - * Get serialized list of Target Group IDs - * - * @return string - */ - public function getTargetGroupIds(): string - { - return $this->targetGroupIds; - } - - /** - * Set assigned target groups - * - * @param TargetGroup[]|int[] $targetGroups - */ - public function setTargetGroups(array $targetGroups): void - { - $ids = array_map(function ($targetGroup) { - if (is_numeric($targetGroup)) { - return (int)$targetGroup; - } elseif ($targetGroup instanceof TargetGroup) { - return $targetGroup->getId(); - } - }, $targetGroups); - - $ids = array_filter($ids, function ($id) { - return null !== $id && $id > 0; - }); - - $this->setTargetGroupIds($ids); - } - - /** - * Return list of assigned target groups (via properties panel) - * - * @return TargetGroup[] - */ - public function getTargetGroups(): array - { - $ids = explode(',', $this->targetGroupIds); - - $targetGroups = array_map(function ($id) { - $id = trim($id); - if (!empty($id)) { - $targetGroup = TargetGroup::getById((int) $id); - if ($targetGroup) { - return $targetGroup; - } - } - }, $ids); - - $targetGroups = array_filter($targetGroups); - - return $targetGroups; - } - public function getPreviewImageFilesystemPath(): string { return PIMCORE_SYSTEM_TEMP_DIRECTORY . '/document-page-previews/document-page-screenshot-' . $this->getId() . '@2x.jpg'; diff --git a/models/Document/Page/Dao.php b/models/Document/Page/Dao.php index baa55882063..622dbeaed27 100644 --- a/models/Document/Page/Dao.php +++ b/models/Document/Page/Dao.php @@ -16,17 +16,14 @@ namespace Pimcore\Model\Document\Page; use Pimcore\Model; -use Pimcore\Model\Document\Targeting\TargetingDocumentDaoInterface; /** * @internal * * @property \Pimcore\Model\Document\Page $model */ -class Dao extends Model\Document\PageSnippet\Dao implements TargetingDocumentDaoInterface +class Dao extends Model\Document\PageSnippet\Dao { - use Model\Document\Targeting\TargetingDocumentDaoTrait; - /** * Get the data for the object by the given id, or by the id which is set in the object * diff --git a/models/Document/Snippet.php b/models/Document/Snippet.php index ee52eb2026e..aba5b08fe58 100644 --- a/models/Document/Snippet.php +++ b/models/Document/Snippet.php @@ -19,7 +19,7 @@ /** * @method \Pimcore\Model\Document\Snippet\Dao getDao() */ -class Snippet extends TargetingDocument +class Snippet extends \Pimcore\Model\Document\PageSnippet { /** * {@inheritdoc} diff --git a/models/Document/Snippet/Dao.php b/models/Document/Snippet/Dao.php index da047a38859..d80c3aa7955 100644 --- a/models/Document/Snippet/Dao.php +++ b/models/Document/Snippet/Dao.php @@ -16,16 +16,14 @@ namespace Pimcore\Model\Document\Snippet; use Pimcore\Model; -use Pimcore\Model\Document\Targeting\TargetingDocumentDaoInterface; /** * @internal * * @property \Pimcore\Model\Document\Snippet $model */ -class Dao extends Model\Document\PageSnippet\Dao implements TargetingDocumentDaoInterface +class Dao extends Model\Document\PageSnippet\Dao { - use Model\Document\Targeting\TargetingDocumentDaoTrait; /** * Get the data for the object by the given id, or by the id which is set in the object diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index c88cae0661a..540ef95ff33 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2,7 +2,7 @@ parameters: ignoreErrors: - message: "#^Negated boolean expression is always false\\.$#" - count: 3 + count: 2 path: bundles/CoreBundle/src/DependencyInjection/PimcoreCoreExtension.php - @@ -91,14 +91,14 @@ parameters: path: lib/Mail.php - - message: "#^Parameter \\#2 \\$eventDispatcher of method Pimcore\\\\Targeting\\\\Condition\\\\EventDispatchingConditionInterface\\:\\:postMatch\\(\\) expects Symfony\\\\Component\\\\EventDispatcher\\\\EventDispatcherInterface, Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface given\\.$#" + message: "#^Parameter \\#2 \\$eventDispatcher of method Pimcore\\\\Bundle\\\\PersonalizationBundle\\\\Targeting\\\\Condition\\\\EventDispatchingConditionInterface\\:\\:postMatch\\(\\) expects Symfony\\\\Component\\\\EventDispatcher\\\\EventDispatcherInterface, Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface given\\.$#" count: 1 - path: lib/Targeting/ConditionMatcher.php + path: bundles/PersonalizationBundle/src/Targeting/ConditionMatcher.php - - message: "#^Parameter \\#2 \\$eventDispatcher of method Pimcore\\\\Targeting\\\\Condition\\\\EventDispatchingConditionInterface\\:\\:preMatch\\(\\) expects Symfony\\\\Component\\\\EventDispatcher\\\\EventDispatcherInterface, Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface given\\.$#" + message: "#^Parameter \\#2 \\$eventDispatcher of method Pimcore\\\\Bundle\\\\PersonalizationBundle\\\\Targeting\\\\Condition\\\\EventDispatchingConditionInterface\\:\\:preMatch\\(\\) expects Symfony\\\\Component\\\\EventDispatcher\\\\EventDispatcherInterface, Symfony\\\\Contracts\\\\EventDispatcher\\\\EventDispatcherInterface given\\.$#" count: 1 - path: lib/Targeting/ConditionMatcher.php + path: bundles/PersonalizationBundle/src/Targeting/ConditionMatcher.php - message: "#^Call to an undefined method COM\\:\\:Run\\(\\)\\.$#" diff --git a/phpstan-parameters.neon b/phpstan-parameters.neon index 48c65a8f703..8035c3f6cdd 100644 --- a/phpstan-parameters.neon +++ b/phpstan-parameters.neon @@ -16,6 +16,8 @@ parameters: - '**/Processor/PdfReactor.php' - '**/PDFreactor.class.php' - 'bundles/EcommerceFrameworkBundle/*' + - 'bundles/PersonalizationBundle/src/Targeting/DataProvider/GeoIp.php' + - 'bundles/PersonalizationBundle/tests/Support/UnitTester.php' ignoreErrors: - '~^Unsafe usage of new static\(\)~'