Skip to content

Commit

Permalink
EZP-26672: Copy a content item using Action Bar
Browse files Browse the repository at this point in the history
  • Loading branch information
yannickroger committed Aug 28, 2017
1 parent 58d3c63 commit d74b120
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 3 deletions.
64 changes: 64 additions & 0 deletions spec/Repository/UiLocationServiceSpec.php
Expand Up @@ -6,13 +6,16 @@
*/
namespace spec\EzSystems\HybridPlatformUi\Repository;

use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\API\Repository\ContentTypeService;
use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\TrashService;
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
use eZ\Publish\API\Repository\Values\Content\LocationCreateStruct;
use eZ\Publish\Core\Repository\Values\Content\Content;
use eZ\Publish\Core\Repository\Values\Content\Location;
use eZ\Publish\Core\Repository\Values\Content\VersionInfo;
use eZ\Publish\Core\Repository\Values\ContentType\ContentType;
use EzSystems\HybridPlatformUi\Repository\PathService;
use EzSystems\HybridPlatformUi\Repository\Permission\UiPermissionResolver;
Expand All @@ -24,13 +27,15 @@ class UiLocationServiceSpec extends ObjectBehavior
{
function let(
LocationService $locationService,
ContentService $contentService,
TrashService $trashService,
PathService $pathService,
UiPermissionResolver $permissionResolver,
ContentTypeService $contentTypeService
) {
$this->beConstructedWith(
$locationService,
$contentService,
$trashService,
$pathService,
$permissionResolver,
Expand Down Expand Up @@ -333,4 +338,63 @@ function it_tells_if_a_location_can_be_moved()

$this->canMoveLocation($location)->shouldReturn(true);
}

function it_copies_a_location(
LocationService $locationService,
ContentService $contentService,
ContentTypeService $contentTypeService
) {
$currentLocationId = 1;
$newParentLocationId = 5;
$parentContentTypeId = 2;

$locationContentInfo = new ContentInfo();
$location = new Location(['id' => $currentLocationId, 'contentInfo' => $locationContentInfo]);

$parentContentInfo = new ContentInfo(['contentTypeId' => $parentContentTypeId]);
$newParentLocation = new Location(['id' => $newParentLocationId, 'contentInfo' => $parentContentInfo]);

$locationService->loadLocation($newParentLocationId)->willReturn($newParentLocation);

$parentContentType = new ContentType(['isContainer' => true]);
$contentTypeService->loadContentType($parentContentTypeId)->willReturn($parentContentType);

$locationCreateStruct = new LocationCreateStruct();
$locationService->newLocationCreateStruct($newParentLocationId)->willReturn($locationCreateStruct);
$copiedContentLocationId = 4242;
$copiedContentContentInfo = new ContentInfo(['mainLocationId' => $copiedContentLocationId]);
$copiedContentVersionInfo = new VersionInfo(['contentInfo' => $copiedContentContentInfo]);
$copiedContent = new Content(['versionInfo' => $copiedContentVersionInfo]);
$contentService->copyContent($locationContentInfo, $locationCreateStruct)->willReturn($copiedContent);

$copiedLocation = new Location();
$locationService->loadLocation($copiedContentLocationId)->willReturn($copiedLocation);

$this->copyLocation($location, $newParentLocationId)->shouldBe($copiedLocation);
}

function it_cannot_copy_a_location_to_a_parent_that_is_not_a_container(
LocationService $locationService,
ContentTypeService $contentTypeService
) {
$currentLocationId = 1;
$newParentLocationId = 5;
$contentTypeId = 2;

$location = new Location(['id' => $currentLocationId]);
$contentInfo = new ContentInfo(['contentTypeId' => $contentTypeId]);
$newParentLocation = new Location(['id' => $newParentLocationId, 'contentInfo' => $contentInfo]);
$contentType = new ContentType(['isContainer' => false]);

$locationService->loadLocation($newParentLocationId)->willReturn($newParentLocation);

$contentTypeService->loadContentType($contentTypeId)->willReturn($contentType);

$locationService->newLocationCreateStruct($newParentLocationId)->shouldNotBeCalled();

$this->shouldThrow(InvalidArgumentException::class)->duringCopyLocation(
$location,
$newParentLocationId
);
}
}
15 changes: 15 additions & 0 deletions src/bundle/Controller/ActionBarController.php
Expand Up @@ -62,4 +62,19 @@ public function moveLocationAction(

return $this->redirectToRoute($location);
}

public function copyLocationAction(
Location $location,
Request $request
) {
$copyLocationsForm = $this->formFactory->createLocationContentCopyForm();
$copyLocationsForm->handleRequest($request);

if ($copyLocationsForm->isValid()) {
$newParentLocationId = $copyLocationsForm->get('newParentLocationId')->getData();
$location = $this->uiLocationService->copyLocation($location, $newParentLocationId);
}

return $this->redirectToRoute($location);
}
}
24 changes: 21 additions & 3 deletions src/bundle/Controller/ContentViewController.php
Expand Up @@ -9,6 +9,7 @@
namespace EzSystems\HybridPlatformUiBundle\Controller;

