From ddab5c7b7b5c12a7a23ce567051bddbe7194a872 Mon Sep 17 00:00:00 2001
From: Agustin Moyano <agustinmoyano@theke.io>
Date: Fri, 9 Oct 2020 09:59:41 -0300
Subject: [PATCH] Bug 26635: Expand authorised values in to_api method

This patch adds the posibility to expand authorised values when to_api
method is called.

The classes where authorised values should expand must implememnt the
_fetch_authorised_values method, and must return a hash like the
following

{
  column_name => Koha::AuthorisedValue->unblessed
  ...
}

This patch will be used in bug 8179, so please test there.

Sponsored-by: Virginia Polytechnic Institute and State University

Signed-off-by: Andrew Fuerste-Henry <andrew@bywatersolutions.com>
---
 Koha/Object.pm              | 69 ++++++++++++++++++++++++-------------
 Koha/REST/Plugin/Objects.pm | 11 +++---
 2 files changed, 53 insertions(+), 27 deletions(-)

diff --git a/Koha/Object.pm b/Koha/Object.pm
index 57b1429b89..eeffb842f5 100644
--- a/Koha/Object.pm
+++ b/Koha/Object.pm
@@ -552,28 +552,10 @@ sub to_api {
     my ( $self, $params ) = @_;
     my $json_object = $self->TO_JSON;
 
-    my $to_api_mapping = $self->to_api_mapping;
-
-    # Rename attributes if there's a mapping
-    if ( $self->can('to_api_mapping') ) {
-        foreach my $column ( keys %{ $self->to_api_mapping } ) {
-            my $mapped_column = $self->to_api_mapping->{$column};
-            if ( exists $json_object->{$column}
-                && defined $mapped_column )
-            {
-                # key != undef
-                $json_object->{$mapped_column} = delete $json_object->{$column};
-            }
-            elsif ( exists $json_object->{$column}
-                && !defined $mapped_column )
-            {
-                # key == undef
-                delete $json_object->{$column};
-            }
-        }
-    }
+    $json_object = $self->_do_api_mapping($json_object);
 
     my $embeds = $params->{embed};
+    my $av_expand = $params->{av_expand};
 
     if ($embeds) {
         foreach my $embed ( keys %{$embeds} ) {
@@ -592,20 +574,60 @@ sub to_api {
                 if ( defined $children and ref($children) eq 'ARRAY' ) {
                     my @list = map {
                         $self->_handle_to_api_child(
-                            { child => $_, next => $next, curr => $curr } )
+                            { child => $_, next => $next, curr => $curr, av_expand => $av_expand } )
                     } @{$children};
                     $json_object->{$curr} = \@list;
                 }
                 else {
                     $json_object->{$curr} = $self->_handle_to_api_child(
-                        { child => $children, next => $next, curr => $curr } );
+                        { child => $children, next => $next, curr => $curr, av_expand => $av_expand } );
                 }
             }
         }
     }
 
+    if($av_expand && $self->can('_fetch_authorised_values')) {
+        # _fetch_authorised_values should return a hash as the following
+        # {
+        #  column_name => <authorised_value>->unblessed
+        #  ...
+        # }
+        my $avs = $self->_fetch_authorised_values($av_expand);
+
+        # Language selection will be implemented when lang overlay for av is ready
+        # Now we will just fetch plain authorised values from the Koha::AuthorisedValues
+        $avs = $self->_do_api_mapping($avs);
+
+        $json_object->{_authorised_values} = $avs || {};
+    }
+
+    return $json_object;
+}
+
+=head3 _do_api_mapping
 
+=cut
 
+sub _do_api_mapping {
+    my ($self, $json_object) = @_;
+    # Rename attributes if there's a mapping
+    if ( $self->can('to_api_mapping') ) {
+        foreach my $column ( keys %{ $self->to_api_mapping } ) {
+            my $mapped_column = $self->to_api_mapping->{$column};
+            if ( exists $json_object->{$column}
+                && defined $mapped_column )
+            {
+                # key != undef
+                $json_object->{$mapped_column} = delete $json_object->{$column};
+            }
+            elsif ( exists $json_object->{$column}
+                && !defined $mapped_column )
+            {
+                # key == undef
+                delete $json_object->{$column};
+            }
+        }
+    }
     return $json_object;
 }
 
@@ -853,6 +875,7 @@ sub _handle_to_api_child {
     my $child = $args->{child};
     my $next  = $args->{next};
     my $curr  = $args->{curr};
+    my $av_expand = $args->{av_expand};
 
     my $res;
 
@@ -862,7 +885,7 @@ sub _handle_to_api_child {
             if defined $next and blessed $child and !$child->can('to_api');
 
         if ( blessed $child ) {
-            $res = $child->to_api({ embed => $next });
+            $res = $child->to_api({ embed => $next, av_expand => $av_expand });
         }
         else {
             $res = $child;
diff --git a/Koha/REST/Plugin/Objects.pm b/Koha/REST/Plugin/Objects.pm
index 7ccc1c4cf4..b68c8505bd 100644
--- a/Koha/REST/Plugin/Objects.pm
+++ b/Koha/REST/Plugin/Objects.pm
@@ -53,7 +53,9 @@ the requested object. It passes through any embeds if specified.
             my $attributes = {};
 
             # Look for embeds
-            my $embed = $c->stash('koha.embed');
+            my $embed     = $c->stash('koha.embed');
+            my $av_expand = $c->req->headers->header('x-koha-av-expand');
+
             # Generate prefetches for embedded stuff
             $c->dbic_merge_prefetch(
                 {
@@ -66,7 +68,7 @@ the requested object. It passes through any embeds if specified.
 
             return unless $object;
 
-            return $object->to_api({ embed => $embed });
+            return $object->to_api({ embed => $embed, av_expand => $av_expand });
         }
     );
 
@@ -92,7 +94,8 @@ for API rendering.
             # Extract reserved params
             my ( $filtered_params, $reserved_params, $path_params ) = $c->extract_reserved_params($args);
             # Look for embeds
-            my $embed = $c->stash('koha.embed');
+            my $embed     = $c->stash('koha.embed');
+            my $av_expand = $c->req->headers->header('x-koha-av-expand');
 
             # Merge sorting into query attributes
             $c->dbic_merge_sorting(
@@ -162,7 +165,7 @@ for API rendering.
                 }
             );
 
-            return $objects->to_api({ embed => $embed });
+            return $objects->to_api({ embed => $embed, av_expand => $av_expand });
         }
     );
 }
-- 
2.25.0