133 lines
3.6 KiB
PHP
133 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Author;
|
|
use App\Models\Book;
|
|
use App\Models\Location;
|
|
use App\Services\BookInformation\BookLookupService;
|
|
use App\Services\BookInformation\GoogleBooks;
|
|
use Carbon\Carbon;
|
|
use GuzzleHttp\Client;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Arr;
|
|
|
|
class MainController extends Controller {
|
|
public function index() {
|
|
$rows = Book::paginate(15);
|
|
|
|
return view('index', [ 'rows' => $rows ]);
|
|
}
|
|
|
|
public function search(Request $request) {
|
|
$rows = Book::search($request->get('query'))->paginate(15);
|
|
|
|
return view('index', [ 'rows' => $rows ]);
|
|
}
|
|
|
|
public function add(Request $request) {
|
|
return view('add', [
|
|
'locations' => Location::get(),
|
|
'old' => array_filter($request->old('books', []), function($item) {
|
|
return !empty($item['barcode']);
|
|
})
|
|
]);
|
|
}
|
|
|
|
public function save(Request $request, BookLookupService $service) {
|
|
$this->validate($request, [
|
|
'location' => [ 'required' ]
|
|
]);
|
|
|
|
$input = array_filter($request->get('books'), function($item) {
|
|
return !empty($item['barcode']) && !empty($item['name']);
|
|
});
|
|
|
|
$this->getValidationFactory()->make($input, [
|
|
'*.barcode' => [ 'required' ],
|
|
'*.name' => [ 'required' ]
|
|
]);
|
|
|
|
$location = Location::firstOrCreate([
|
|
'name' => trim($request->get('location'))
|
|
]);
|
|
|
|
foreach ($input as $item) {
|
|
$book = Book::create([
|
|
'location_id' => $location->id,
|
|
'barcode' => $item['barcode'],
|
|
'name' => $item['name']
|
|
]);
|
|
|
|
$authors = [];
|
|
|
|
foreach (Arr::get($item, 'authors') as $author) {
|
|
$authors[] = Author::firstOrCreate([
|
|
'name' => $author
|
|
]);
|
|
}
|
|
|
|
$authors = array_map(function($author) { return $author->id; }, $authors);
|
|
|
|
$book->authors()->attach($authors);
|
|
|
|
// Lookup info from cache
|
|
$res = $service->lookup($item['barcode']);
|
|
|
|
if (!empty($res)) {
|
|
if ($images = data_get($res, 'images')) {
|
|
foreach ($images as $key => $image) {
|
|
if (empty($image)) {
|
|
continue;
|
|
}
|
|
|
|
$file = $this->downloadFile($image);
|
|
|
|
$attachment = $book->attach($file, [
|
|
'key' => $key,
|
|
'group' => 'images'
|
|
]);
|
|
|
|
$attachment->filename = $key . '.jpg';
|
|
$attachment->save();
|
|
}
|
|
}
|
|
|
|
$book->description = data_get($res, 'description');
|
|
|
|
if ($date = data_get($res, 'published_date')) {
|
|
$book->published_date = Carbon::parse($date);
|
|
}
|
|
|
|
$book->pages = data_get($res, 'pages', 0);
|
|
|
|
$book->save();
|
|
}
|
|
}
|
|
|
|
return redirect()->route('locations.show', $location->id);
|
|
}
|
|
|
|
/**
|
|
* Download a file and return the local temp path.
|
|
*
|
|
* @param $url
|
|
* @return string|null
|
|
*/
|
|
private function downloadFile($url) {
|
|
$client = new Client();
|
|
|
|
$path = tempnam(storage_path('app/temp'), 'image');
|
|
|
|
$res = $client->get($url, [
|
|
'sink' => $path
|
|
]);
|
|
|
|
if ($res->getStatusCode() != 200) {
|
|
return null;
|
|
}
|
|
|
|
return $path;
|
|
}
|
|
}
|