Skip to content

Commit

Permalink
feat: add PageExportController to bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
mike4git committed Jan 31, 2025
1 parent 7eb9595 commit 71c9c41
Show file tree
Hide file tree
Showing 9 changed files with 310 additions and 1 deletion.
59 changes: 59 additions & 0 deletions config/packages/neusta_import_export_converter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
neusta_converter:
converter:
###########################################################
# Import Converter (YamlExportPage -> Page)
###########################################################
neusta_import_page:
target: Pimcore\Model\Document\Page
populators:
- Neusta\Pimcore\ImportExportBundle\Documents\Import\PageImportPopulator
properties:
id:
source: id
default: 0
key: ~
title:
source: title
default: 'no title'
controller:
source: controller
default: 'no controller'
type:
source: type
default: 'page'
published:
source: published
default: false
path:
source: path
default: '/'
parentId:
source: parentId
default: 0

###########################################################
# Export Converter (Page -> YamlExportPage)
###########################################################
neusta_export_page:
target: Neusta\Pimcore\ImportExportBundle\Documents\Export\YamlExportPage
populators:
- page.property.language.populator
- page.property.navigation_title.populator
- page.property.navigation_name.populator
- page.editables.populator
properties:
id: ~
key: ~
title: ~
controller: ~
type: ~
published: ~
path: ~
parentId: ~

neusta_export_editable_converter:
target: Neusta\Pimcore\ImportExportBundle\Documents\Export\YamlExportEditable
properties:
type: ~
name: ~
data: ~
2 changes: 2 additions & 0 deletions config/pimcore/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
imports:
- { resource: ../packages/ }
5 changes: 5 additions & 0 deletions config/pimcore/routing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
page_export:
resource: '../../src/Controller/Admin/PageExportController.php'
type: annotation
options:
expose: true
55 changes: 55 additions & 0 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,58 @@ services:
_defaults:
autowire: true
autoconfigure: true

Neusta\Pimcore\ImportExportBundle\Toolbox\:
resource: '../src/Toolbox'

###########################################################
# Controller
###########################################################
Neusta\Pimcore\ImportExportBundle\Controller\Admin\PageExportController:
public: true
tags: [ 'controller.service_arguments' ]

###########################################################
# Import Populator (YamlExportPage -> Page)
###########################################################
Neusta\Pimcore\ImportExportBundle\Documents\Import\PageImportPopulator: ~

Neusta\Pimcore\ImportExportBundle\Documents\Import\PageImporter:
arguments:
$yamlToPageConverter: '@neusta_import_page'

###########################################################
# Export Populator (Page -> YamlExportPage)
###########################################################
page.editables.populator:
class: Neusta\ConverterBundle\Populator\ArrayConvertingPopulator
arguments:
$converter: '@neusta_export_editable_converter'
$sourceArrayPropertyName: 'editables'
$targetPropertyName: 'editables'

page.property.language.populator:
class: Neusta\Pimcore\ConverterBundle\Populator\PropertyBasedMappingPopulator
arguments:
$propertyKey: 'language'
$targetProperty: 'language'

page.property.navigation_title.populator:
class: Neusta\Pimcore\ConverterBundle\Populator\PropertyBasedMappingPopulator
arguments:
$propertyKey: 'navigation_title'
$targetProperty: 'navigation_title'

page.property.navigation_name.populator:
class: Neusta\Pimcore\ConverterBundle\Populator\PropertyBasedMappingPopulator
arguments:
$propertyKey: 'navigation_name'
$targetProperty: 'navigation_name'

Neusta\Pimcore\ImportExportBundle\Documents\Export\PageExporter:
arguments:
$pageToYamlConverter: '@neusta_export_page'

Neusta\Pimcore\ImportExportBundle\EventListener\PimcoreAdminListener:
tags:
- { name: kernel.event_listener, event: pimcore.bundle_manager.paths.js, method: addJSFiles }
25 changes: 25 additions & 0 deletions public/js/exportPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// /Resources/public/js/exportPage.js
pimcore.registerNS("pimcore.plugin.page.export");

pimcore.plugin.page.export = Class.create({
initialize: function () {
document.addEventListener(pimcore.events.prepareDocumentTreeContextMenu, this.onPrepareDocumentTreeContextMenu.bind(this));
},

onPrepareDocumentTreeContextMenu: function (e) {
let menu = e.detail.menu;
let document = e.detail.document;
// Export page into yaml file
menu.add("-");
menu.add(new Ext.menu.Item({
text: 'Export to yaml',
iconCls: "pimcore_icon_export",
handler: function () {
pimcore.helpers.download(Routing.generate('page_export', {page_id: document.data.id}));
}
}));
},

});

var pimcorePluginPageExport = new pimcore.plugin.page.export();
58 changes: 58 additions & 0 deletions src/Controller/Admin/PageExportController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php declare(strict_types=1);

namespace Neusta\Pimcore\ImportExportBundle\Controller\Admin;

