From 55dc29ed2a2beafb0ae0facfca5869e75715ac76 Mon Sep 17 00:00:00 2001
From: Jan-Hendrik Willms <tleilax+studip@gmail.com>
Date: Tue, 21 Mar 2023 09:08:37 +0000
Subject: [PATCH] enable attributes in Schema::getAttributes() to be defined as
 a callable for...

Closes #2406

Merge request studip/studip!1601
---
 .../JsonApi/JsonApiIntegration/Factory.php    |  9 ++++
 .../JsonApiIntegration/FieldsetFilter.php     | 45 +++++++++++++++++++
 2 files changed, 54 insertions(+)
 create mode 100644 lib/classes/JsonApi/JsonApiIntegration/FieldsetFilter.php

diff --git a/lib/classes/JsonApi/JsonApiIntegration/Factory.php b/lib/classes/JsonApi/JsonApiIntegration/Factory.php
index afdd4317a16..8cdc6e62580 100644
--- a/lib/classes/JsonApi/JsonApiIntegration/Factory.php
+++ b/lib/classes/JsonApi/JsonApiIntegration/Factory.php
@@ -4,6 +4,7 @@ namespace JsonApi\JsonApiIntegration;
 
 use Neomerx\JsonApi\Contracts\Parser\EditableContextInterface;
 use Neomerx\JsonApi\Contracts\Parser\ParserInterface;
+use Neomerx\JsonApi\Contracts\Representation\FieldSetFilterInterface;
 use Neomerx\JsonApi\Contracts\Schema\LinkInterface;
 use Neomerx\JsonApi\Contracts\Schema\SchemaContainerInterface;
 use Neomerx\JsonApi\Factories\Factory as NeomerxFactory;
@@ -22,6 +23,14 @@ use Neomerx\JsonApi\Schema\Link;
  */
 class Factory extends NeomerxFactory
 {
+    /**
+     * @inheritdoc
+     */
+    public function createFieldSetFilter(array $fieldSets): FieldSetFilterInterface
+    {
+        return new FieldsetFilter($fieldSets);
+    }
+
     /**
      * @inheritdoc
      */
diff --git a/lib/classes/JsonApi/JsonApiIntegration/FieldsetFilter.php b/lib/classes/JsonApi/JsonApiIntegration/FieldsetFilter.php
new file mode 100644
index 00000000000..42a5842edbe
--- /dev/null
+++ b/lib/classes/JsonApi/JsonApiIntegration/FieldsetFilter.php
@@ -0,0 +1,45 @@
+<?php
+namespace JsonApi\JsonApiIntegration;
+
+class FieldsetFilter extends \Neomerx\JsonApi\Representation\FieldSetFilter
+{
+    /**
+     * @param string   $type
+     * @param iterable $fields
+     *
+     * @return iterable
+     */
+    protected function filterFields(string $type, iterable $fields): iterable
+    {
+        if ($this->hasFilter($type) === false) {
+            foreach ($fields as $name => $value) {
+                yield $name => $this->resolveValue($value);
+            }
+
+            return;
+        }
+
+        $allowedFields = $this->getAllowedFields($type);
+        foreach ($fields as $name => $value) {
+            if (isset($allowedFields[$name]) === true) {
+                yield $name => $this->resolveValue($value);
+            }
+        }
+    }
+
+    /**
+     * Resolves a given by either calling it if it's a callable. Otherwise
+     * just return the value itself.
+     *
+     * @param mixed $value
+     * @return mixed
+     */
+    private function resolveValue($value)
+    {
+        if (is_callable($value)) {
+            return $value();
+        }
+
+        return $value;
+    }
+}
-- 
GitLab