Skip to content
This repository was archived by the owner on Sep 16, 2021. It is now read-only.

Commit e0a0f15

Browse files
authored
Merge pull request #76 from symfony-cmf/resource_enhancer
moves the sonata admin description enhancer from resource component
2 parents 0756264 + 6c4e87d commit e0a0f15

File tree

6 files changed

+253
-0
lines changed

6 files changed

+253
-0
lines changed

src/DependencyInjection/CmfSonataPhpcrAdminIntegrationExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public function load(array $configs, ContainerBuilder $container)
6262
$this->loadBundles($config['bundles'], $loader, $container);
6363

6464
$loader->load('main.xml');
65+
$loader->load('enhancer.xml');
6566
}
6667

6768
private function loadBundles(array $config, XmlFileLoader $loader, ContainerBuilder $container)

src/Description/SonataEnhancer.php

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony CMF package.
5+
*
6+
* (c) 2011-2017 Symfony CMF
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Cmf\Bundle\SonataPhpcrAdminIntegrationBundle\Description;
13+
14+
use Doctrine\Common\Util\ClassUtils;
15+
use Sonata\AdminBundle\Admin\Pool;
16+
use Symfony\Cmf\Component\Resource\Description\Description;
17+
use Symfony\Cmf\Component\Resource\Description\DescriptionEnhancerInterface;
18+
use Symfony\Cmf\Component\Resource\Description\Descriptor;
19+
use Symfony\Cmf\Component\Resource\Puli\Api\PuliResource;
20+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
21+
22+
/**
23+
* Add links and meta-info from Sonata Admin.
24+
*
25+
* @author Daniel Leech <[email protected]>
26+
*
27+
* @internal
28+
*/
29+
class SonataEnhancer implements DescriptionEnhancerInterface
30+
{
31+
/**
32+
* @var Pool
33+
*/
34+
private $pool;
35+
36+
/**
37+
* @var UrlGeneratorInterface
38+
*/
39+
private $urlGenerator;
40+
41+
/**
42+
* @param Pool $pool
43+
* @param UrlGeneratorInterface $urlGenerator
44+
*/
45+
public function __construct(Pool $pool, UrlGeneratorInterface $urlGenerator)
46+
{
47+
$this->pool = $pool;
48+
$this->urlGenerator = $urlGenerator;
49+
}
50+
51+
/**
52+
* {@inheritdoc}
53+
*/
54+
public function enhance(Description $description)
55+
{
56+
$object = $description->getResource()->getPayload();
57+
58+
// sonata has dependency on ClassUtils so this is fine.
59+
$class = ClassUtils::getClass($object);
60+
$admin = $this->pool->getAdminByClass($class);
61+
62+
$links = [];
63+
64+
$routeCollection = $admin->getRoutes();
65+
66+
foreach ($routeCollection->getElements() as $code => $route) {
67+
$routeName = $route->getDefault('_sonata_name');
68+
$url = $this->urlGenerator->generate($routeName, [
69+
$admin->getIdParameter() => $admin->getUrlsafeIdentifier($object),
70+
], true);
71+
72+
$routeRole = substr($code, strlen($admin->getCode()) + 1);
73+
74+
$links[$routeRole] = $url;
75+
}
76+
77+
if (isset($links['list'])) {
78+
$description->set('list', $links['list']);
79+
unset($links['list']);
80+
}
81+
82+
if (isset($links['create'])) {
83+
$description->set(Descriptor::LINK_CREATE_HTML, $links['create']);
84+
unset($links['create']);
85+
}
86+
87+
if (isset($links['edit'])) {
88+
$description->set(Descriptor::LINK_EDIT_HTML, $links['edit']);
89+
unset($links['edit']);
90+
}
91+
92+
if (isset($links['delete'])) {
93+
$description->set(Descriptor::LINK_REMOVE_HTML, $links['delete']);
94+
unset($links['delete']);
95+
}
96+
97+
if (isset($links['show'])) {
98+
$description->set(Descriptor::LINK_SHOW_HTML, $links['show']);
99+
unset($links['show']);
100+
}
101+
102+
$description->set(Descriptor::PAYLOAD_TITLE, $admin->toString($object));
103+
$description->set(Descriptor::TYPE_ALIAS, $admin->getLabel());
104+
}
105+
106+
/**
107+
* {@inheritdoc}
108+
*/
109+
public function supports(PuliResource $resource)
110+
{
111+
if (false === $resource instanceof CmfResource) {
112+
return false;
113+
}
114+
115+
$payload = $resource->getPayload();
116+
117+
// sonata has dependency on ClassUtils so this is fine.
118+
$class = ClassUtils::getClass($payload);
119+
120+
return $this->pool->hasAdminByClass($class);
121+
}
122+
}

src/Resources/config/enhancer.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
6+
7+
<services>
8+
9+
<service
10+
id="cmf_sonata_phpcr_admin_integration.description.enhancer"
11+
class="Symfony\Cmf\Bundle\SonataPhpcrAdminIntegrationBundle\Description\SonataEnhancer"
12+
public="false">
13+
<argument type="service" id="sonata.admin.pool" />
14+
<argument type="service" id="router" />
15+
<tag name="cmf_resource.description.enhancer" alias="sonata_phpcr_admin" />
16+
</service>
17+
18+
</services>
19+
</container>

