Skip to content

Commit

Permalink
Merge pull request #2581 from bolt/fix/more-relationship-fixes
Browse files Browse the repository at this point in the history
Fix relationships showing in backend, allow bidirectional deleting
  • Loading branch information
I-Valchev authored May 11, 2021
2 parents bb72c0a + c8dc8e1 commit 2733f3b
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 68 deletions.
2 changes: 1 addition & 1 deletion src/Controller/Backend/ContentEditController.php
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ private function updateTaxonomy(Content $content, string $key, $taxonomy): void
private function updateRelation(Content $content, $newRelations): array
{
$newRelations = (new Collection(Json::findArray($newRelations)))->filter();
$currentRelations = $this->relationRepository->findRelations($content, null, true, null, false);
$currentRelations = $this->relationRepository->findRelations($content, null, null, false);
$relationsResult = [];

// Remove old ones
Expand Down
41 changes: 9 additions & 32 deletions src/Repository/RelationRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,68 +24,45 @@ public function __construct(ManagerRegistry $registry)
parent::__construct($registry, Relation::class);
}

public function findRelations(Content $from, ?string $name, bool $biDirectional = false, ?int $limit = null, bool $publishedOnly = true): array
public function findRelations(Content $from, ?string $name, ?int $limit = null, bool $publishedOnly = true): array
{
// Only get existing Relations from content that was persisted before
if ($from->getId() === null) {
return [];
}

$result = $this->buildRelationQuery($from, $name, false, $publishedOnly)
return $this->buildRelationQuery($from, $name, $publishedOnly)
->setMaxResults($limit)
->getQuery()
->getResult();

if (empty($result) === true && $biDirectional === true) {
$result = $this->buildRelationQuery($from, $name, true, $publishedOnly)
->setMaxResults($limit)
->getQuery()
->getResult();
}

return $result;
}

public function findFirstRelation(Content $from, ?string $name, bool $biDirectional = false, bool $publishedOnly = true): ?Relation
public function findFirstRelation(Content $from, ?string $name, bool $publishedOnly = true): ?Relation
{
$result = $this->buildRelationQuery($from, $name, false, $publishedOnly)
return $this->buildRelationQuery($from, $name, $publishedOnly)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();

if ($result === null && $biDirectional === true) {
$result = $this->buildRelationQuery($from, $name, true, $publishedOnly)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
}

return $result;
}

