Skip to content

Instantly share code, notes, and snippets.

@sonOfRa
Created September 20, 2017 04:15
Show Gist options
  • Select an option

  • Save sonOfRa/ad7e5534307990d2cfa530a1eb9efc66 to your computer and use it in GitHub Desktop.

Select an option

Save sonOfRa/ad7e5534307990d2cfa530a1eb9efc66 to your computer and use it in GitHub Desktop.
<?php
namespace App\Http\Controllers;
use App\Category;
use App\Collection;
use App\Creator;
use App\Entry;
use App\EntryType;
use App\Keyword;
use App\Publisher;
use App\Rules\UniqueCategoryId;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class EntryController extends Controller
{
public function __construct()
{
$this->middleware(['auth', 'admin'], ['except' => ['index', 'show']]);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return view('entries.index', ['entries' => Entry::paginate(15)]);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$entry = new Entry();
return view('entries.create', ['entry' => $entry,
'categories' => Category::all(),
'creators' => Creator::orderBy('sort_name')->get(),
'publishers' => Publisher::orderBy('name')->get(),
'types' => EntryType::orderBy('name')->get(),
'collections' => Collection::orderBy('name')->get(),
'keywords' => Keyword::orderBy('name')->get()]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required|string|max:191',
'subtitle' => 'nullable|string|max:191',
'type' => 'required|integer|exists:entry_types,id',
'category' => 'required|integer|exists:categories,id',
'categorysubid' => 'nullable|string',
'categoryid' => ['nullable', 'integer',
new UniqueCategoryId($request->get('category'), $request->get('categorysubid'))],
'pubyear' => 'required|integer',
'isbn' => 'nullable|string',
'citationkey' => 'nullable|string|unique:entries,citation_key',
'abstract' => 'nullable|string',
'publisher' => 'nullable|integer|exists:publishers,id',
'creators' => 'required|array|min:1',
'creators.*' => 'integer|exists:creators,id',
'collections' => 'nullable|array',
'collections.*' => 'integer|exists:collections,id',
'keywords' => 'nullable|array',
'keywords.*' => 'integer|exists:keywords,id'
]);
DB::transaction(function () use ($request) {
$category_id = $request->get('categoryid');
$category = Category::findOrFail($request->get('category'));
if ($category_id === null) {
$category_id = $category->highest_id + 1;
$category->highest_id = $category_id;
$category->save();
}
$citation_key = $request->get('citationkey');
if ($citation_key === null) {
/*
* Generate a unique citation key. By default, use the first author's Last Name
* and the publication year. If the first author has no last name, use the first word
* and the publication year. If the resulting key is taken, append 'a'. If that key is also taken,
* append 'b' instead of 'a' etc., until a free key is found. Use 'aa' after 'z' and 'ba' after 'az' etc.
*/
$creator = Creator::findOrFail($request->get('creators')[0]);
$name = $creator->last_name ?? explode(' ', $creator->name)[0];
$key = $name . $request->get('pubyear');
if (Entry::whereCitationKey($key)->exists()) {
$extension = 'a';
while (Entry::whereCitationKey($key . $extension)->exists()) {
$extension++;
}
$key .= $extension;
}
$citation_key = $key;
}
$entry = new Entry();
$entry->fill([
'in_category_id' => $category_id,
'title' => $request->get('title'),
'sub_title' => $request->get('subtitle'),
'in_category_sub_id' => $request->get('categorysubid'),
'publication_year' => $request->get('pubyear'),
'abstract' => $request->get('abstract'),
'citation_key' => $citation_key,
'isbn' => $request->get('isbn')]);
$entry->category()->associate($category);
$type = EntryType::findOrFail($request->get('type'));
$entry->type()->associate($type);
if ($request->get('publisher') !== null) {
$publisher = Publisher::findOrFail($request->get('publisher'));
$entry->publisher()->associate($publisher);
}
$entry->saveOrFail();
$keywords = $request->get('keywords');
if ($keywords !== null) {
foreach ($keywords as $keyword) {
$entry->keywords()->attach($keyword);
}
}
$collections = $request->get('collections');
if ($collections !== null) {
foreach ($collections as $collection) {
$entry->collections()->attach($collection);
}
}
foreach ($request->get('creators') as $creator) {
$entry->creators()->attach($creator);
}
$entry->saveOrFail();
});
self::success('Entry created successfully');
return redirect()->route('entries.index');
}
/**
* Display the specified resource.
*
* @param \App\Entry $entry
* @return \Illuminate\Http\Response
*/
public function show(Entry $entry)
{
return view('entries.show', ['entry' => $entry]);
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Entry $entry
* @return \Illuminate\Http\Response
*/
public function edit(Entry $entry)
{
return view('entries.edit', ['entry' => $entry,
'categories' => Category::all(),
'creators' => Creator::orderBy('sort_name')->get(),
'publishers' => Publisher::orderBy('name')->get(),
'types' => EntryType::orderBy('name')->get(),
'collections' => Collection::orderBy('name')->get(),
'keywords' => Keyword::orderBy('name')->get()]);
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Entry $entry
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Entry $entry)
{
$this->validate($request, [
'title' => 'required|string|max:191',
'subtitle' => 'nullable|string|max:191',
'type' => 'required|integer|exists:entry_types,id',
'category' => 'required|integer|exists:categories,id',
'categorysubid' => 'nullable|string',
'categoryid' => ['required', 'integer',
new UniqueCategoryId($request->get('category'), $request->get('categorysubid'), $entry->id)],
'pubyear' => 'required|integer',
'isbn' => 'nullable|string',
'citationkey' => 'required|string|unique:entries,citation_key,' . $entry->id,
'abstract' => 'nullable|string',
'publisher' => 'nullable|integer|exists:publishers,id',
'creators' => 'required|array|min:1',
'creators.*' => 'integer|exists:creators,id',
'collections' => 'nullable|array',
'collections.*' => 'integer|exists:collections,id',
'keywords' => 'nullable|array',
'keywords.*' => 'integer|exists:keywords,id'
]);
DB::transaction(function () use ($request, &$entry) {
$entry->update([
'in_category_id' => $request->get('categoryid'),
'title' => $request->get('title'),
'sub_title' => $request->get('subtitle'),
'in_category_sub_id' => $request->get('categorysubid'),
'publication_year' => $request->get('pubyear'),
'abstract' => $request->get('abstract'),
'citation_key' => $request->get('citationkey'),
'isbn' => $request->get('isbn')
]);
$entry->category()->associate(Category::findOrFail($request->get('category')));
$entry->type()->associate(EntryType::findOrFail($request->get('type')));
if ($request->get('publisher') === null) {
$entry->publisher()->dissociate();
} else {
$entry->publisher()->associate(Publisher::findOrFail($request->get('publisher')));
}
$entry->saveOrFail();
$entry->keywords()->sync($request->get('keywords') ?? []);
$entry->collections()->sync($request->get('collections') ?? []);
$entry->creators()->sync($request->get('creators'));
});
self::success('Entry updated successfully');
return redirect()->action('EntryController@show', $entry);
}
/**
* Remove the specified resource from storage.
*
* @param \App\Entry $entry
* @return \Illuminate\Http\Response
*/
public function destroy(Entry $entry)
{
$entry->delete();
self::success('Entry deleted successfully');
return redirect()->action('EntryController@index');
}
/**
* Search for entries.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function search(Request $request)
{
$this->validate($request, [
'q' => 'required|string',
'in.*' => 'string|in:title,creator,keyword,ident,bibtex,publisher,abstract'
]);
$q = $request->get('q');
$in = $request->get('in') ??
explode(',', 'title,creator,keyword,ident,bibtex,publisher,abstract');
$ident_string = null;
$ident_number = null;
if (in_array('ident', $in)) {
if (preg_match_all('/[a-zA-Z]+/', $q, $matches)) {
$ident_string = $matches[0][0];
}
if (preg_match_all('/\d+/', $q, $matches)) {
$ident_number = $matches[0][0];
}
if (count($in) == 1 && ($ident_string === null || $ident_number === null)) {
self::danger('Invalid Identnumber, cannot search for this value');
return redirect()->back();
}
}
$entries = null;
for ($i = 0; $i < count($in); $i++) {
$haystack = $in[$i];
if ($i == 0) {
switch ($haystack) {
case 'title':
$entries = Entry::where('title', 'like', '%' . $q . '%', 'or')
->where('sub_title', 'like', '%' . $q . '%', 'or');
break;
case 'creator':
$entries = Entry::whereHas('creators', function ($query) use ($q) {
$query->where('sort_name', 'like', '%' . $q . '%');
});
break;
case 'keyword':
$entries = Entry::whereHas('keywords', function ($query) use ($q) {
$query->where('name', 'like', '%' . $q . '%');
});
break;
case 'ident':
$entries = Entry::whereHas('category', function ($query) use ($q, $ident_string, $ident_number) {
$query->where('name', 'like', '%' . $ident_string . '%');
})->where('in_category_id', '=', $ident_number);
break;
case 'bibtex':
$entries = Entry::where('citation_key', 'like', '%' . $q . '%');
break;
case 'publisher':
$entries = Entry::whereHas('publisher', function ($query) use ($q) {
$query->where('name', 'like', '%' . $q . '%')->orWhere('location', 'like', '%' . $q . '%');
});
break;
case 'abstract':
$entries = Entry::where('abstract', 'like', '%' . $q . '%');
break;
}
} else {
switch ($haystack) {
case 'title':
$entries->orWhere('title', 'like', '%' . $q . '%')
->orWhere('sub_title', 'like', '%' . $q . '%');
break;
case 'creator':
$entries->orWhereHas('creators', function ($query) use ($q) {
$query->where('sort_name', 'like', '%' . $q . '%');
});
break;
case 'keyword':
$entries->orwhereHas('keywords', function ($query) use ($q) {
$query->where('name', 'like', '%' . $q . '%');
});
break;
case 'ident':
$entries->orwhereHas('category', function ($query) use ($q, $ident_string, $ident_number) {
$query->where('name', 'like', '%' . $ident_string . '%');
})->where('in_category_id', '=', $ident_number);
break;
case 'bibtex':
$entries->orWhere('citation_key', 'like', '%' . $q . '%');
break;
case 'publisher':
$entries->orwhereHas('publisher', function ($query) use ($q) {
$query->where('name', 'like', '%' . $q . '%')->orWhere('location', 'like', '%' . $q . '%');
});
break;
case 'abstract':
$entries->orwhere('abstract', 'like', '%' . $q . '%');
break;
}
}
}
return view('entries.results', ['term' => $request->get('q'), 'entries' => $entries->paginate(15)]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment