From 5e4e0c8ec60d2f0d01ee0cc21a62f4f81377cf69 Mon Sep 17 00:00:00 2001
From: Devin <devin@blackhat.co.za>
Date: Fri, 12 Oct 2018 19:19:52 +0200
Subject: [PATCH] added resources for json api responses, moved some of the
 computations to soft attributes, moved the qrcode generation into the project
 model

---
 app/Http/Controllers/FundingController.php | 31 ++++++++++++----------
 app/Http/Resources/ProjectCollection.php   | 24 +++++++++++++++++
 app/Http/Resources/ProjectResource.php     | 25 +++++++++++++++++
 app/Project.php                            | 18 +++++++++++--
 resources/views/projects/index.blade.php   |  2 +-
 resources/views/projects/show.blade.php    |  6 ++---
 6 files changed, 86 insertions(+), 20 deletions(-)
 create mode 100644 app/Http/Resources/ProjectCollection.php
 create mode 100644 app/Http/Resources/ProjectResource.php

diff --git a/app/Http/Controllers/FundingController.php b/app/Http/Controllers/FundingController.php
index 7123b09..1ad7f0d 100644
--- a/app/Http/Controllers/FundingController.php
+++ b/app/Http/Controllers/FundingController.php
@@ -2,10 +2,9 @@
 
 namespace App\Http\Controllers;
 
-use App\Deposit;
+use App\Http\Resources\ProjectResource;
 use App\Project;
 use Illuminate\Http\Request;
-use Monero\Wallet;
 use SimpleSoftwareIO\QrCode\Facades\QrCode;
 
 class FundingController extends Controller
@@ -13,11 +12,17 @@ class FundingController extends Controller
     /**
      * Shows all projects
      *
-     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
+     * @param Request $request
+     * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\Resources\Json\AnonymousResourceCollection|\Illuminate\View\View
      */
-    public function index()
+    public function index(Request $request)
     {
-        $projects = Project::all();
+        $projects = Project::paginate(15);
+        // If the request has header `Accept: */json`, return JSON
+        if ($request->wantsJson())
+        {
+            return ProjectResource::collection($projects);
+        }
         return view('projects.index')
             ->with('projects', $projects);
     }
@@ -27,23 +32,21 @@ class FundingController extends Controller
      *
      * @param $paymentId
      *
-     * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory
+     * @return ProjectResource|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
      */
-    public function show($paymentId)
+    public function show(Request $request, $paymentId)
     {
         $project = Project::where('payment_id', $paymentId)->first();
         if (!$project) {
             abort(404);
         }
-        $contributions = $project->deposits->count();
-        $amountReceived = $project->deposits->sum('amount');
-        $percentage = round($amountReceived / $project->target_amount * 100);
+        if ($request->wantsJson())
+        {
+            return new ProjectResource($project);
+        }
         $qrcode = QrCode::format('png')->size(100)->generate($project->uri);
         return view('projects.show')
             ->with('project', $project)
-            ->with('contributions', $contributions)
-            ->with('percentage', $percentage)
-            ->with('qrcode', $qrcode)
-            ->with('amount_received', $amountReceived);
+            ->with('qrcode', $qrcode);
     }
 }
diff --git a/app/Http/Resources/ProjectCollection.php b/app/Http/Resources/ProjectCollection.php
new file mode 100644
index 0000000..756c505
--- /dev/null
+++ b/app/Http/Resources/ProjectCollection.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Resources\Json\ResourceCollection;
+
+class ProjectCollection extends ResourceCollection
+{
+    /**
+     * Transform the resource collection into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return array
+     */
+    public function toArray($request)
+    {
+        return [
+            'data' => $this->collection,
+            'links' => [
+                'self' => 'link-value',
+            ],
+        ];
+    }
+}
diff --git a/app/Http/Resources/ProjectResource.php b/app/Http/Resources/ProjectResource.php
new file mode 100644
index 0000000..7cfc552
--- /dev/null
+++ b/app/Http/Resources/ProjectResource.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace App\Http\Resources;
+
+use Illuminate\Http\Resources\Json\JsonResource;
+
+class ProjectResource extends JsonResource
+{
+    /**
+     * Transform the resource into an array.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @return array
+     */
+    public function toArray($request)
+    {
+        return [
+            'payment_id' => $this->payment_id,
+            'status' => $this->status,
+            'amount_received' => $this->amount_received,
+            'target_amount' => $this->target_amount,
+            'percentage_funded' => $this->percentage_funded,
+        ];
+    }
+}
diff --git a/app/Project.php b/app/Project.php
index 98a13ad..b0f718e 100644
--- a/app/Project.php
+++ b/app/Project.php
@@ -3,10 +3,10 @@
 namespace App;
 
 use Illuminate\Database\Eloquent\Model;
-use Monero\Wallet;
+use SimpleSoftwareIO\QrCode\Facades\QrCode;
 
 /**
- * App\Project
+ * App\ProjectResource
  *
  * @property int $id
  * @property string $payment_id
@@ -17,6 +17,8 @@ use Monero\Wallet;
  * @property-read \Illuminate\Database\Eloquent\Collection|\App\Deposit[] $deposits
  * @property-read mixed $amount_received
  * @property-read string $uri
+ * @property-read int $percentage_funded
+ * @property-read int $contributions
  * @method static \Illuminate\Database\Eloquent\Builder|\App\Project whereCreatedAt($value)
  * @method static \Illuminate\Database\Eloquent\Builder|\App\Project whereId($value)
  * @method static \Illuminate\Database\Eloquent\Builder|\App\Project wherePaymentId($value)
@@ -42,4 +44,16 @@ class Project extends Model
     public function getUriAttribute() {
         return 'monero:'.env('WALLET_ADDRESS').'tx_payment_id='.$this->payment_id;
     }
+
+    public function getPercentageFundedAttribute() {
+        return round($this->amount_received / $this->target_amount * 100);
+    }
+
+    public function getContributionsAttribute() {
+        return $this->deposits->count() ?? 0;
+    }
+
+    public function getQrCodeAttribute() {
+        return QrCode::format('png')->size(500)->generate($this->uri);
+    }
 }
diff --git a/resources/views/projects/index.blade.php b/resources/views/projects/index.blade.php
index 95e3433..4bab2b4 100644
--- a/resources/views/projects/index.blade.php
+++ b/resources/views/projects/index.blade.php
@@ -12,7 +12,7 @@
     <tr>
         <td><a href='{!! url('/projects/'.$project->payment_id); !!}'>{{ $project->payment_id }}</a></td>
         <td>{{$project->status}}</td>
-        <td>{{$project->amountReceived}} XMR</td>
+        <td>{{$project->amount_received}} XMR</td>
         <td>{{$project->target_amount}} XMR</td>
     </tr>
 @endforeach
diff --git a/resources/views/projects/show.blade.php b/resources/views/projects/show.blade.php
index 7a3dd12..be4036a 100644
--- a/resources/views/projects/show.blade.php
+++ b/resources/views/projects/show.blade.php
@@ -1,6 +1,6 @@
-XMR {{$amount_received}} /  XMR {{$project->target_amount}} Target
+XMR {{$project->amount_received}} /  XMR {{$project->target_amount}} Target
 
-{{$contributions}} contributions made.  {{$percentage}}%
+{{$project->contributions}} contributions made.  {{$project->percentage_funded}}%
 <br>
 
-{!! QrCode::size(400)->generate($project->uri); !!}
\ No newline at end of file
+<img src="data:image/png;base64,{!! base64_encode($project->qrcode) !!}">
\ No newline at end of file
-- 
GitLab