/** * Parse input structure. * * @param array $data * @param \eZ\Publish\Core\REST\Common\Input\ParsingDispatcher $parsingDispatcher * * @return \Netgen\TagsBundle\API\Repository\Values\Tags\TagCreateStruct */ public function parse(array $data, ParsingDispatcher $parsingDispatcher) { if (!array_key_exists('ParentTag', $data) || !is_array($data['ParentTag'])) { throw new Exceptions\Parser("Missing or invalid 'ParentTag' element for TagCreate."); } if (!array_key_exists('_href', $data['ParentTag'])) { throw new Exceptions\Parser("Missing '_href' attribute for ParentTag element in TagCreate."); } if (!array_key_exists('mainLanguageCode', $data)) { throw new Exceptions\Parser("Missing 'mainLanguageCode' element for TagCreate."); } $tagHrefParts = explode('/', $this->requestParser->parseHref($data['ParentTag']['_href'], 'tagPath')); $tagCreateStruct = $this->tagsService->newTagCreateStruct(array_pop($tagHrefParts), $data['mainLanguageCode']); if (array_key_exists('remoteId', $data)) { $tagCreateStruct->remoteId = $data['remoteId']; } if (array_key_exists('alwaysAvailable', $data)) { $tagCreateStruct->alwaysAvailable = $this->parserTools->parseBooleanValue($data['alwaysAvailable']); } if (array_key_exists('names', $data)) { if (!is_array($data['names']) || !array_key_exists('value', $data['names']) || !is_array($data['names']['value'])) { throw new Exceptions\Parser("Invalid 'names' element for TagCreate."); } $keywords = $this->parserTools->parseTranslatableList($data['names']); foreach ($keywords as $languageCode => $keyword) { $tagCreateStruct->setKeyword($keyword, $languageCode); } } return $tagCreateStruct; }
/** * Builds the View based on $parameters. * * @param array $parameters * * @throws \eZ\Publish\Core\Base\Exceptions\InvalidArgumentException If the tag cannot be loaded * * @return \eZ\Publish\Core\MVC\Symfony\View\View An implementation of the View interface */ public function buildView(array $parameters) { $view = new TagView(); if (!empty($parameters['viewType'])) { $view->setViewType($parameters['viewType']); } if (isset($parameters['tagId'])) { $view->setTag($this->tagsService->loadTag($parameters['tagId'])); } elseif (isset($parameters['tag']) && $parameters['tag'] instanceof Tag) { $view->setTag($parameters['tag']); } else { throw new InvalidArgumentException('Tag', 'No tag could be loaded from parameters'); } $this->viewConfigurator->configure($view); // Deprecated controller actions are replaced with their new equivalent, viewAction if (!$view->getControllerReference() instanceof ControllerReference) { if ($parameters['_controller'] === 'eztags.controller.tag_view:viewTag') { $view->setControllerReference(new ControllerReference('eztags.controller.tag_view:viewAction')); } // We want to have a default template for full tag view if ($view->getViewType() === 'full' && $view->getTemplateIdentifier() === null) { $view->setTemplateIdentifier($this->configResolver->getParameter('tag_view.template', 'eztags')); } } $this->viewParametersInjector->injectViewParameters($view, $parameters); return $view; }
/** * Returns the field type under test. * * @return \Netgen\TagsBundle\Core\FieldType\Tags\Type */ protected function createFieldTypeUnderTest() { $this->tagsService = $this->getMock('Netgen\\TagsBundle\\API\\Repository\\TagsService'); $this->tagsService->expects($this->any())->method('loadTag')->will($this->returnCallback(array($this, 'getTagsServiceLoadTagValues'))); $tagsType = new TagsType($this->tagsService); $tagsType->setEditViews(array('default' => array('identifier' => 'Default'), 'select' => array('identifier' => 'Select'))); return $tagsType; }
/** * Returns an slice of the results. * * @param int $offset The offset. * @param int $length The length. * * @return \eZ\Publish\API\Repository\Values\Content\Content[] */ public function getSlice($offset, $length) { $relatedContent = $this->tagsService->getRelatedContent($this->tag, $offset, $length); if (!isset($this->nbResults)) { $this->nbResults = $this->tagsService->getRelatedContentCount($this->tag); } return $relatedContent; }
/** * Returns tag keyword for provided tag ID or tag object. * * @param mixed|\Netgen\TagsBundle\API\Repository\Values\Tags\Tag $tag * * @return string */ public function getTagKeyword($tag) { if (!$tag instanceof Tag) { try { $tag = $this->tagsService->loadTag($tag); } catch (NotFoundException $e) { return ''; } } return $this->translationHelper->getTranslatedByMethod($tag, 'getKeyword'); }
/** * @covers \Netgen\TagsBundle\Core\Pagination\Pagerfanta\RelatedContentAdapter::testGetSlice */ public function testGetSlice() { $offset = 2; $limit = 2; $nbResults = 5; $tag = new Tag(array('id' => 42)); $relatedContent = array(new Content(array('internalFields' => array())), new Content(array('internalFields' => array()))); $this->tagsService->expects($this->once())->method('getRelatedContentCount')->with($this->equalTo($tag))->will($this->returnValue($nbResults)); $this->tagsService->expects($this->once())->method('getRelatedContent')->with($this->equalTo($tag), $this->equalTo($offset), $this->equalTo($limit))->will($this->returnValue($relatedContent)); $adapter = $this->getAdapter($tag, $this->tagsService); $this->assertSame($relatedContent, $adapter->getSlice($offset, $limit)); $this->assertSame($nbResults, $adapter->getNbResults()); }
/** * Generates the URL from $tag and $parameters. * Entries in $parameters will be added in the query string. * * @param \Netgen\TagsBundle\API\Repository\Values\Tags\Tag $tag * @param array $parameters * * @return string */ public function doGenerate($tag, array $parameters) { if (isset($parameters['siteaccess'])) { // We generate for a different siteaccess, so potentially in a different language. $languages = $this->configResolver->getParameter('languages', null, $parameters['siteaccess']); unset($parameters['siteaccess']); } else { $languages = $this->configResolver->getParameter('languages'); } $tagUrl = ''; $isInternal = false; $originalTagId = $tagId = $tag->id; try { do { $tag = $this->tagsService->loadTag($tagId, $languages); $tagKeyword = null; foreach ($languages as $language) { $tagKeyword = $tag->getKeyword($language); if (!empty($tagKeyword)) { break; } } if (empty($tagKeyword)) { if ($tag->alwaysAvailable) { $tagKeyword = $tag->getKeyword(); } if (empty($tagKeyword)) { throw new LogicException("Unknown error when generating URL for tag ID #{$originalTagId}"); } } $tagUrl = '/' . $tagKeyword . $tagUrl; $tagId = $tag->parentTagId; } while ($tagId > 0); } catch (NotFoundException $e) { $isInternal = true; $tagUrl = $this->defaultRouter->generate(self::INTERNAL_TAG_ROUTE, array('tagId' => $originalTagId)); } catch (LogicException $e) { if ($this->logger !== null) { $this->logger->warning($e->getMessage()); } $isInternal = true; $tagUrl = $this->defaultRouter->generate(self::INTERNAL_TAG_ROUTE, array('tagId' => $originalTagId)); } $queryString = ''; if (!empty($parameters)) { $queryString = '?' . http_build_query($parameters, '', '&'); } return (!$isInternal ? $this->getPathPrefix() : '') . '/' . trim($tagUrl, '/') . $queryString; }
/** * @covers \Netgen\TagsBundle\Core\SignalSlot\TagsService::newTagUpdateStruct */ public function testNewTagUpdateStruct() { $this->tagsService->expects($this->once())->method('newTagUpdateStruct')->will($this->returnValue(new TagUpdateStruct())); $signalSlotService = $this->getSignalSlotService(); $tagUpdateStruct = $signalSlotService->newTagUpdateStruct(); $this->assertInstanceOf('Netgen\\TagsBundle\\API\\Repository\\Values\\Tags\\TagUpdateStruct', $tagUpdateStruct); }
/** * Validates the fieldSettings of a FieldDefinitionCreateStruct or FieldDefinitionUpdateStruct. * * @param mixed $fieldSettings * * @return \eZ\Publish\SPI\FieldType\ValidationError[] */ public function validateFieldSettings($fieldSettings) { $validationErrors = array(); if (!is_array($fieldSettings)) { $validationErrors[] = new ValidationError('Field settings must be in form of an array'); return $validationErrors; } foreach ($fieldSettings as $name => $value) { if (!isset($this->settingsSchema[$name])) { $validationErrors[] = new ValidationError("Setting '%setting%' is unknown", null, array('setting' => $name)); continue; } switch ($name) { case 'subTreeLimit': if (!is_integer($value)) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be of integer type", null, array('setting' => $name)); } if ($value < 0) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be equal or larger than 0", null, array('setting' => $name)); } if ($value > 0) { try { $this->tagsService->loadTag($value); } catch (NotFoundException $e) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be an existing tag ID", null, array('setting' => $name)); } } break; case 'hideRootTag': if (!is_bool($value)) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be of boolean type", null, array('setting' => $name)); } break; case 'maxTags': if (!is_integer($value)) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be of integer type", null, array('setting' => $name)); } if ($value < 0) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be equal or larger than 0", null, array('setting' => $name)); } break; case 'editView': if (!is_string($value)) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be of string type", null, array('setting' => $name)); } $editViewExists = false; foreach ($this->availableEditViews as $editView) { if ($editView['identifier'] === $value) { $editViewExists = true; break; } } if (!$editViewExists) { $validationErrors[] = new ValidationError("Edit view '%editView%' does not exist", null, array('editView' => $value)); } break; } } return $validationErrors; }
/** * @covers \Netgen\TagsBundle\Core\Pagination\Pagerfanta\RelatedContentAdapter::__construct * @covers \Netgen\TagsBundle\Core\Pagination\Pagerfanta\RelatedContentAdapter::setTag * @covers \Netgen\TagsBundle\Core\Pagination\Pagerfanta\RelatedContentAdapter::getSlice */ public function testGetSliceWithoutTag() { $this->tagsService->expects($this->never())->method('getRelatedContentCount'); $this->tagsService->expects($this->never())->method('getRelatedContent'); $adapter = new RelatedContentAdapter($this->tagsService); $this->assertSame(array(), $adapter->getSlice(2, 2)); }
/** * @covers \Netgen\TagsBundle\Core\SignalSlot\TagsService::sudo */ public function testSudo() { $callback = function () { }; $this->tagsService->expects($this->once())->method('sudo')->will($this->returnValue('some_value')); $signalSlotService = $this->getSignalSlotService(); $value = $signalSlotService->sudo($callback); $this->assertEquals('some_value', $value); }
/** * Parse input structure. * * @param array $data * @param \eZ\Publish\Core\REST\Common\Input\ParsingDispatcher $parsingDispatcher * * @return \Netgen\TagsBundle\API\Repository\Values\Tags\SynonymCreateStruct */ public function parse(array $data, ParsingDispatcher $parsingDispatcher) { if (!array_key_exists('mainLanguageCode', $data)) { throw new Exceptions\Parser("Missing 'mainLanguageCode' element for SynonymCreate."); } $synonymCreateStruct = $this->tagsService->newSynonymCreateStruct(null, $data['mainLanguageCode']); if (array_key_exists('remoteId', $data)) { $synonymCreateStruct->remoteId = $data['remoteId']; } if (array_key_exists('alwaysAvailable', $data)) { $synonymCreateStruct->alwaysAvailable = $this->parserTools->parseBooleanValue($data['alwaysAvailable']); } if (array_key_exists('names', $data)) { if (!is_array($data['names']) || !array_key_exists('value', $data['names']) || !is_array($data['names']['value'])) { throw new Exceptions\Parser("Invalid 'names' element for SynonymCreate."); } $keywords = $this->parserTools->parseTranslatableList($data['names']); foreach ($keywords as $languageCode => $keyword) { $synonymCreateStruct->setKeyword($keyword, $languageCode); } } return $synonymCreateStruct; }
/** * Validates the fieldSettings of a FieldDefinitionCreateStruct or FieldDefinitionUpdateStruct. * * @param mixed $fieldSettings * * @return \eZ\Publish\SPI\FieldType\ValidationError[] */ public function validateFieldSettings($fieldSettings) { $validationErrors = array(); if (!is_array($fieldSettings)) { $validationErrors[] = new ValidationError('Field settings must be in form of an array'); return $validationErrors; } foreach ($fieldSettings as $name => $value) { if (!isset($this->settingsSchema[$name])) { $validationErrors[] = new ValidationError("Setting '%setting%' is unknown", null, array('setting' => $name)); continue; } switch ($name) { case 'subTreeLimit': if (!is_integer($value)) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be of integer type", null, array('setting' => $name)); } if ($value < 0) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be equal or larger than 0", null, array('setting' => $name)); } if ($value > 0) { try { $this->tagsService->loadTag($value); } catch (NotFoundException $e) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be an existing tag ID", null, array('setting' => $name)); } } break; case 'showDropDown': if (!is_bool($value)) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be of boolean type", null, array('setting' => $name)); } break; case 'hideRootTag': if (!is_bool($value)) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be of boolean type", null, array('setting' => $name)); } break; case 'maxTags': if (!is_integer($value)) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be of integer type", null, array('setting' => $name)); } if ($value < 0) { $validationErrors[] = new ValidationError("Setting '%setting%' value must be equal or larger than 0", null, array('setting' => $name)); } break; } } return $validationErrors; }
/** * Generates a URL for a tag, from the given parameters. * * It is possible to directly pass a Tag object as the route name, as the ChainRouter allows it through ChainedRouterInterface * * If $name is a route name, the "tag" key in $parameters must be set to a valid Netgen\TagsBundle\API\Repository\Values\Tags\Tag object. * "tagId" can also be provided. * * If the generator is not able to generate the URL, it must throw the RouteNotFoundException as documented below. * * @param string|\Netgen\TagsBundle\API\Repository\Values\Tags\Tag $name The name of the route or a Tag instance * @param mixed $parameters An array of parameters * @param bool $absolute Whether to generate an absolute URL * * @throws \LogicException * @throws \Symfony\Component\Routing\Exception\RouteNotFoundException * @throws \InvalidArgumentException * * @return string The generated URL */ public function generate($name, $parameters = array(), $absolute = false) { // Direct access to Tag if ($name instanceof Tag) { return $this->generator->generate($name, $parameters, $absolute); } // Normal route name if ($name === self::TAG_URL_ROUTE_NAME) { if (isset($parameters['tag']) || isset($parameters['tagId'])) { // Check if tag is a valid Tag object if (isset($parameters['tag']) && !$parameters['tag'] instanceof Tag) { throw new LogicException("When generating a Tag route, 'tag' parameter must be a valid Netgen\\TagsBundle\\API\\Repository\\Values\\Tags\\Tag."); } $tag = isset($parameters['tag']) ? $parameters['tag'] : $this->tagsService->loadTag($parameters['tagId']); unset($parameters['tag'], $parameters['tagId'], $parameters['viewType'], $parameters['layout']); return $this->generator->generate($tag, $parameters, $absolute); } throw new InvalidArgumentException("When generating a Tag route, either 'tag' or 'tagId' must be provided."); } throw new RouteNotFoundException('Could not match route'); }
/** * Allows tags API execution to be performed with full access sand-boxed. * * The closure sandbox will do a catch all on exceptions and rethrow after * re-setting the sudo flag. * * Example use: * $tag = $tagsService->sudo( * function ( TagsService $tagsService ) use ( $tagId ) * { * return $tagsService->loadTag( $tagId ); * } * ); * * @param \Closure $callback * * @throws \RuntimeException Thrown on recursive sudo() use. * @throws \Exception Re throws exceptions thrown inside $callback * * @return mixed */ public function sudo(Closure $callback) { return $this->service->sudo($callback, $this); }
/** * Deletes a tag. * * @param string $tagPath * * @return \eZ\Publish\Core\REST\Server\Values\NoContent */ public function deleteTag($tagPath) { $tag = $this->tagsService->loadTag($this->extractTagIdFromPath($tagPath)); $this->tagsService->deleteTag($tag); return new BaseValues\NoContent(); }
/** * Instantiates a new tag update struct. * * @return \Netgen\TagsBundle\API\Repository\Values\Tags\TagUpdateStruct */ public function newTagUpdateStruct() { return $this->service->newTagUpdateStruct(); }
/** * @expectedException \eZ\Publish\API\Repository\Exceptions\UnauthorizedException * * @covers \Netgen\TagsBundle\Core\Repository\TagsService::deleteTag */ public function testDeleteTagThrowsUnauthorizedExceptionForSynonym() { $this->repository->setCurrentUser($this->getStubbedUser(10)); $this->tagsService->deleteTag(new Tag(array('id' => 95))); }
/** * Action for rendering a tag view. * * @param mixed $tagId * @param \Symfony\Component\HttpFoundation\Request $request * * @return \Symfony\Component\HttpFoundation\Response */ public function viewTag($tagId, Request $request) { $tag = $this->tagsService->loadTag($tagId); return $this->renderTag($tag, $request); }
/** * Returns the field type under test. * * @return \Netgen\TagsBundle\Core\FieldType\Tags\Type */ protected function createFieldTypeUnderTest() { $this->tagsService = $this->getMock('Netgen\\TagsBundle\\API\\Repository\\TagsService'); $this->tagsService->expects($this->any())->method('loadTag')->will($this->returnCallback(array($this, 'getTagsServiceLoadTagValues'))); return new TagsType($this->tagsService); }