use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\Values\Content\Location;
use eZ\Publish\Core\MVC\Symfony\View\ContentView;
use EzSystems\HybridPlatformUi\Form\UiFormFactory;
use EzSystems\HybridPlatformUi\Repository\UiFieldGroupService;
Expand Down Expand Up @@ -57,6 +58,23 @@ public function locationViewAction(
$locationParameterSupplier->supply($view);
$location = $view->getLocation();

$this->addActionBarFormsToView($view, $location);

$view->addParameters([
'childCount' => $this->locationService->getLocationChildCount($location),
]);

return $view;
}

/**
* Adds the action bar forms to the provided view.
*
* @param ContentView $view
* @param Location $location
*/
private function addActionBarFormsToView(ContentView $view, Location $location)
{
$trashDisabled = !$this->uiLocationService->canRemoveLocation($location);

$trashLocationForm = $this->formFactory->createLocationContentTrashForm(
Expand All @@ -66,13 +84,13 @@ public function locationViewAction(
$moveDisabled = !$this->uiLocationService->canMoveLocation($location);
$moveLocationForm = $this->formFactory->createLocationContentMoveForm($moveDisabled);

$copyLocationForm = $this->formFactory->createLocationContentCopyForm();

$view->addParameters([
'trashLocationForm' => $trashLocationForm->createView(),
'moveLocationForm' => $moveLocationForm->createView(),
'childCount' => $this->locationService->getLocationChildCount($location),
'copyLocationForm' => $copyLocationForm->createView(),
]);

return $view;
}

public function contentTabAction(ContentView $view, UiFieldGroupService $fieldGroupService)
Expand Down
21 changes: 21 additions & 0 deletions src/bundle/Form/Locations/LocationCopy.php
@@ -0,0 +1,21 @@
<?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.
*/
namespace EzSystems\HybridPlatformUiBundle\Form\Locations;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;

class LocationCopy extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('newParentLocationId', HiddenType::class)
->add('copy', SubmitType::class);
}
}
6 changes: 6 additions & 0 deletions src/bundle/Resources/config/routing.yml
Expand Up @@ -33,6 +33,12 @@ ez_hybrid_platform_ui_location_move_location:
defaults:
_controller: EzSystemsHybridPlatformUiBundle:ActionBar:moveLocation
methods: [POST]
ez_hybrid_platform_ui_location_copy_location:
path: /content/{contentId}/location/{locationId}/copy
defaults:
_controller: EzSystemsHybridPlatformUiBundle:ActionBar:copyLocation
methods: [POST]

ez_hybrid_platform_ui_location_sort_order:
path: /content/{contentId}/locations/{locationId}/sortorder
defaults:
Expand Down
23 changes: 23 additions & 0 deletions src/bundle/Resources/views/locationview.html.twig
Expand Up @@ -112,6 +112,29 @@
})
}}
{{ form_end(moveLocationForm) }}

