Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EZP-29998: As a developer, I want to define icons for content types #804

Merged
merged 12 commits into from
Jan 29, 2019
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformAdminUiBundle\DependencyInjection\Configuration\Parser;

use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\AbstractParser;
use eZ\Bundle\EzPublishCoreBundle\DependencyInjection\Configuration\SiteAccessAware\ContextualizerInterface;
use Symfony\Component\Config\Definition\Builder\NodeBuilder;

/**
* Configuration parser for subtree related operations.
*
* Example configuration:
*
* ```yaml
* ezpublish:
* system:
* default: # configuration per siteaccess or siteaccess group
* content_type:
* article:
* thumbnail: '/assets/images/customarticle.svg'
* poll:
* thumbnail: '/assets/images/poll.svg'
* ```
*/
class ContentType extends AbstractParser
{
/**
* {@inheritdoc}
*/
public function mapConfig(array &$scopeSettings, $currentScope, ContextualizerInterface $contextualizer)
{
if (empty($scopeSettings['content_type'])) {
return;
}

foreach ($scopeSettings['content_type'] as $identifier => $config) {
$contextualizer->setContextualParameter("content_type.$identifier", $currentScope, $config);
}
}

/**
* {@inheritdoc}
*/
public function addSemanticConfig(NodeBuilder $nodeBuilder)
{
$nodeBuilder
->arrayNode('content_type')
->useAttributeAsKey('identifier')
->arrayPrototype()
->children()
->scalarNode('thumbnail')->defaultNull()->end()
->end()
->end()
->end();
}
}
2 changes: 2 additions & 0 deletions src/bundle/EzPlatformAdminUiBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use EzSystems\EzPlatformAdminUiBundle\DependencyInjection\Compiler\ViewBuilderRegistryPass;
use EzSystems\EzPlatformAdminUiBundle\DependencyInjection\Configuration\Parser\AdminUiForms;
use EzSystems\EzPlatformAdminUiBundle\DependencyInjection\Configuration\Parser\ContentTranslateView;
use EzSystems\EzPlatformAdminUiBundle\DependencyInjection\Configuration\Parser\ContentType;
use EzSystems\EzPlatformAdminUiBundle\DependencyInjection\Configuration\Parser\LocationIds;
use EzSystems\EzPlatformAdminUiBundle\DependencyInjection\Configuration\Parser\Module;
use EzSystems\EzPlatformAdminUiBundle\DependencyInjection\Configuration\Parser\Notifications;
Expand Down Expand Up @@ -83,6 +84,7 @@ private function getConfigParsers(): array
new Notifications(),
new ContentTranslateView(),
new AdminUiForms(),
new ContentType(),
];
}
}
35 changes: 35 additions & 0 deletions src/bundle/Resources/config/default_parameters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,41 @@ parameters:
match:
SystemInfo\Identifier: 'symfony_kernel'

ezsettings.default.content_type.about:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#about'
ezsettings.default.content_type.article:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#article'
ezsettings.default.content_type.blog:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#blog'
ezsettings.default.content_type.blog_post:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#blog_post'
ezsettings.default.content_type.folder:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#folder'
ezsettings.default.content_type.form:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#form'
ezsettings.default.content_type.place:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#place'
ezsettings.default.content_type.product:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#product'
ezsettings.default.content_type.field:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#field'
ezsettings.default.content_type.user:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#user'
ezsettings.default.content_type.user_group:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#user_group'
ezsettings.default.content_type.file:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#file'
ezsettings.default.content_type.gallery:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#gallery'
ezsettings.default.content_type.image:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#image'
ezsettings.default.content_type.video:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#video'
ezsettings.default.content_type.landing_page:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#landing_page'
ezsettings.default.content_type.default-config:
thumbnail: '/bundles/ezplatformadminui/img/ez-icons.svg#file'

ezplatform.content_view.tabs.default_template: '@@ezdesign/parts/tab/default.html.twig'

ezplatform.multifile_upload.location.mappings: []
Expand Down
2 changes: 2 additions & 0 deletions src/bundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,5 @@ services:
- {name: kernel.event_subscriber, priority: -250}

EzSystems\EzPlatformAdminUiBundle\Templating\Twig\UserPreferencesGlobalExtension: ~

