Install the Spryker Core Back Office feature
Edit on GitHubThis feature integration guide expects the basic feature to be in place. The current feature integration guide adds the following functionalities:
- Translation
- Security
- OAuth 2.0/Open ID Connect Support for Zed login
Prerequisites
Ensure that the related features are installed:
NAME | VERSION |
---|---|
Spryker Core | 202212.0 |
1) Install the required modules using Composer
Install the required modules:
composer require spryker-feature/spryker-core-back-office:"202212.0" --update-with-dependencies
Make sure the following modules have been installed:
MODULE | EXPECTED DIRECTORY |
---|---|
Translator | vendor/spryker/translator |
UserLocale | vendor/spryker/user-locale |
UserLocaleGui | vendor/spryker/user-locale-gui |
MessengerExtension | vendor/spryker/messenger-extension |
SecurityGui | vendor/spryker/security-gui |
UserPasswordReset | vendor/spryker/user-password-reset |
UserPasswordResetExtension | vendor/spryker/user-password-reset-extension |
UserPasswordResetMail | vendor/spryker/user-password-reset-mail |
SecurityOauthUser | vendor/sprkyer/security-oauth-user |
Ensure that the following modules have been removed:
MODULE | EXPECTED DIRECTORY |
---|---|
Auth | vendor/spryker/auth |
AuthMailConnector | vendor/spryker/auth-mail-connector |
AuthMailConnectorExtension | vendor/spryker/auth-mail-connector-extension |
If these modules have not been removed, remove them:
composer remove spryker/auth spryker/auth-mail-connector spryker/auth-mail-connector-extension
2) Set up transfer objects
Generate transfers:
console transfer:generate
Ensure the following transfers have been created:
TRANSFER | TYPE | EVENT | PATH |
---|---|---|---|
UserTransfer.fkLocale | attribute | created | src/Generated/Shared/Transfer/UserTransfer` |
UserTransfer.localName | attribute | created | src/Generated/Shared/Transfer/UserTransfer` |
UserTransfer.username | attribute | created | src/Generated/Shared/Transfer/UserTransfer` |
UserTransfer.password | attribute | created | src/Generated/Shared/Transfer/UserTransfer` |
UserTransfer.lastLogin | attribute | created | src/Generated/Shared/Transfer/UserTransfer` |
MessageTransfer | class | created | src/Generated/Shared/Transfer/MessageTransfer` |
TranslationTransfer | class | created | src/Generated/Shared/Transfer/TranslationTransfer` |
KeyTranslationTransfer | class | created | src/Generated/Shared/Transfer/KeyTranslationTransfer` |
OauthAuthenticationLinkTransfer | class | created | src/Generated/Shared/Transfer/OauthAuthenticationLinkTransfer |
ResourceOwnerTransfer | class | created | src/Generated/Shared/Transfer/ResourceOwnerTransfer` |
ResourceOwnerRequestTransfer | class | created | src/Generated/Shared/Transfer/ResourceOwnerRequestTransfer |
ResourceOwnerResponseTransfer | class | created | src/Generated/Shared/Transfer/ResourceOwnerResponseTransfer |
3) Set up the configuration
Add the following configuration to your project:
CONFIGURATION | SPECIFICATION | NAMESPACE |
---|---|---|
TranslatorConstants::TRANSLATION_ZED_FALLBACK_LOCALES | Fallback locales that are used if there is no translation for a selected locale. | Spryker\Shared\Translator |
TranslatorConstants::TRANSLATION_ZED_CACHE_DIRECTORY | Absolute path to a translation cache directory. For example, /var/www/data/DE/cache/Zed/translation . |
Spryker\Shared\Translator |
TranslatorConstants::TRANSLATION_ZED_FILE_PATH_PATTERNS | Paths to project level translations. You can use a global pattern that specifies sets of filenames with wildcard characters. | Spryker\Shared\Translator |
AclConstants::ACL_DEFAULT_RULES | Default rules for ACL functionality, where you can open access to some modules or controller out of the box. | Spryker\Shared\Acl |
config/Shared/config_default.php
use Spryker\Shared\Translator\TranslatorConstants;
// ----------- Translator
$config[TranslatorConstants::TRANSLATION_ZED_FALLBACK_LOCALES] = [
'de_DE' => ['en_US'],
];
$config[TranslatorConstants::TRANSLATION_ZED_CACHE_DIRECTORY] = sprintf(
'%s/data/%s/cache/Zed/translation',
APPLICATION_ROOT_DIR,
$CURRENT_STORE
);
$config[TranslatorConstants::TRANSLATION_ZED_FILE_PATH_PATTERNS] = [
APPLICATION_ROOT_DIR . '/data/translation/Zed/*/[a-z][a-z]_[A-Z][A-Z].csv',
];
// >> BACKOFFICE
// ACL: Allow or disallow of URLs for Zed GUI for ALL users
$config[AclConstants::ACL_DEFAULT_RULES] = [
[
'bundle' => 'security-gui',
'controller' => '*',
'action' => '*',
'type' => 'allow',
],
[
'bundle' => 'acl',
'controller' => 'index',
'action' => 'denied',
'type' => 'allow',
],
];
Set up an authentication strategy
Spryker offers two authentication strategies out of the box:
\Spryker\Zed\SecurityOauthUser\SecurityOauthUserConfig::AUTHENTICATION_STRATEGY_CREATE_USER_ON_FIRST_LOGIN
—if a user does not exist, it is created automatically based on the data from an external service.\Spryker\Zed\SecurityOauthUser\SecurityOauthUserConfig::AUTHENTICATION_STRATEGY_ACCEPT_ONLY_EXISTING_USERS
—it accepts only existing users for authentication.
src/Pyz/Zed/SecurityOauthUser/SecurityOauthUserConfig.php
<?php
namespace Pyz\Zed\SecurityOauthUser;
use Spryker\Zed\SecurityOauthUser\SecurityOauthUserConfig as SprykerSecurityOauthUserConfig;
class SecurityOauthUserConfig extends SprykerSecurityOauthUserConfig
{
/**
* Specification:
* - Defines by which strategy Oauth user authentication should be.
*
* @api
*
* @return string
*/
public function getAuthenticationStrategy(): string
{
return static::AUTHENTICATION_STRATEGY_CREATE_USER_ON_FIRST_LOGIN;
}
}
After finishing the entire integration, ensure the following:
- Entries without a translation for a language with a configured fallback are translated into the fallback language.
- Translation cache is stored under the configured directory.
- Translations are found based on the configured file path pattern.
Configure navigation
Add the StrageGui
section to navigation.xml
:
config/Zed/navigation.xml
<?xml version="1.0"?>
<config>
<maintenance>
<label>Maintenance</label>
<title>Maintenance</title>
<icon>fa-wrench</icon>
<pages>
<storage-gui>
<label>Storage</label>
<title>Storage index</title>
<bundle>storage-gui</bundle>
<controller>maintenance</controller>
<action>index</action>
</storage-gui>
</pages>
</maintenance>
</config>
Execute the following command:
console navigation:build-cache
Make sure that in the Back Office, you can select Maintenance > Storage.
4) Set up behavior
Set up the following behaviors.
Set up admin user login to the Back Office
Set up admin user login to the Back Office:
- Activate the following security plugins:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
SecurityApplicationPlugin | Extends the Zed global container with the services required for the Security functionality. | If there is WebProfilerApplicationPlugin in ApplicationDependencyProvider , put SecurityApplicationPlugin before it. |
Spryker\Zed\Security\Communication\Plugin\Application |
UserSessionHandlerSecurityPlugin | Sets an authenticated user to the session. | None | Spryker\Zed\User\Communication\Plugin\Securiy |
UserSecurityPlugin | Sets security firewalls, such as rules and handlers, for the Back Office users. | None | Spryker\Zed\SecurityGui\Communication\Plugin\Security |
UserPasswordResetMailTypePlugin | Adds a new email type, which is used by MailUserPasswordResetRequestHandlerPlugin . |
None | Spryker\Zed\UserPasswordResetMail\Communication\Plugin\Mail |
MailUserPasswordResetRequestHandlerPlugin | Sends a password reset email on a user request. | Mail module must be configured. UserPasswordResetMailTypePlugin is enabled. |
Spryker\Zed\UserPasswordResetMail\Communication\Plugin\UserPasswordReset |
OauthUserSecurityPlugin | Sets security firewalls, such as rules and handlers, for Oauth users. | None | \Spryker\Zed\SecurityOauthUser\Communication\Plugin\Security |
src/Pyz/Zed/Application/ApplicationDependencyProvider.php
<?php
namespace Pyz\Zed\Application;
use Spryker\Zed\Application\ApplicationDependencyProvider as SprykerApplicationDependencyProvider;
use Spryker\Zed\Security\Communication\Plugin\Application\SecurityApplicationPlugin;
class ApplicationDependencyProvider extends SprykerApplicationDependencyProvider
{
/**
* @return \Spryker\Shared\ApplicationExtension\Dependency\Plugin\ApplicationPluginInterface[]
*/
protected function getApplicationPlugins(): array
{
return [
new SecurityApplicationPlugin(),
// web profiler plugin should be after security plugin.
new WebProfilerApplicationPlugin(),
];
}
}
src/Pyz/Zed/Security/SecurityDependencyProvider.php
<?php
namespace Pyz\Zed\Security;
use Spryker\Zed\Security\SecurityDependencyProvider as SprykerSecurityDependencyProvider;
use Spryker\Zed\SecurityOauthUser\Communication\Plugin\Security\OauthUserSecurityPlugin;
class SecurityDependencyProvider extends SprykerSecurityDependencyProvider
{
/**
* @return \Spryker\Shared\SecurityExtension\Dependency\Plugin\SecurityPluginInterface[]
*/
protected function getSecurityPlugins(): array
{
return [
new UserSessionHandlerSecurityPlugin(),
new UserSecurityPlugin(),
new OauthUserSecurityPlugin(),
];
}
}
Ensure that https://mysprykershop.com/security-oauth-user/login
redirects you to the login page with the Authentication failed! message displayed.
src/Pyz/Zed/UserPasswordReset/UserPasswordResetDependencyProvider.php
<?php
namespace Pyz\Zed\UserPasswordReset;
use Spryker\Zed\UserPasswordReset\UserPasswordResetDependencyProvider as SprykerUserPasswordResetDependencyProvider;
use Spryker\Zed\UserPasswordResetMail\Communication\Plugin\UserPasswordReset\MailUserPasswordResetRequestHandlerPlugin;
class UserPasswordResetDependencyProvider extends SprykerUserPasswordResetDependencyProvider
{
/**
* @return \Spryker\Zed\UserPasswordResetExtension\Dependency\Plugin\UserPasswordResetRequestHandlerPluginInterface[]
*/
public function getUserPasswordResetRequestHandlerPlugins(): array
{
return [
new MailUserPasswordResetRequestHandlerPlugin(),
];
}
}
src/Pyz/Zed/Mail/MailDependencyProvider.php
<?php
use Spryker\Zed\Mail\MailDependencyProvider as SprykerMailDependencyProvider;
use Spryker\Zed\UserPasswordResetMail\Communication\Plugin\Mail\UserPasswordResetMailTypePlugin;
class MailDependencyProvider extends SprykerMailDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Spryker\Zed\Kernel\Container
*/
public function provideBusinessLayerDependencies(Container $container)
{
$container = parent::provideBusinessLayerDependencies($container);
$container->extend(static::MAIL_TYPE_COLLECTION, function (MailTypeCollectionAddInterface $mailCollection) {
$mailCollection
->add(new UserPasswordResetMailTypePlugin());
return $mailCollection;
});
return $container;
}
}
- Rebuild Zed router and Twig caches:
console router:cache:warm-up
console twig:cache:warmer
console twig:cache:warmer
Ensure the following:
- You can open the Back Office login page or any page which requires authentication.
- On the Back Office login page, the Forgot password? button redirects you to the password reset form.
- You receive a password reset email to the email address you submitted the password reset form with.
Set up translation across the Back Office
- Activate the following plugins for translation:
PLUGIN | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
TranslatorInstallerPlugin | Regenerates new translation caches for all locales of the current store. | None | Spryker\Zed\Translator\Communication\Plugin |
TranslationPlugin | Translates flash messages provided by the Messenger module. | None | Spryker\Zed\Translator\Communication\Plugin\Messenger |
TranslatorTwigPlugin | Extends Twig with Symfony’s translation extension and Spryker’s translator logic. | None | Spryker\Zed\Translator\Communication\Plugin\Twig |
UserLocaleLocalePlugin | Provides locale of the logged-in user as current locale. | Enable \Spryker\Zed\Locale\Communication\Plugin\Application\LocaleApplicationPlugin that sets the locale of the application based on the provided locale plugin. |
Spryker\Zed\UserLocale\Communication\Plugin\Locale |
AssignUserLocalePreSavePlugin | Expands UserTransfer before saving it with a locale ID and name. |
None | Spryker\Zed\UserLocale\Communication\Plugin\User |
UserLocaleTransferExpanderPlugin | Expands UserTransfer with a locale ID and name after reading it from the database. |
None | Spryker\Zed\UserLocale\Communication\Plugin\User |
UserLocaleFormExpanderPlugin | Expands the Edit user profile form with a locale field. | None | Spryker\Zed\UserLocaleGui\Communication\Plugin |
src/Pyz/Zed/Installer/InstallerDependencyProvider.php
<?php
namespace Pyz\Zed\Installer;
use Spryker\Zed\Installer\InstallerDependencyProvider as SprykerInstallerDependencyProvider;
use Spryker\Zed\Translator\Communication\Plugin\TranslatorInstallerPlugin;
class InstallerDependencyProvider extends SprykerInstallerDependencyProvider
{
/**
* @return \Spryker\Zed\Installer\Dependency\Plugin\InstallerPluginInterface[]
*/
public function getInstallerPlugins()
{
return [
new TranslatorInstallerPlugin(),
];
}
}
- Execute the registered installer plugins and install infrastructural data:
console setup:init-db
Ensure that the command has done the following:
- Cleaned the previous translation cache in the translation folder, which is
data/{YourStore}/cache/Zed/translation
by default. - Generated translation cache files like
catalogue.{your_locale}.{randomString}.php
andcatalogue.{your_locale}.{randomString}.php.meta
in the translation folder, which isdata/{YourStore}/cache/Zed/translation
by default.
src/Pyz/Zed/Messenger/MessengerDependencyProvider.php
<?php
namespace Pyz\Zed\Messenger;
use Spryker\Zed\Messenger\MessengerDependencyProvider as SprykerMessengerDependencyProvider;
use Spryker\Zed\Translator\Communication\Plugin\Messenger\TranslationPlugin;
class MessengerDependencyProvider extends SprykerMessengerDependencyProvider
{
/**
* @return \Spryker\Zed\MessengerExtension\Dependency\Plugin\TranslationPluginInterface[]
*/
protected function getTranslationPlugins(): array
{
return [
/**
* TranslationPlugin needs to be after other translator plugins.
*/
new TranslationPlugin(),
];
}
}
src/Pyz/Zed/Twig/TwigDependencyProvider.php
<?php
namespace Pyz\Zed\Twig;
use Spryker\Zed\Translator\Communication\Plugin\Twig\TranslatorTwigPlugin;
use Spryker\Zed\Twig\TwigDependencyProvider as SprykerTwigDependencyProvider;
class TwigDependencyProvider extends SprykerTwigDependencyProvider
{
/**
* @return \Spryker\Shared\TwigExtension\Dependency\Plugin\TwigPluginInterface[]
*/
protected function getTwigPlugins(): array
{
return [
new TranslatorTwigPlugin(),
];
}
}
Ensure that the trans
and transChoice
Twig filters are working and using translations from the configured translation files.
src/Pyz/Zed/Locale/LocaleDependencyProvider.php
<?php
namespace Pyz\Zed\Locale;
use Spryker\Shared\LocaleExtension\Dependency\Plugin\LocalePluginInterface;
use Spryker\Zed\Locale\LocaleDependencyProvider as SprykerLocaleDependencyProvider;
use Spryker\Zed\UserLocale\Communication\Plugin\Locale\UserLocaleLocalePlugin;
class LocaleDependencyProvider extends SprykerLocaleDependencyProvider
{
/**
* @return \Spryker\Shared\LocaleExtension\Dependency\Plugin\LocalePluginInterface
*/
protected function getLocalePlugin(): LocalePluginInterface
{
return new UserLocaleLocalePlugin();
}
}
Ensure that the locale of the Back Office matches the locale of a logged-in user.
src/Pyz/Zed/User/UserDependencyProvider.php
<?php
namespace Pyz\Zed\User;
use Spryker\Zed\User\UserDependencyProvider as SprykerUserDependencyProvider;
use Spryker\Zed\UserLocale\Communication\Plugin\User\AssignUserLocalePreSavePlugin;
use Spryker\Zed\UserLocale\Communication\Plugin\User\UserLocaleTransferExpanderPlugin;
use Spryker\Zed\UserLocaleGui\Communication\Plugin\UserLocaleFormExpanderPlugin;
class UserDependencyProvider extends SprykerUserDependencyProvider
{
/**
* @return \Spryker\Zed\UserExtension\Dependency\Plugin\UserFormExpanderPluginInterface[]
*/
protected function getUserFormExpanderPlugins(): array
{
return [
new UserLocaleFormExpanderPlugin(),
];
}
/**
* @return \Spryker\Zed\UserExtension\Dependency\Plugin\UserPreSavePluginInterface[]
*/
protected function getUserPreSavePlugins(): array
{
return [
new AssignUserLocalePreSavePlugin(),
];
}
/**
* @return \Spryker\Zed\UserExtension\Dependency\Plugin\UserTransferExpanderPluginInterface[]
*/
protected function getUserTransferExpanderPlugins(): array
{
return [
new UserLocaleTransferExpanderPlugin(),
];
}
}
Ensure that you’ve enabled the plugins:
- In the Back Office, select Users > Users.
- Select Add New User.
- On the Create new User page, check that the Interface language* field exists.
Set up console commands for cache
Set up the following console commands:
COMMAND | SPECIFICATION | PREREQUISITES | NAMESPACE |
---|---|---|---|
CleanTranslationCacheConsole | Cleans translation cache for Zed. | None | Spryker\Zed\Translator\Communication\Console |
GenerateTranslationCacheConsole | Generates translation cache for Zed. | None | Spryker\Zed\Translator\Communication\Console |
src/Pyz/Zed/Console/ConsoleDependencyProvider.php
<?php
namespace Pyz\Zed\Console;
use Spryker\Zed\Kernel\Container;
use Spryker\Zed\Console\ConsoleDependencyProvider as SprykerConsoleDependencyProvider;
use Spryker\Zed\Translator\Communication\Console\CleanTranslationCacheConsole;
use Spryker\Zed\Translator\Communication\Console\GenerateTranslationCacheConsole;
class ConsoleDependencyProvider extends SprykerConsoleDependencyProvider
{
/**
* @param \Spryker\Zed\Kernel\Container $container
*
* @return \Symfony\Component\Console\Command\Command[]
*/
protected function getConsoleCommands(Container $container)
{
$commands = [
new CleanTranslationCacheConsole(),
new GenerateTranslationCacheConsole(),
];
return $commands;
}
}
Regenerate translation cache:
console translator:clean-cache
console translator:generate-cache
Ensure that the command has done the following:
- Cleaned the previous translation cache in the translation folder, which is
data/{YourStore}/cache/Zed/translation
by default. - Generated translator cache files like
catalogue.{your_locale}.{randomString}.php
andcatalogue.{your_locale}.{randomString}.php.meta
in the translation folder, which isdata/{YourStore}/cache/Zed/translation
by default.
Thank you!
For submitting the form