Skip to content
This repository has been archived by the owner on Jul 22, 2022. It is now read-only.

Add profile to CustomerBundle #634

Merged
merged 1 commit into from
Jan 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions UPGRADE-3.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ UPGRADE 3.x
UPGRADE FROM 3.0 to 3.1
=======================

## Added missing profile part to CustomerBundle

Profile dependencies are no longer fetched from SonataUserBundle, but you can
use this profile by changing the configuration (`template` and `menu_builder`).


## Deprecated not passing dependencies to `Sonata\PaymentBundle\Controller\PaymentController`

Dependencies are no longer fetched from the container, so if you manually
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"knplabs/knp-paginator-bundle": "^2.6",
"kriswallsmith/buzz": "^0.15 || 0.16.0",
"sonata-project/admin-bundle": "^3.29",
"sonata-project/block-bundle": "^3.8",
"sonata-project/block-bundle": "^3.18.3",
"sonata-project/classification-bundle": "^3.3",
"sonata-project/comment-bundle": "^3.1",
"sonata-project/core-bundle": "^3.15.1",
Expand Down
35 changes: 35 additions & 0 deletions docs/reference/bundles/customer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,41 @@ The bundle allows you to configure the entity classes; you'll also need to regis
.. code-block:: yaml

sonata_customer:
profile:
template: 'SonataCustomerBundle:Profile:action.html.twig' # or 'SonataCustomerBundle:Profile:action_with_user_menu.html.twig'
menu_builder: 'sonata.customer.profile.menu_builder.default'

menu:
-
route: 'sonata_customer_dashboard'
label: 'link_list_dashboard'
domain: 'SonataCustomerBundle'
route_parameters: {}
-
route: 'sonata_customer_addresses'
label: 'link_list_addresses'
domain: 'SonataCustomerBundle'
route_parameters: {}
-
route: 'sonata_order_index'
label: 'order_list'
domain: 'SonataOrderBundle'
route_parameters: {}

blocks:
-
position: left
type: sonata.order.block.recent_orders
settings: { title: Recent Orders, number: 5, mode: public }
-
position: right
type: sonata.news.block.recent_posts
settings: { title: Recent Posts, number: 5, mode: public }
-
position: right
type: sonata.news.block.recent_comments
settings: { title: Recent Comments, number: 5, mode: public }

class:
customer: App\Sonata\CustomerBundle\Entity\Customer
address: App\Sonata\CustomerBundle\Entity\Address
Expand Down
82 changes: 82 additions & 0 deletions src/CustomerBundle/Block/ProfileMenuBlockService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\CustomerBundle\Block;

use Knp\Menu\ItemInterface;
use Knp\Menu\Provider\MenuProviderInterface;
use Sonata\BlockBundle\Block\BlockContextInterface;
use Sonata\BlockBundle\Block\Service\MenuBlockService;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
* @author Hugo Briand <briand@ekino.com>
*/
final class ProfileMenuBlockService extends MenuBlockService
{
private $menuBuilder;

/**
* @param object $menuBuilder
*/
public function __construct(string $name, EngineInterface $templating, MenuProviderInterface $menuProvider, $menuBuilder)
{
parent::__construct($name, $templating, $menuProvider, []);

if (!\is_object($menuBuilder) || !method_exists($menuBuilder, 'createProfileMenu')) {
greg0ire marked this conversation as resolved.
Show resolved Hide resolved
throw new \InvalidArgumentException(
'Argument 4 should be object with public function "createProfileMenu(array $itemOptions = [])"'
);
}

$this->menuBuilder = $menuBuilder;
}

public function getName(): string
{
return 'Ecommerce Profile Menu';
}

public function configureSettings(OptionsResolver $resolver): void
{
parent::configureSettings($resolver);

$resolver->setDefaults([
'cache_policy' => 'private',
'menu_template' => 'SonataBlockBundle:Block:block_side_menu_template.html.twig',
]);
}

private function getMenu(BlockContextInterface $blockContext): ItemInterface
{
$settings = $blockContext->getSettings();

$menu = parent::getMenu($blockContext);

if (null === $menu || '' === $menu) {
$menu = $this->menuBuilder->createProfileMenu(
[
'childrenAttributes' => ['class' => $settings['menu_class']],
'attributes' => ['class' => $settings['children_class']],
]
);

if (method_exists($menu, 'setCurrentUri')) {
$menu->setCurrentUri($settings['current_uri']);
}
}

return $menu;
}
}
27 changes: 27 additions & 0 deletions src/CustomerBundle/Controller/DashboardController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\CustomerBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;