use Neusta\Pimcore\ImportExportBundle\Documents\Export\PageExporter;
use Neusta\Pimcore\ImportExportBundle\Toolbox\Repository\PageRepository;
use Pimcore\Controller\UserAwareController;
use Pimcore\Model\Document\Page;
use Symfony\Component\HttpFoundation\HeaderUtils;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

final class PageExportController extends UserAwareController
{
public function __construct(
private PageExporter $pageExporter,
private PageRepository $pageRepository,
) {
}

/**
* @Route("/admin/page/export", name="page_export", methods={"GET"})
*/
public function exportPage(Request $request): Response
{
$pageId = $request->get('page_id');
$page = $this->pageRepository->getById($pageId);

if (!$page instanceof Page) {
return new JsonResponse(
\sprintf('Page with id "%s" was not found', $pageId),
Response::HTTP_NOT_FOUND,
);
}

try {
$json = $this->pageExporter->toYaml($page);
} catch (\Exception $e) {
return new JsonResponse($e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}

$response = new Response($json);
$response->headers->set('Content-type', 'application/json');
$response->headers->set(
'Content-Disposition',
HeaderUtils::makeDisposition(HeaderUtils::DISPOSITION_ATTACHMENT, $this->createFilename($page)),
);

return $response;
}

private function createFilename(Page $page): string
{
return \sprintf('%s.yaml', str_replace(' ', '_', (string) $page->getKey()));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php declare(strict_types=1);

namespace Neusta\Pimcore\ImportExportBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
Expand All @@ -9,7 +11,7 @@ final class NeustaPimcoreImportExportExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new Loader\YamlFileLoader($container, new FileLocator(dirname(__DIR__, 2) . '/config'));
$loader = new Loader\YamlFileLoader($container, new FileLocator(\dirname(__DIR__, 2) . '/config'));
$loader->load('services.yaml');
}
}
18 changes: 18 additions & 0 deletions src/EventListener/PimcoreAdminListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php declare(strict_types=1);

namespace Neusta\Pimcore\ImportExportBundle\EventListener;

use Pimcore\Event\BundleManager\PathsEvent;

final class PimcoreAdminListener
{
public function addJSFiles(PathsEvent $event): void
{
$event->setPaths(array_merge(
$event->getPaths(),
[
'/bundles/neustapimcoreimportexport/js/exportPage.js',
],
));
}
}
85 changes: 85 additions & 0 deletions tests/Unit/Controller/Admin/PageExportControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<?php declare(strict_types=1);

namespace Neusta\Pimcore\ImportExportBundle\Tests\Unit\Controller;

use Neusta\Pimcore\ImportExportBundle\Controller\Admin\PageExportController;
use Neusta\Pimcore\ImportExportBundle\Documents\Export\PageExporter;
use Neusta\Pimcore\Toolbox\Repository\PageRepository;
use PHPUnit\Framework\TestCase;
use Pimcore\Model\Document\Page;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class PageExportControllerTest extends TestCase
{
use ProphecyTrait;

private PageExportController $controller;

/** @var ObjectProphecy<\Neusta\TrinityPimcoreBundle\Fixture\Documents\Export\PageExporter> */
private $pageExporter;

/** @var ObjectProphecy<PageRepository> */
private $pageRepository;

protected function setUp(): void
{
$this->pageExporter = $this->prophesize(PageExporter::class);
$this->pageRepository = $this->prophesize(PageRepository::class);

$this->controller = new PageExportController(
$this->pageExporter->reveal(),
$this->pageRepository->reveal(),
);
}

public function testExportPage_regular_case(): void
{
$request = $this->prophesize(Request::class);
$request->get('page_id')->willReturn('17');

$page = $this->prophesize(Page::class);
$this->pageRepository->getById(17)->willReturn($page->reveal());
$this->pageExporter->toYaml($page->reveal())->willReturn('TEST_YAML');

$response = $this->controller->exportPage($request->reveal());

self::assertTrue($response instanceof Response);
self::assertEquals(Response::HTTP_OK, $response->getStatusCode());
self::assertEquals('application/json', $response->headers->get('Content-type'));
self::assertEquals('TEST_YAML', $response->getContent());
}

public function testExportPage_exceptional_case(): void
{
$request = $this->prophesize(Request::class);
$request->get('page_id')->willReturn('17');

$page = $this->prophesize(Page::class);
$this->pageRepository->getById(17)->willReturn($page->reveal());
$this->pageExporter->toYaml($page->reveal())->willThrow(new \Exception('Problem'));

$response = $this->controller->exportPage($request->reveal());

self::assertTrue($response instanceof JsonResponse);
self::assertEquals(Response::HTTP_INTERNAL_SERVER_ERROR, $response->getStatusCode());
self::assertEquals('"Problem"', $response->getContent());
}

public function testExportPage_no_document_case(): void
{
$request = $this->prophesize(Request::class);
$request->get('page_id')->willReturn('17');

$this->pageRepository->getById(17)->willReturn(null);

$response = $this->controller->exportPage($request->reveal());

self::assertTrue($response instanceof JsonResponse);
self::assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode());
self::assertEquals('"Page with id \u002217\u0022 was not found"', $response->getContent());
}
}

0 comments on commit 71c9c41

Please sign in to comment.