proximity search for book cases

This commit is contained in:
Benjamin Takats
2022-12-07 18:16:07 +01:00
parent 840f79e7fc
commit 351c9047a9
14 changed files with 331 additions and 115 deletions

View File

@@ -35,8 +35,8 @@ class SyncOpenBooks extends Command
],
[
'title' => $case['title'],
'lat' => (float)$case['lat'],
'lon' => (float)$case['lon'],
'latitude' => (float)$case['lat'],
'longitude' => (float)$case['lon'],
'address' => $case['address'],
'type' => $case['type'],
'open' => $case['open'],

View File

@@ -4,9 +4,14 @@ namespace App\Http\Livewire\Frontend;
use App\Models\BookCase;
use Livewire\Component;
use Livewire\WithFileUploads;
class CommentBookCase extends Component
{
use WithFileUploads;
public $photo;
public string $c = 'de';
public BookCase $bookCase;
@@ -16,28 +21,26 @@ class CommentBookCase extends Component
return view('livewire.frontend.comment-book-case');
}
public function save()
{
$this->validate([
'photo' => 'image|max:4096', // 4MB Max
]);
$this->bookCase
->addMedia($this->photo)
->toMediaCollection('images');
return to_route('comment.bookcase', ['bookCase' => $this->bookCase->id]);
}
protected function url_to_absolute($url)
{
// Determine request protocol
$request_protocol = $request_protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');
// If dealing with a Protocol Relative URL
if (stripos($url, '//') === 0) {
if (str($url)->contains('http')) {
return $url;
}
// If dealing with a Root-Relative URL
if (stripos($url, '/') === 0) {
return $request_protocol.'://'.$_SERVER['HTTP_HOST'].$url;
if (!str($url)->contains('http')) {
return str($url)->prepend('https://');
}
// If dealing with an Absolute URL, just return it as-is
if (stripos($url, 'http') === 0) {
return $url;
}
// If dealing with a relative URL,
// and attempt to handle double dot notation ".."
do {
$url = preg_replace('/[^\/]+\/\.\.\//', '', $url, 1, $count);
} while ($count);
// Return the absolute version of a Relative URL
return $request_protocol.'://'.$_SERVER['HTTP_HOST'].'/'.$url;
}
}

View File

@@ -3,16 +3,23 @@
namespace App\Http\Livewire\Tables;
use App\Models\BookCase;
use App\Models\OrangePill;
use Illuminate\Database\Eloquent\Builder;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
use Rappasoft\LaravelLivewireTables\Views\Column;
use Rappasoft\LaravelLivewireTables\Views\Filters\TextFilter;
use WireUi\Traits\Actions;
class BookCaseTable extends DataTableComponent
{
use Actions;
public bool $viewingModal = false;
public $currentModal;
public array $orangepill = [
'amount' => 1,
'date' => null,
'amount' => 1,
'date' => null,
'comment' => '',
];
protected $model = BookCase::class;
@@ -37,12 +44,27 @@ class BookCaseTable extends DataTableComponent
->setPerPage(50);
}
public function filters(): array
{
return [
TextFilter::make('By IDs', 'byids')
->filter(function (Builder $builder, string $value) {
$builder->whereIn('id', str($value)->explode(','));
}),
];
}
public function columns(): array
{
return [
Column::make("Name", "title")
->sortable()
->searchable(),
->searchable(
function (Builder $query, $searchTerm) {
$query->where('title', 'ilike', '%'.$searchTerm.'%');
}
),
Column::make("Adresse", "address")
->sortable()
->searchable(),
@@ -61,27 +83,20 @@ class BookCaseTable extends DataTableComponent
private function url_to_absolute($url)
{
// Determine request protocol
$request_protocol = $request_protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http');
// If dealing with a Protocol Relative URL
if (stripos($url, '//') === 0) {
if (str($url)->contains('http')) {
return $url;
}
// If dealing with a Root-Relative URL
if (stripos($url, '/') === 0) {
return $request_protocol.'://'.$_SERVER['HTTP_HOST'].$url;
if (!str($url)->contains('http')) {
return str($url)->prepend('https://');
}
// If dealing with an Absolute URL, just return it as-is
if (stripos($url, 'http') === 0) {
return $url;
}
// If dealing with a relative URL,
// and attempt to handle double dot notation ".."
do {
$url = preg_replace('/[^\/]+\/\.\.\//', '', $url, 1, $count);
} while ($count);
// Return the absolute version of a Relative URL
return $request_protocol.'://'.$_SERVER['HTTP_HOST'].'/'.$url;
}
public function builder(): Builder
{
return BookCase::query()
->withCount([
'orangePills',
]);
}
public function viewHistoryModal($modelId): void
@@ -90,6 +105,25 @@ class BookCaseTable extends DataTableComponent
$this->currentModal = BookCase::findOrFail($modelId);
}
public function submit(): void
{
$this->validate([
'orangepill.amount' => 'required|numeric',
'orangepill.date' => 'required|date',
]);
$orangePill = OrangePill::create([
'user_id' => auth()->id(),
'book_case_id' => $this->currentModal->id,
'amount' => $this->orangepill['amount'],
'date' => $this->orangepill['date'],
]);
if ($this->orangepill['comment']) {
$this->currentModal->comment($this->orangepill['comment']);
}
$this->resetModal();
$this->emit('refreshDatatable');
}
public function resetModal(): void
{
$this->reset('viewingModal', 'currentModal');

View File

@@ -2,6 +2,7 @@
namespace App\Http\Livewire\Tables;
use App\Models\BookCase;
use App\Models\City;
use Illuminate\Database\Eloquent\Builder;
use Rappasoft\LaravelLivewireTables\DataTableComponent;
@@ -87,4 +88,21 @@ class CityTable extends DataTableComponent
]
]);
}
public function proximitySearchForBookCases($id)
{
$city = City::query()
->find($id);
$query = BookCase::radius($city->latitude, $city->longitude, 5);
return to_route('search.bookcases', [
'#table',
'country' => $this->country,
'table' => [
'filters' => [
'byids' => $query->pluck('id')
->implode(',')
],
]
]);
}
}

View File

@@ -2,35 +2,63 @@
namespace App\Models;
use Akuechler\Geoly;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Spatie\Comments\Models\Concerns\HasComments;
use Spatie\Image\Manipulations;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
class BookCase extends Model
class BookCase extends Model implements HasMedia
{
use HasFactory;
use HasComments;
use InteractsWithMedia;
use Geoly;
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = [];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'id' => 'integer',
'lat' => 'double',
'lon' => 'array',
'digital' => 'boolean',
'id' => 'integer',
'lat' => 'double',
'lon' => 'array',
'digital' => 'boolean',
'deactivated' => 'boolean',
];
public function registerMediaConversions(Media $media = null): void
{
$this
->addMediaConversion('preview')
->fit(Manipulations::FIT_CROP, 300, 300)
->nonQueued();
$this->addMediaConversion('thumb')
->fit(Manipulations::FIT_CROP, 130, 130)
->width(130)
->height(130);
}
public function registerMediaCollections(): void
{
$this->addMediaCollection('images');
}
public function orangePills(): HasMany
{
return $this->hasMany(OrangePill::class);
}
/*
* This string will be used in notifications on what a new comment
* was made.