EzSystems\EzPlatformAdminUi\UI\Service\ContentTypeIconResolver: ~
2 changes: 2 additions & 0 deletions src/bundle/Resources/config/services/ui_config/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,5 @@ services:
- { name: ezplatform.admin_ui.config_provider, key: 'dateFormat' }

EzSystems\EzPlatformAdminUiBundle\Templating\Twig\PathStringExtension: ~

EzSystems\EzPlatformAdminUiBundle\Templating\Twig\ContentTypeIconExtension: ~
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
(function(global, doc, eZ) {
let contentTypesDataMap = null;

/**
* Creates map with content types identifiers as keys for faster lookup
*
* @function createContentTypeDataMap
* @returns {Object} contentTypesDataMap
*/
const createContentTypeDataMap = () =>
Object.values(eZ.adminUiConfig.contentTypes).reduce((contentTypeDataMap, contentTypeGroup) => {
for (const contentTypeData of contentTypeGroup) {
contentTypeDataMap[contentTypeData.identifier] = contentTypeData;
}

return contentTypeDataMap;
}, {});

/**
* Returns an URL to a content type icon
*
* @function getContentTypeIcon
* @param {String} contentTypeIdentifier
* @returns {String|null} url to icon
*/
const getContentTypeIconUrl = (contentTypeIdentifier) => {
if (!contentTypesDataMap) {
contentTypesDataMap = createContentTypeDataMap();
}

if (!contentTypeIdentifier || !contentTypesDataMap[contentTypeIdentifier]) {
return null;
}

const iconUrl = contentTypesDataMap[contentTypeIdentifier].thumbnail;

return iconUrl;
};

eZ.addConfig('helpers.contentType', {
getContentTypeIconUrl,
});
})(window, document, window.eZ);
1 change: 1 addition & 0 deletions src/bundle/Resources/views/layout.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@
'@EzPlatformAdminUiBundle/Resources/public/js/scripts/helpers/request.helper.js'
'@EzPlatformAdminUiBundle/Resources/public/js/scripts/helpers/notification.helper.js'
'@EzPlatformAdminUiBundle/Resources/public/js/scripts/helpers/timezone.helper.js'
'@EzPlatformAdminUiBundle/Resources/public/js/scripts/helpers/content.type.helper.js'
'@EzPlatformAdminUiBundle/Resources/public/js/scripts/admin.notifications.js'
'@EzPlatformAdminUiModulesBundle/Resources/public/js/UniversalDiscovery.module.js'
'@EzPlatformAdminUiBundle/Resources/public/js/scripts/button.trigger.js'
Expand Down
43 changes: 43 additions & 0 deletions src/bundle/Templating/Twig/ContentTypeIconExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformAdminUiBundle\Templating\Twig;

use EzSystems\EzPlatformAdminUi\UI\Service\ContentTypeIconResolver;
use Twig_Extension;
use Twig_SimpleFunction;

class ContentTypeIconExtension extends Twig_Extension
{
/** @var \EzSystems\EzPlatformAdminUi\UI\Service\ContentTypeIconResolver */
private $contentTypeIconResolver;

/**
* @param \EzSystems\EzPlatformAdminUi\UI\Service\ContentTypeIconResolver $contentTypeIconResolver
*/
public function __construct(ContentTypeIconResolver $contentTypeIconResolver)
{
$this->contentTypeIconResolver = $contentTypeIconResolver;
}

/**
* {@inheritdoc}
*/
public function getFunctions(): array
{
return [
new Twig_SimpleFunction(
'ez_content_type_icon',
[$this->contentTypeIconResolver, 'getContentTypeIcon'],
[
'is_safe' => ['html'],
]
),
];
}
}
121 changes: 121 additions & 0 deletions src/lib/Tests/UI/Config/Service/ContentTypeIconResolverTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformAdminUi\Tests\UI\Config\Service;

use eZ\Publish\Core\MVC\ConfigResolverInterface;
use EzSystems\EzPlatformAdminUi\UI\Service\ContentTypeIconResolver;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Asset\Packages;