final class DashboardController extends Controller
wbloszyk marked this conversation as resolved.
Show resolved Hide resolved
{
public function dashboardAction(): Response
{
return $this->render('SonataCustomerBundle:Profile:dashboard.html.twig', [
'blocks' => $this->container->getParameter('sonata.customer.profile.blocks'),
]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\CustomerBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
* @author Thomas Rabaix <thomas.rabaix@sonata-project.org>
*/
final class GlobalVariablesCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$container->getDefinition('twig')
->addMethodCall('addGlobal', ['sonata_customer', new Reference('sonata.customer.twig.global')]);
}
}
105 changes: 105 additions & 0 deletions src/CustomerBundle/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public function getConfigTreeBuilder()
$node = $treeBuilder->root('sonata_customer');

$this->addModelSection($node);
$this->addProfileSection($node);

return $treeBuilder;
}
Expand Down Expand Up @@ -63,4 +64,108 @@ private function addModelSection(ArrayNodeDefinition $node): void
->end()
;
}

private function addProfileSection(ArrayNodeDefinition $node): void
{
$node
->children()
->arrayNode('profile')
->addDefaultsIfNotSet()
->fixXmlConfig('block')
->children()
->scalarNode('template')
->info('This is the profile template. You should extend your profile actions template by using {% extends sonata_customer.profileTemplate %}.')
->cannotBeEmpty()
->defaultValue('SonataCustomerBundle:Profile:action.html.twig')
->end()
->scalarNode('menu_builder')
->info('MenuBuilder::createProfileMenu(array $itemOptions = []):ItemInterface is used to build profile menu.')
->defaultValue('sonata.customer.profile.menu_builder.default')
->cannotBeEmpty()
->end()
->arrayNode('blocks')
->info('Define your customer profile block here.')
->defaultValue($this->getProfileBlocksDefaultValues())
->prototype('array')
->fixXmlConfig('setting')
->children()
->scalarNode('type')->cannotBeEmpty()->end()
greg0ire marked this conversation as resolved.
Show resolved Hide resolved
->arrayNode('settings')
->useAttributeAsKey('id')
->prototype('variable')->defaultValue([])->end()
->end()
->scalarNode('position')->defaultValue('right')->end()
greg0ire marked this conversation as resolved.
Show resolved Hide resolved
->end()
->end()
->end()
->arrayNode('menu')
->info('Define your customer profile menu records here.')
->prototype('array')
->addDefaultsIfNotSet()
->cannotBeEmpty()
->children()
->scalarNode('route')->cannotBeEmpty()->end()
->arrayNode('route_parameters')
->defaultValue([])
->prototype('array')->end()
->end()
->scalarNode('label')->cannotBeEmpty()->end()
->scalarNode('domain')->defaultValue('messages')->end()
->end()
->end()
->defaultValue($this->getProfileMenuDefaultValues())
->end()
->end()
->end()
->end()
wbloszyk marked this conversation as resolved.
Show resolved Hide resolved
;
}

/**
* Returns default values for profile menu (to avoid BC Break).
*/
private function getProfileMenuDefaultValues(): array
{
return [
[
'route' => 'sonata_customer_dashboard',
'label' => 'link_list_dashboard',
'domain' => 'SonataCustomerBundle',
'route_parameters' => [],
],
[
'route' => 'sonata_customer_addresses',
'label' => 'link_list_addresses',
'domain' => 'SonataCustomerBundle',
'route_parameters' => [],
],
[
'route' => 'sonata_order_index',
'label' => 'order_list',
'domain' => 'SonataOrderBundle',
'route_parameters' => [],
],
];
}

private function getProfileBlocksDefaultValues(): array
{
return [
[
'position' => 'left',
'type' => 'sonata.order.block.recent_orders',
'settings' => ['title' => 'Recent Orders', 'number' => 5, 'mode' => 'public'],
],
[
'position' => 'right',
'type' => 'sonata.news.block.recent_posts',
'settings' => ['title' => 'Recent Posts', 'number' => 5, 'mode' => 'public'],
],
[
'position' => 'right',
'type' => 'sonata.news.block.recent_comments',
'settings' => ['title' => 'Recent Comments', 'number' => 5, 'mode' => 'public'],
],
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ public function load(array $configs, ContainerBuilder $container): void

$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('block.xml');
$loader->load('orm.xml');
$loader->load('form.xml');
$loader->load('menu.xml');
$loader->load('orm.xml');
$loader->load('twig.xml');

if (isset($bundles['FOSRestBundle'], $bundles['NelmioApiDocBundle'])) {
Expand All @@ -69,6 +70,7 @@ public function load(array $configs, ContainerBuilder $container): void
$loader->load('admin.xml');
}

$this->configureCustomerProfile($container, $config);
$this->registerDoctrineMapping($config);
$this->registerParameters($container, $config);
}
Expand Down Expand Up @@ -157,4 +159,13 @@ public function registerDoctrineMapping(array $config): void
'orphanRemoval' => false,
]);
}

private function configureCustomerProfile(ContainerBuilder $container, array $config)
{
$container->setParameter('sonata.customer.profile.blocks', $config['profile']['blocks']);
$container->setParameter('sonata.customer.profile.template', $config['profile']['template']);

$container->setAlias('sonata.customer.profile.menu_builder', $config['profile']['menu_builder']);
$container->getDefinition('sonata.customer.profile.menu_builder.default')->replaceArgument(2, $config['profile']['menu']);
}
}
Loading