{{
form_start(copyLocationForm, {
"action": path("ez_hybrid_platform_ui_location_copy_location",
{'contentId': content.id, 'locationId': locationId})
})
}}
{{ form_widget(copyLocationForm.newParentLocationId) }}
{{
form_widget(copyLocationForm.copy, {
'label': 'actionbar.copy'|trans()|desc('Copy'),
'attr': {
'class': 'ez-button ez-button-action ez-js-run-universal-discovery',
'data-ud-title': 'actionbar.copy.selectbox.title'|trans()|desc('Select a new location to copy your content item'),
'data-ud-confirm-label': 'actionbar.copy.selectbox.confirmlabel'|trans()|desc('Copy'),
'data-ud-starting-location-id': location.parentLocationId,
'data-ud-container': true,
'data-ud-confirm-fill': '#' ~ copyLocationForm.newParentLocationId.vars.id,
'data-ud-confirm-fill-with': 'location.id',
}
})
}}
{{ form_end(copyLocationForm) }}
{% endblock %}
</ez-toolbar>
{% endblock %}
Expand Down
11 changes: 11 additions & 0 deletions src/lib/Form/UiFormFactory.php
Expand Up @@ -11,6 +11,7 @@
use EzSystems\HybridPlatformUi\Mapper\Form\LocationMapper;
use EzSystems\HybridPlatformUi\Mapper\Form\TranslationMapper;
use EzSystems\HybridPlatformUi\Mapper\Form\VersionMapper;
use EzSystems\HybridPlatformUiBundle\Form\Locations\LocationCopy;
use EzSystems\HybridPlatformUiBundle\Form\Locations\LocationMove;
use EzSystems\HybridPlatformUiBundle\Form\Locations\LocationSwap;
use EzSystems\HybridPlatformUiBundle\Form\Locations\LocationTrash;
Expand Down Expand Up @@ -149,6 +150,16 @@ public function createLocationContentMoveForm($disabled = false)
);
}

/**
* Create a form to be used for copying contents location.
*
* @return \Symfony\Component\Form\FormInterface
*/
public function createLocationContentCopyForm()
{
return $this->formFactory->create(LocationCopy::class);
}

/**
* Create form to be used for ordering of locations.
*
Expand Down
45 changes: 45 additions & 0 deletions src/lib/Repository/UiLocationService.php
Expand Up @@ -6,6 +6,7 @@
*/
namespace EzSystems\HybridPlatformUi\Repository;

use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\API\Repository\ContentTypeService;
use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\TrashService;
Expand All @@ -32,6 +33,11 @@ class UiLocationService
*/
private $trashService;

/**
* @var ContentService
*/
private $contentService;

/**
* @var PathService
*/
Expand All @@ -49,13 +55,15 @@ class UiLocationService

public function __construct(
LocationService $locationService,
ContentService $contentService,
TrashService $trashService,
PathService $pathService,
UiPermissionResolver $permissionResolver,
ContentTypeService $contentTypeService
) {
$this->locationService = $locationService;
$this->trashService = $trashService;
$this->contentService = $contentService;
$this->pathService = $pathService;
$this->permissionResolver = $permissionResolver;
$this->contentTypeService = $contentTypeService;
Expand Down Expand Up @@ -227,6 +235,43 @@ public function moveLocation(Location $currentLocation, $newParentLocationId)
return $this->locationService->loadLocation($currentLocation->id);
}

/**
* Copies a location item.
* Returns the newly copied location.
*
* @param Location $currentLocation
* @param mixed $newParentLocationId
*
* @return Location
*
* @throws InvalidArgumentException
*/
public function copyLocation(Location $currentLocation, $newParentLocationId)
{
$newParentLocation = $this->locationService->loadLocation($newParentLocationId);

$newParentContentType = $this->contentTypeService->loadContentType(
$newParentLocation->getContentInfo()->contentTypeId
);

if (!$newParentContentType->isContainer) {
throw new InvalidArgumentException(
'$newParentLocation',
'Cannot copy location to a parent that is not a container'
);
}

$locationCreateStruct = $this->locationService->newLocationCreateStruct($newParentLocationId);

// Copying only the current item, not the subtree
$copiedContent = $this->contentService->copyContent(
$currentLocation->contentInfo,
$locationCreateStruct
);

return $this->locationService->loadLocation($copiedContent->contentInfo->mainLocationId);
}

private function buildUiLocations(array $locations)
{
return array_map(
Expand Down

0 comments on commit d74b120

Please sign in to comment.