tests/Resources/app/AppKernel.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public function configure()
3838
new Symfony\Cmf\Bundle\BlockBundle\CmfBlockBundle(),
3939
new Symfony\Cmf\Bundle\MenuBundle\CmfMenuBundle(),
4040
new Symfony\Cmf\Bundle\ContentBundle\CmfContentBundle(),
41+
new JMS\SerializerBundle\JMSSerializerBundle(),
4142
));
4243

4344
if (class_exists('Symfony\Cmf\Bundle\ResourceRestBundle\CmfResourceRestBundle')) {

tests/Unit/DependencyInjection/CmfSonataAdminExtensionTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,4 +141,23 @@ public function testCoreDefaults()
141141
'cmf_sonata_phpcr_admin_integration.core.extension.child'
142142
);
143143
}
144+
145+
public function testEnhancerExists()
146+
{
147+
$this->container->setParameter(
148+
'kernel.bundles',
149+
[
150+
'SonataDoctrinePHPCRAdminBundle' => true,
151+
'SonataAdminBundle' => true,
152+
]
153+
);
154+
155+
$this->load(['bundles' => []]);
156+
157+
$this->assertContainerBuilderHasServiceDefinitionWithTag(
158+
'cmf_sonata_phpcr_admin_integration.description.enhancer',
159+
'cmf_resource.description.enhancer',
160+
['alias' => 'sonata_phpcr_admin']
161+
);
162+
}
144163
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony CMF package.
5+
*
6+
* (c) 2011-2017 Symfony CMF
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Cmf\Bundle\SonataPhpcrAdminIntegrationBundle\Tests\Unit\Enhancer\ResourceDescription;
13+
14+
use Prophecy\Argument;
15+
use Sonata\AdminBundle\Admin\AbstractAdmin;
16+
use Sonata\AdminBundle\Admin\Pool;
17+
use Sonata\AdminBundle\Model\AuditManagerInterface;
18+
use Sonata\AdminBundle\Model\ModelManagerInterface;
19+
use Sonata\AdminBundle\Route\PathInfoBuilder;
20+
use Symfony\Cmf\Bundle\SonataPhpcrAdminIntegrationBundle\Description\SonataEnhancer;
21+
use Symfony\Cmf\Component\Resource\Description\Description;
22+
use Symfony\Cmf\Component\Resource\Description\Descriptor;
23+
use Symfony\Cmf\Component\Resource\Repository\Resource\CmfResource;
24+
use Symfony\Component\DependencyInjection\ContainerBuilder;
25+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
26+
27+
class SonataEnhancerTest extends \PHPUnit_Framework_TestCAse
28+
{
29+
private $admin;
30+
private $pool;
31+
32+
public function setUp()
33+
{
34+
$this->admin = new TestAdmin(
35+
'test',
36+
'stdClass',
37+
'FooController'
38+
);
39+
$this->container = new ContainerBuilder();
40+
$this->pool = new Pool($this->container, 'Test', 'logo');
41+
$this->pool->setAdminClasses([
42+
'stdClass' => ['std_class_admin'],
43+
]);
44+
$this->pool->setAdminServiceIds(['std_class_admin']);
45+
46+
$this->container->set('std_class_admin', $this->admin);
47+
$this->generator = $this->prophesize(UrlGeneratorInterface::class);
48+
$this->resource = $this->prophesize(CmfResource::class);
49+
50+
$this->modelManager = $this->prophesize(ModelManagerInterface::class);
51+
$this->modelManager->getUrlsafeIdentifier(Argument::cetera())->will(function ($args) {
52+
return $args[0];
53+
});
54+
$this->routeBuilder = new PathInfoBuilder($this->prophesize(AuditManagerInterface::class)->reveal());
55+
$this->admin->setRouteBuilder($this->routeBuilder);
56+
$this->admin->setModelManager($this->modelManager->reveal());
57+
$this->admin->setBaseCodeRoute('test');
58+
}
59+
60+
/**
61+
* It should provide a description.
62+
*/
63+
public function testDescriptionProvide()
64+
{
65+
$this->resource->getPayload()->willReturn(new \stdClass());
66+
67+
$this->generator->generate(Argument::cetera())->will(function ($args) {
68+
return '/'.$args[0];
69+
});
70+
71+
$description = new Description($this->resource->reveal());
72+
$enhancer = new SonataEnhancer($this->pool, $this->generator->reveal());
73+
$enhancer->enhance($description);
74+
75+
$this->assertEquals('/std_class_edit', $description->get(Descriptor::LINK_EDIT_HTML));
76+
$this->assertEquals('/std_class_create', $description->get(Descriptor::LINK_CREATE_HTML));
77+
$this->assertEquals('/std_class_show', $description->get(Descriptor::LINK_SHOW_HTML));
78+
$this->assertEquals('/std_class_delete', $description->get(Descriptor::LINK_REMOVE_HTML));
79+
}
80+
}
81+
82+
class TestAdmin extends AbstractAdmin
83+
{
84+
protected $baseRouteName = 'std_class';
85+
protected $baseRoutePattern = '_';
86+
87+
public function __toString()
88+
{
89+
return 'Standard Class';
90+
}
91+
}

0 commit comments

Comments
 (0)