Skip to content

Commit

Permalink
Personal Code: Logic for Keep Track Show All page
Browse files Browse the repository at this point in the history
My biggest achievement with this block of code was with the sorting. Sorting (and one level of sub-sorting) on related tables, for me, was tricky. But I managed to figure out the sorting callback for 2 different scenarios, particularly the blocks at lines 167 and 183. It took some days to figure this out... advanced documentation was non-existent in Laravel, but the Laravel (sort) code, the PHP docs, and Google/Stack Overflow helped a lot.
  • Loading branch information
KDCinfo committed Feb 16, 2017
1 parent f9eb452 commit 77f904f
Showing 1 changed file with 259 additions and 0 deletions.
259 changes: 259 additions & 0 deletions keeptrack/ItemsController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
<?php

namespace App\Http\Controllers;

// ... //

class ItemsController extends Controller
{

protected $ratingFactors = [ '[1-2]', '[1-3]', '[1-4]', '[1-5]', '[1-10]', '[1-20]', '[1-25]', '[1-50]', '[1-100]' ];

public function index($pathId)
{
$curUser = $this->getUserLogged();

// ... //

$orderCol = Request::input('order'); // [value] from '?col=value' or 'null'
$orderDir = Request::input('dir');
$pageCur = Request::input('page');

// Check and convert filter querystring
//
$attrArray = ['type', 'status', 'medium', 'condition'];
$orderFilterAttr = Request::input('facet');
$orderFilterName = Request::input('filter');

if ( preg_match('/^[1-4]{1}$/', $orderFilterAttr) ) { // If [facet=] querystring is [1-4]

$filterMap = [1 => 'type', 2 => 'status', 3 => 'medium', 4 => 'condition'];
$filterSet = '&facet=' . $orderFilterAttr . '&filter=' . $orderFilterName;
$orderFilterAttr = $filterMap[$orderFilterAttr];

} elseif ( in_array($orderFilterAttr, $attrArray) ) { // If [facet=] querystring is a given attribute

// Not using this ... not converting 'type' to 1, etc. ... changed 'ft' to 'faceet' which is more descriptive
// $filterMap = ['type' => 1, 'status' => 2, 'medium' => 3, 'condition' => 4];
// $filterSet = '&facet=' . $filterMap[$orderFilterAttr] . '&filter=' . Request::input('filter');
$filterSet = '&facet=' . $orderFilterAttr . '&filter=' . $orderFilterName;

} else {

$orderFilterAttr = '';
$orderFilterName = '';
$filterSet = '';
}

if (strlen($filterSet) > 0) {
$filterFacet = ucwords($orderFilterAttr);
$filterStatus = $orderFilterName;
} else {
$filterFacet = '';
$filterStatus = '';
}

// End filter querystring check

$orderCol = ($orderCol) ? $orderCol : 'title';
$orderDir = ($orderDir) ? $orderDir : 'asc';
$pageCur = ($pageCur) ? $pageCur : '1';

if ($canView) {
$pageBlock = $findUser->pref_items_per_page;
} else {
$pageBlock = 5;
}

/* Sorting - Begin */
$queryMap = [
'title' => 'item_title',
'type' => 'type_title', // 'item_type_id'
'medium' => 'medium_title', // 'item_medium_id'
'status' => 'status_title', // 'item_status_id'
'condition' => 'condition_title', // 'item_condition_id'
'rating' => 'item_rating', // 'item_content_id'
'added' => 'created_at', // 'created_at'
];
$queryMapModel = [
'type' => 'itemsType', // 'item_type_id'
'medium' => 'itemsMedium', // 'item_medium_id'
'status' => 'itemsStatus', // 'item_status_id'
'condition' => 'itemsCondition', // 'item_condition_id'
'rating' => 'itemsContent', // 'item_content_id'
];
$queryMapText = $queryMap[$orderCol];

if ($orderCol == 'title' || $orderCol == 'added') {
$queryText = $queryMapText; // Set sort [column title] based on URL (e.g., where URL = 'title' => $queryText = 'item-title')
} else {
$queryMapModelText = $queryMapModel[$orderCol]; // This will allow the sorting to be based on a related table's [column title] using dot-notation
$queryText = $queryMapModelText . "." . $queryMapText; // (e.g., sortBy(itemsType.type_title) )
}

/* WHERE CLAUSES - Init */

if ($isProperUser) {
$itemWhere = [
'user_id' => $userId // Owners can view all their items
];
} else {
$itemWhere = [
'user_id' => $userId,
'is_viewable' => 1 // Don't show private items for non-owners
];
$whereIsPublic = function ($query) { $query->where('is_public', '=', '1'); };
}

/* WHERE CLAUSES - Create Results List */

// Old: $itemListBase = Item::where($itemWhere)->get()->sortBy($queryText, SORT_STRING | SORT_FLAG_CASE);
// New: Filting results list using ->whereHas()

if ($isProperUser) {
$itemListBase = Item::where($itemWhere);
} else {

$whereTypeNotNull = function ($query) use ($whereIsPublic) { $query->whereHas('itemsType', $whereIsPublic)->orWhere('item_type_id', '=', null); };
$whereMediumNotNull = function ($query) use ($whereIsPublic) { $query->whereHas('itemsMedium', $whereIsPublic)->orWhere('item_medium_id', '=', null); };
$whereStatusNotNull = function ($query) use ($whereIsPublic) { $query->whereHas('itemsStatus', $whereIsPublic)->orWhere('item_status_id', '=', null); };
// $whereContentNotNull = function ($query) use ($whereHasRating) { $query->whereHas('itemsContent', $whereHasRating)->orWhere('item_content_id', '=', null); };

$itemListBase = Item::where($itemWhere)->where($whereTypeNotNull)->where($whereMediumNotNull)->where($whereStatusNotNull);
// $itemListBase = Item::where($itemWhere)->where($whereTypeNotNull)->where($whereMediumNotNull)->where($whereStatusNotNull)->where($whereContentNotNull);
}

// Apply Filters
if ($orderFilterAttr == 'type') {
$whereTypeFilter = function ($query) use ($orderFilterName) { $query->where('type_title', '=', $orderFilterName); };
$itemListBase = $itemListBase->whereHas('itemsType', $whereTypeFilter);
}
if ($orderFilterAttr == 'status') {
$whereStatusFilter = function ($query) use ($orderFilterName) { $query->where('status_title', '=', $orderFilterName); };
$itemListBase = $itemListBase->whereHas('itemsStatus', $whereStatusFilter);
}
if ($orderFilterAttr == 'medium') {
$whereMediumFilter = function ($query) use ($orderFilterName) { $query->where('medium_title', '=', $orderFilterName); };
$itemListBase = $itemListBase->whereHas('itemsMedium', $whereMediumFilter);
}
if ($orderFilterAttr == 'condition') {
$whereConditionFilter = function ($query) use ($orderFilterName) { $query->where('condition_title', '=', $orderFilterName); };
$itemListBase = $itemListBase->whereHas('itemsCondition', $whereConditionFilter);
}

// Get list of all attribute types for display in Filter dropdown list
$itemAttrWhere = [
'user_id' => $userId,
'is_public' => 1
];
$itemTypes = ItemsType::where($itemAttrWhere)->get();
$itemStatuses = ItemsStatus::where($itemAttrWhere)->get();
$itemMediums = ItemsMedium::where($itemAttrWhere)->get();
$itemConditions = ItemsCondition::where( [ 'user_id' => $userId ] )->get();

/* Append sorting to results list (from above) */

// $queryText = "itemsMedium.medium_title"

if ($orderCol == 'title') {
if ($orderDir == 'desc') {
$itemListBase = $itemListBase->get()->sortByDesc($queryText, SORT_STRING | SORT_FLAG_CASE);
} else {
$itemListBase = $itemListBase->get()->sortBy($queryText, SORT_STRING | SORT_FLAG_CASE);
}

} elseif ($orderCol == 'added') {

$itemListBase = $itemListBase->get()
->sort(function($a, $b) use ($queryText, $orderDir) {

$queryTextTitle = 'item_title';

$sortResultVal = strcasecmp($a->$queryText, $b->$queryText);
if ($sortResultVal === 0) {
$sortResultVal = strtolower($a->$queryTextTitle . "z") > strtolower($b->$queryTextTitle . "z") ? 1 : -1;
} else {
$sortResultVal = ($orderDir == 'asc') ? $sortResultVal : -1 * $sortResultVal;
}
return $sortResultVal;
});

} else {

$itemListBase = $itemListBase->with($queryMapModelText)->get()
->sort(function($a, $b) use ($queryText, $orderDir, $orderCol) {

$queryTextTitle = 'item_title';

$queryTableName = explode(".", $queryText)[0];
$queryFieldName = explode(".", $queryText)[1];

if ($orderCol == "rating") { // Ratings are numeric; Don't compare as strings
$testCase = -1;
} else {
$testCase = "";
}

$queryItem1 = is_null($a->$queryTableName) ? $testCase : (is_null($a->$queryTableName->$queryFieldName) ? $testCase : $a->$queryTableName->$queryFieldName);
$queryItem2 = is_null($b->$queryTableName) ? $testCase : (is_null($b->$queryTableName->$queryFieldName) ? $testCase : $b->$queryTableName->$queryFieldName);

if ($orderCol == "rating") {
$sortResultVal = ($queryItem1 < $queryItem2) ? -1 : (($queryItem1 > $queryItem2) ? 1 : 0);
} else {
$sortResultVal = strcmp($queryItem1, $queryItem2);
}

if ($sortResultVal === 0) {
$sortResultVal = strtolower($a->$queryTextTitle . "z") > strtolower($b->$queryTextTitle . "z") ? 1 : -1;
} else {
$sortResultVal = ($orderDir == 'asc') ? $sortResultVal : -1 * $sortResultVal;
}
return $sortResultVal;
});
}

$itemList = $itemListBase->forPage($pageCur, $pageBlock);
$itemListBaseCount = count($itemListBase);
$pageCount = ceil(($itemListBaseCount / $pageBlock));

// if ($itemList && count($itemListBase) > 0) {
// return view('items.showAll')->with(['whichView' => $whichView, 'pageTitle' => $pageTitle, 'pathId' => $pathId, 'items' => $itemList]);

// RATINGS
$ratingFactor = $this->ratingFactors[$findUser->rating_factor];
$ratingFactorNoBrackets = substr($ratingFactor, 1, (strlen($ratingFactor)-2));
$ratingFactorMax = explode("-", $ratingFactorNoBrackets)[1];

// VISIBLE COLUMNS
$availableColumns = [0 => 'Type', 1 => 'Status', 2 => 'Medium', 3 => 'Condition', 4 => 'Rating', 5 => 'Date Added'];
if (is_null($findUser->show_columns)) {
$selectedColumns = array('0', '1', '2', '3', '4', '5'); // If null, select all (all columns visible)
} else {
$selectedColumns = unserialize($findUser->show_columns); // N; // a:2:{i:0;s:1:"1";i:1;s:1:"4";}
}
$selectedColumnsCount = count($selectedColumns);

return view('items.showAll', [
'canView' => $canView,
'whichView' => $whichView,
'pageTitle' => $pageTitle,
'pathId' => $pathId,
'pageCur' => $pageCur,
'pageCount' => $pageCount,
'orderCol' => $orderCol,
'orderDir' => $orderDir,
'filterSet' => $filterSet,
'filterFacet' => $filterFacet,
'filterStatus' => $filterStatus,
'itemCount' => $itemListBaseCount,
'items' => $itemList,
'itemTypes' => $itemTypes,
'itemStatuses' => $itemStatuses,
'itemMediums' => $itemMediums,
'itemConditions' => $itemConditions,
'ratingFactorMax' => $ratingFactorMax,
'selectedColumns' => $selectedColumns,
'selectedColumnsCount' => $selectedColumnsCount,
]);
}
}

0 comments on commit 77f904f

Please sign in to comment.