private function buildRelationQuery(Content $from, ?string $name, bool $reversed = false, bool $publishedOnly = true): QueryBuilder
private function buildRelationQuery(Content $from, ?string $name, bool $publishedOnly = true): QueryBuilder
{
$qb = $this->createQueryBuilder('r')
->select('r, cfrom, cto')
->join('r.fromContent', 'cfrom')
->join('r.toContent', 'cto')
->orderBy('r.position', 'DESC');

if ($reversed === false) {
$qb->andWhere('r.fromContent = :from');
$cto = 'cto';
} else {
$qb->andWhere('r.toContent = :from');
$cto = 'cfrom';
}
$qb->andWhere('r.fromContent = :from OR r.toContent = :from');

if ($publishedOnly === true) {
$qb->andWhere($cto . '.status = :status')
$qb->andWhere('cto.status = :status')
->andWhere('cfrom.status = :status')
->setParameter('status', Statuses::PUBLISHED, \PDO::PARAM_STR);
}

if ($name !== null) {
$qb->andWhere($cto . '.contentType = :name')
$qb->andWhere('cto.contentType = :name OR cfrom.contentType = :name')
->setParameter('name', $name, \PDO::PARAM_STR);
}

Expand Down
31 changes: 4 additions & 27 deletions src/Twig/RelatedExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function getRelatedContentByType(Content $content, bool $bidirectional =
return [];
}

$relations = $this->relationRepository->findRelations($content, null, $bidirectional, $limit, $publishedOnly);
$relations = $this->relationRepository->findRelations($content, null, $limit, $publishedOnly);

return (new Collection($relations))
->reduce(function (array $result, Relation $relation) use ($content): array {
Expand All @@ -105,7 +105,7 @@ public function getRelatedContent($content, ?string $name = null, bool $bidirect
return [];
}

$relations = $this->relationRepository->findRelations($content, $name, $bidirectional, $limit, $publishedOnly);
$relations = $this->relationRepository->findRelations($content, $name, $limit, $publishedOnly);

return (new Collection($relations))
->map(function (Relation $relation) use ($content) {
Expand All @@ -115,13 +115,13 @@ public function getRelatedContent($content, ?string $name = null, bool $bidirect
->toArray();
}

public function getFirstRelatedContent($content, ?string $name = null, bool $bidirectional = true, bool $publishedOnly = true): ?Content
public function getFirstRelatedContent($content, ?string $name = null, bool $publishedOnly = true): ?Content
{
if (! $this->checkforContent($content, 'related_first')) {
return null;
}

$relation = $this->relationRepository->findFirstRelation($content, $name, $bidirectional, $publishedOnly);
$relation = $this->relationRepository->findFirstRelation($content, $name, $publishedOnly);

if ($relation === null) {
return null;
Expand Down Expand Up @@ -202,29 +202,6 @@ public function getRelatedValues(Content $source, string $contentType): Collecti
return new Collection($values);
}

/**
* Gets relations from this content via the content variable, and not via a doctrine query
*/
public function getRelatedValuesFromContent(Content $source, string $contentType): Collection
{
if (! $this->checkforContent($source, 'related_values')) {
return new Collection([]);
}

if ($source->getId() === null) {
return new Collection([]);
}

return new Collection($source->getRelationsFromThisContent()
->filter(function (Relation $relation) use ($contentType) {
return $relation->getToContent()->getContentType() === $contentType;
})->map(function (Relation $relation) {
$toContent = $relation->getToContent();

return $toContent->getId();
})->getValues());
}

private function checkforContent($content, string $keyword): bool
{
if (! $content instanceof Content) {
Expand Down
3 changes: 1 addition & 2 deletions templates/content/_relationships.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
{% for contentType, relation in record.definition.relations %}

{% set options = related_options(contentType, relation.order|default(), relation.format|default(), relation.required) %}
{# {% set value = record|related_values(contentType) %}#}
{% set value = record|related_values_from_content(contentType) %}
{% set value = record|related_values(contentType) %}

<div class="form-group is-normal">

Expand Down
12 changes: 6 additions & 6 deletions tests/spec/Bolt/Twig/RelatedExtensionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function let(RelationRepository $relationRepository, ContentRepository $c

public function it_gets_all_related_content(Content $content, RelationRepository $relationRepository, Relation $relation, Content $related): void
{
$relationRepository->findRelations($content, null, true, null, true)
$relationRepository->findRelations($content, null, null, true)
->shouldBeCalledOnce()
->willReturn([$relation, $relation]);

Expand All @@ -44,7 +44,7 @@ public function it_gets_all_related_content(Content $content, RelationRepository

public function it_gets_related_content(Content $content, RelationRepository $relationRepository, Relation $relation, Content $related): void
{
$relationRepository->findRelations($content, self::TEST_CT_SLUG, true, null, true)
$relationRepository->findRelations($content, self::TEST_CT_SLUG, null, true)
->shouldBeCalledOnce()
->willReturn([$relation]);

Expand All @@ -60,7 +60,7 @@ public function it_gets_related_content(Content $content, RelationRepository $re

public function it_gets_related_content_unidirectional_with_limit(Content $content, RelationRepository $relationRepository, Relation $relation, Content $related): void
{
$relationRepository->findRelations($content, self::TEST_CT_SLUG, false, 3, true)
$relationRepository->findRelations($content, self::TEST_CT_SLUG, 3, true)
->shouldBeCalledOnce()
->willReturn([$relation, $relation, $relation]);

Expand All @@ -77,7 +77,7 @@ public function it_gets_related_content_unidirectional_with_limit(Content $conte

public function it_gets_first_related_content(Content $content, RelationRepository $relationRepository, Relation $relation, Content $related): void
{
$relationRepository->findFirstRelation($content, self::TEST_CT_SLUG, true, true)
$relationRepository->findFirstRelation($content, self::TEST_CT_SLUG, true)
->shouldBeCalledOnce()
->willReturn($relation);

Expand All @@ -92,15 +92,15 @@ public function it_gets_first_related_content(Content $content, RelationReposito

public function it_couldnt_find_related_content(Content $content, RelationRepository $relationRepository): void
{
$relationRepository->findRelations($content, null, true, null, true)->willReturn([]);
$relationRepository->findRelations($content, null, null, true)->willReturn([]);
$result = $this->getRelatedContent($content);
$result->shouldBeArray();
$result->shouldHaveCount(0);
}

public function it_couldnt_find_first_related_content(Content $content, RelationRepository $relationRepository): void
{
$relationRepository->findFirstRelation($content, null, true, true)->willReturn(null);
$relationRepository->findFirstRelation($content, null, true)->willReturn(null);
$result = $this->getFirstRelatedContent($content);
$result->shouldBeNull();
}
Expand Down

0 comments on commit 2733f3b

Please sign in to comment.