Last active
January 5, 2017 17:34
-
-
Save phillipsharring/36396b49b3dd612846aa517f9e6d734a to your computer and use it in GitHub Desktop.
A function swapping back and forth between collections and arrays that I'm sure could be refactored #laravel #collections
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@extends('layouts.app') | |
@section('content') | |
<!-- a bunch of other blade/html... --> | |
<!-- placeholder for the chart --> | |
<div class="col-xs-6"> | |
<h3>Technology Focus</h3> | |
<canvas id="myChart2" style="width: 400px; height: 200px;"></canvas> | |
</div> | |
<!-- more blade/html --> | |
@endsection | |
@section('js-foot') | |
<script type="text/javascript"> | |
// other scripts | |
var ctx2 = document.getElementById("myChart2"); | |
// we're using this with chart js | |
var myChart2 = new Chart(ctx2, { | |
type: 'pie', | |
data: { | |
// the keys for $technologyFocus are here, as the labels | |
// this becomes [ "Technology", "Another Technology", "Others Below 7%" ], | |
labels: [ "{!! $technologyFocus->keys()->implode('","') !!}" ], | |
datasets: [ | |
{ | |
// the values for $technologyfocus are here, as the data | |
// this becomes [ 1500, 1489, 400 ], | |
data: [ {{ $technologyFocus->values()->implode(',')}} ], | |
backgroundColor: [ | |
<?php | |
// a lame random RGB color function I found and modified | |
$colors = $technologyFocus->map(function(){ | |
$color = function() { | |
return str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT); | |
}; | |
$rgb = function() use($color) { | |
return $color() . $color() . $color(); | |
}; | |
return '#' . $rgb(); | |
}); | |
echo '"' . $colors->implode('","') . '"'; | |
?> | |
] | |
}] | |
}, | |
options: { | |
scales: { | |
yAxes: [{ | |
ticks: { | |
beginAtZero: true | |
} | |
}] | |
} | |
} | |
}); | |
</script> | |
@endsection |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Controllers; | |
use Illuminate\Support\Facades\Auth; | |
use App\Services\ReportService; | |
use App\Models\User; | |
class LearnerProfileController extends Controller | |
{ | |
// route is /learner-profile/{userId} where userId is optional. | |
// we get auth::user if it's null | |
public function index($userId = null) | |
{ | |
$user = (null == $userId) | |
? Auth::user() | |
: User::find($userId); | |
// get the service in ReportService.php | |
$reportService = new ReportService(); | |
// a bunch of other reports grabbed here... | |
$technologyFocus = $reportService->getTechnologyFocus($user->id); | |
return view('learner-profile.index', compact( | |
'user', | |
// the other report results. | |
'technologyFocus' | |
)); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// ReportService.php | |
namespace App\Services; | |
// various use statements go here | |
class ReportService | |
{ | |
// other methods... | |
/** | |
* @param integer $userId | |
* | |
* @return Collection; | |
*/ | |
public function getTechnologyFocus($userId) | |
{ | |
// get all the reported events from reporting table | |
$views = Report::where('report', 'content-titles-viewed') | |
->where('user_id', $userId) | |
->get(); | |
// reportable_type & reportable_id are a polymorphic relationship | |
// reportable_id in this case is a Catalog_title id (yes, the model naming is messed up) | |
$titleIds = $views->pluck('reportable_id')->unique(); | |
// query for the technology names and counts | |
$technologies = Catalog_titles_lov_product_technologies::select(DB::raw('COUNT(*) AS `total`'), 'lov_product_technologies.name') | |
->join('lov_product_technologies', 'catalog_titles_lov_product_technologies.lov_product_technology_id', '=', 'lov_product_technologies.id') | |
->whereIn('catalog_titles_lov_product_technologies.catalog_title_id', $titleIds->toArray()) | |
->where('lov_product_technologies.name', '!=', '') | |
->whereNotNull('lov_product_technologies.name') | |
->groupBy('lov_product_technologies.name') | |
->orderBy('total', 'DESC') | |
->get(); | |
$percentage = 7; | |
$total = $technologies->sum('total'); | |
$threshold = floor($total * ($percentage * .01)); | |
// get counts above the threshold | |
$counts = $technologies->filter(function($item) use ($threshold) | |
{ | |
return ($threshold < $item['total']); | |
})->toArray(); | |
// right above here ^^^ I'm making this into an array because | |
// a) I don't need all of the Report objects, just selected values | |
// b) I want to append to it later | |
// find all the "others" below the threshold, then sum them to a single number | |
$othersTotal = $technologies->filter(function($item) use ($threshold) | |
{ | |
return ($threshold >= $item['total']); | |
})->reduce(function($carry, $item) | |
{ | |
return $carry + $item['total']; | |
}); | |
// append the "others" count to the $counts array | |
$counts[] = [ | |
'total' => $othersTotal, | |
'name' => 'Others (Below ' . $percentage . '%)', | |
]; | |
$result = []; | |
// make the result a key => value array (name => total) | |
collect($counts)->map(function($item) use (&$result) | |
{ | |
$result[$item['name']] = $item['total']; | |
}); | |
// this too ^^^ seems like something that could be done more smoothly. | |
// is there a better way to make $counts into a key => value array? | |
/* | |
// output | |
// $result is like this now... | |
[ | |
"Technology" => 1500, | |
"Another Technology" => 1489, | |
// ... etc. | |
"Others Below 7%" => 400, | |
]; | |
// */ | |
return collect($result); | |
} | |
// other methods | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
$technologies query output
Collection {#2916 ▼
#items: array:28 [▼
0 => Catalog_titles_lov_product_technologies {#2915 ▼
#table: "catalog_titles_lov_product_technologies"
#connection: null
#primaryKey: "id"
#keyType: "int"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:2 [▼
"total" => 472
"name" => "Technology 1"
]
#original: array:2 [▶]
#relations: []
#hidden: []
#visible: []
#appends: []
#fillable: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
+exists: true
+wasRecentlyCreated: false
}
1 => Catalog_titles_lov_product_technologies {#2914 ▶}
2 => Catalog_titles_lov_product_technologies {#2913 ▶}
etc.
$result should be something like
Collection {#2947 ▼
#items: array:5 [▼
"Technology 1" => 472
"Technology 2" => 438
"Another Technology" => 249
"Yet Another Technology" => 232
"Others (Below 7%)" => 1407
]
}