class ContentTypeIconResolverTest extends TestCase
{
/** @var \eZ\Publish\Core\MVC\ConfigResolverInterface|\PHPUnit\Framework\MockObject\MockObject */
private $configResolver;

/** @var \Symfony\Component\Asset\Packages|\PHPUnit\Framework\MockObject\MockObject */
private $packages;

/** @var \EzSystems\EzPlatformAdminUi\UI\Service\ContentTypeIconResolver */
private $contentTypeIconResolver;

protected function setUp()
{
$this->configResolver = $this->createMock(ConfigResolverInterface::class);
$this->packages = $this->createMock(Packages::class);

$this->contentTypeIconResolver = new ContentTypeIconResolver(
$this->configResolver,
$this->packages
);
}

/**
* @dataProvider dataProviderForGetContentTypeIcon
*/
public function testGetContentTypeIcon(array $config, string $identifier, string $expected)
{
$this->configResolver
->expects($this->any())
->method('hasParameter')
->willReturnCallback(function (string $key) use ($config) {
$key = explode('.', $key);

return isset($config[array_pop($key)]);
});

$this->configResolver
->expects($this->any())
->method('getParameter')
->willReturnCallback(function (string $key) use ($config) {
$key = explode('.', $key);

return $config[array_pop($key)];
});

$this->packages
->expects($this->any())
->method('getUrl')
->willReturnCallback(function (string $uri) {
return "https://cdn.example.com/$uri";
});

$this->assertEquals($expected, $this->contentTypeIconResolver->getContentTypeIcon($identifier));
}

public function dataProviderForGetContentTypeIcon(): array
{
return [
[
[
'custom' => [
'thumbnail' => 'icon.svg#custom',
],
'default-config' => [
'thumbnail' => 'icon.svg#default',
],
],
'custom',
'https://cdn.example.com/icon.svg#custom',
],
[
[
'custom-without-fragment' => [
'thumbnail' => 'icon.png',
],
'default-config' => [
'thumbnail' => 'icon.svg#default',
],
],
'custom-without-fragment',
'https://cdn.example.com/icon.png',
],
[
[
'custom-without-icon' => [
'thumbnail' => null,
],
'default-config' => [
'thumbnail' => 'icon.svg#default',
],
],
'custom-without-icon',
'https://cdn.example.com/icon.svg#default',
],
[
[
'default-config' => [
'thumbnail' => 'icon.svg#default',
],
],
'custom-with-missing-config',
'https://cdn.example.com/icon.svg#default',
],
];
}
}
14 changes: 12 additions & 2 deletions src/lib/UI/Config/Provider/ContentTypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use eZ\Publish\API\Repository\ContentTypeService;
use eZ\Publish\Core\MVC\Symfony\Locale\UserLanguagePreferenceProviderInterface;
use EzSystems\EzPlatformAdminUi\UI\Config\ProviderInterface;
use EzSystems\EzPlatformAdminUi\UI\Service\ContentTypeIconResolver;

class ContentTypes implements ProviderInterface
{
Expand All @@ -18,14 +19,22 @@ class ContentTypes implements ProviderInterface
/** @var \eZ\Publish\Core\MVC\Symfony\Locale\UserLanguagePreferenceProviderInterface */
private $userLanguagePreferenceProvider;

/** @var \EzSystems\EzPlatformAdminUi\UI\Service\ContentTypeIconResolver */
private $contentTypeIconResolver;

/**
* @param \eZ\Publish\API\Repository\ContentTypeService $contentTypeService
* @param \eZ\Publish\Core\MVC\Symfony\Locale\UserLanguagePreferenceProviderInterface $userLanguagePreferenceProvider
* @param \EzSystems\EzPlatformAdminUi\UI\Service\ContentTypeIconResolver $contentTypeIconResolver
*/
public function __construct(ContentTypeService $contentTypeService, UserLanguagePreferenceProviderInterface $userLanguagePreferenceProvider)
{
public function __construct(
ContentTypeService $contentTypeService,
UserLanguagePreferenceProviderInterface $userLanguagePreferenceProvider,
ContentTypeIconResolver $contentTypeIconResolver
) {
$this->contentTypeService = $contentTypeService;
$this->userLanguagePreferenceProvider = $userLanguagePreferenceProvider;
$this->contentTypeIconResolver = $contentTypeIconResolver;
}

/**
Expand All @@ -48,6 +57,7 @@ public function getConfig()
$contentTypeGroups[$contentTypeGroup->identifier][] = [
'identifier' => $contentType->identifier,
'name' => $contentType->getName(),
'thumbnail' => $this->contentTypeIconResolver->getContentTypeIcon($contentType->identifier),
];
}
}
Expand Down
Loading