From 51337379678f344330bef866f13ce9caafc81bdf Mon Sep 17 00:00:00 2001
From: Kasper Garnaes <kasper.garnaes@gmail.com>
Date: Wed, 12 Oct 2016 09:40:22 +0200
Subject: [PATCH] Add support for caching of individual requests

Caching is added to the individual methods by using a wrapper around the
request method as we cannot determine cachability based on HTTP method.
---
 src/Apsis.php | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 50 insertions(+), 5 deletions(-)

diff --git a/src/Apsis.php b/src/Apsis.php
index 923bd35..58b1303 100644
--- a/src/Apsis.php
+++ b/src/Apsis.php
@@ -70,6 +70,51 @@ class Apsis {
     }
   }
 
+  /**
+   * Perform a cachable request against Apsis.
+   *
+   * If a cached response for the request already exists then that is used.
+   * If not then the an actual request will be performed and the response
+   * cached.
+   *
+   * @param string $method
+   *   The HTTP method to use.
+   * @param string $path
+   *   The endpoint path to use for the request.
+   * @param array $args
+   *   The HTTP request arguments.
+   *
+   * @return mixed
+   *   The response from Apsis.
+   */
+  protected function cachableRequest($method, $path, $args = []) {
+    $cid = 'apsis_mail:api:' . hash('sha256', var_export(func_get_args(), TRUE));
+
+    // First check static cache, to avoid unnecessary queries to cache backend.
+    $response = drupal_static($cid, NULL);
+    if ($response === NULL) {
+      // Then check the cache backend.
+      $cache = \Drupal::cache()->get($cid);
+      if ($cache !== FALSE) {
+        $response = $cache->data;
+      }
+    }
+
+    // If we do not have a cached response then perform the actual request.
+    if ($response === NULL) {
+      $response = $this->request($method, $path, $args);
+
+      // Make sure that static cache is set.
+      $static_cache = &drupal_static($cid, NULL);
+      $static_cache = $response;
+
+      // Cache results for 30 seconds.
+      \Drupal::cache()->set($cid, $response, REQUEST_TIME + 30);
+    }
+
+    return $response;
+  }
+
   /**
    * Get single mailing list.
    *
@@ -105,7 +150,7 @@ class Apsis {
     ];
 
     // Get request content.
-    $contents = $this->request($method, $path, $args);
+    $contents = $this->cachableRequest($method, $path, $args);
     // Populate array for settings.
     $list = [];
     if (!empty($contents)) {
@@ -131,7 +176,7 @@ class Apsis {
     ];
 
     // Get request content.
-    $contents = $this->request($method, $path, $args);
+    $contents = $this->cachableRequest($method, $path, $args);
 
     // Get result.
     $result = $contents->Result;
@@ -156,7 +201,7 @@ class Apsis {
     ];
 
     // @todo This REST method uses queueing, must figure out how to handle it.
-    $contents = $this->request($method, $path, $args);
+    $contents = $this->cachableRequest($method, $path, $args);
 
     return $contents;
   }
@@ -169,7 +214,7 @@ class Apsis {
     $method = 'get';
     $path = '/v1/subscribers/' . $id . '/mailinglists';
 
-    $contents = $this->request($method, $path);
+    $contents = $this->cachableRequest($method, $path);
 
     return $contents ? $contents->Result : NULL;
   }
@@ -189,7 +234,7 @@ class Apsis {
     ];
 
     // Do request.
-    $contents = $this->request($method, $path, $args);
+    $contents = $this->cachableRequest($method, $path, $args);
 
     return $contents ? $contents->Result : NULL;
   }
-- 
2.9.2+GitX