File: /home/imensosw/www/mpl.imenso.co/app/Models/Event.php
<?php
namespace App\Models;
use App\Events\EventAnnounced;
use App\Events\EventCancelled;
use App\Events\EventProposed;
use App\Events\VenueApprovesProposedEvent;
use App\Events\VenueDeniesProposedEvent;
use App\Mail\AdminEventCancelled;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image as ImageLib;
use Laravel\Scout\Searchable;
class Event extends Model
{
use Searchable, SoftDeletes;
protected $table = 'events';
protected $casts = [
'event_at' => 'datetime',
'event_end_at' => 'datetime',
'announced_at' => 'datetime',
];
protected $fillable = [
'name',
'venue_id',
'status_id',
'event_at',
'event_end_at',
'enquiry_id',
'age_restriction',
'description',
'creator_id',
];
public function toSearchableArray()
{
$array = [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'venue' => $this->venue,
'status' => $this->status,
];
$array['artist_names'] = collect($this->artists())
->map(function ($artist) {
return utf8_encode($artist->getName());
})
->values()
->join(' ');
if ($this->venue != null) {
$array['venue_name'] = $this->venue->getName();
} else {
$array['venue_name'] = 'N/A';
}
$array['status_name'] = $this->status->name;
return $array;
}
public function tickets()
{
return $this->hasMany(\App\Models\Ticket::class);
}
public function ticketTypes()
{
return $this->hasMany(\App\Models\TicketType::class, 'event_id');
}
public function interestedUsers()
{
return $this->belongsToMany(\App\Models\User::class, 'event_interests', 'event_id', 'user_id');
}
public function comments()
{
return $this->morphMany(\App\Models\Comment::class, 'commentable');
}
public function venue()
{
return $this->belongsTo(\App\Models\User::class, 'venue_id');
}
public function creator()
{
return $this->belongsTo(User::class, 'creator_id');
}
public function tours()
{
return $this->belongsToMany(\App\Models\Tour::class, 'tour_events', 'event_id');
}
public function images()
{
return $this->morphMany(\App\Models\Image::class, 'imageable');
}
public function status()
{
return $this->belongsTo(\App\Models\EventStatus::class, 'status_id');
}
public function promoter()
{
return $this->belongsTo(\App\Models\User::class, 'promoter_id');
}
public function agent()
{
return $this->belongsTo(User::class, 'agent_id');
}
public function artist()
{
return $this->belongsTo(\App\Models\User::class, 'artist_id');
}
public function getPoster()
{
return $this->image(14);
}
public function supports()
{
return $this->artists('supports');
}
public function allReferredTicketsSold()
{
$ticketsSold = 0;
$event_related_orders = Order::leftJoin('tickets', 'orders.id', '=', 'tickets.order_id')->where('tickets.event_id', $this->id)->get();
foreach ($event_related_orders as $orderticket) {
$ticketsSold += $orderticket->quantity;
}
return $ticketsSold;
}
public function currentUserReferredTicketsSold($ticketType = null)
{
return $this->userReferredTicketsSold(Auth::user(), $ticketType);
}
public function userReferredTicketsSold(User $user, $ticketType = null)
{
$ticketsSold = 0;
if ($ticketType == null) {
$event_related_orders = Order::leftJoin('tickets', 'orders.id', '=', 'tickets.order_id')->where('orders.status_id', 2)->where('tickets.event_id', $this->id)->get();
} else {
$event_related_orders = Order::leftJoin('tickets', 'orders.id', '=', 'tickets.order_id')->where('orders.status_id', 2)->where('tickets.event_id', $this->id)->where('tickets.ticket_type_id', $ticketType)->get();
}
foreach ($event_related_orders as $orderticket) {
if ($user->ticket_sales_referer_id != null && ($orderticket->referer_id == $user->ticket_sales_referer_id)) {
$ticketsSold += $orderticket->quantity;
}
}
return $ticketsSold;
}
public function artist_ids_with_temps()
{
$ids = [];
$i = 0;
foreach ($this->artists() as $artist) {
if ($artist->id == 0) {
$ids[] = 't'.$i;
$i++;
} else {
$ids[] = $artist->id;
}
}
return $ids;
}
public function artist_ids()
{
$ids = [];
foreach ($this->artists() as $artist) {
$ids[] = $artist->id;
}
return $ids;
}
public function artists($slot_type_id = false)
{
if ($slot_type_id == 'supports') {
$artist_ids = DB::table('event_artists')->where('event_id', $this->id)->where('slot_type_id', '!=', 1)->orderBy('orderby')->get();
} elseif ($slot_type_id !== false) {
$artist_ids = DB::table('event_artists')->where('event_id', $this->id)->where('slot_type_id', $slot_type_id)->orderBy('orderby')->get();
} else {
$artist_ids = DB::table('event_artists')->where('event_id', $this->id)->orderBy('orderby')->get();
}
$artists = new Collection;
$temp_artist_count = 0;
foreach ($artist_ids as $id) {
if ($id->artist_id != 0) {
if (User::where('id', $id->artist_id)->count() == 0) {
$artist = new User;
$artist->artist_name = '[Deleted]';
$artist->type_id = 2;
$artist->role = $id->slot_type_id;
} else {
$artist = User::findOrFail($id->artist_id);
$artist->role = $id->slot_type_id;
$artists->push($artist);
}
} else {
$temp_artist = new User;
$temp_artist->id = 't'.$temp_artist_count;
$temp_artist->tmp_id = 't'.$temp_artist_count;
$temp_artist->artist_name = $id->artist_name;
$temp_artist->type_id = 2;
$temp_artist->role = $id->slot_type_id;
$temp_artist->created_at = \Carbon\Carbon::parse($id->created_at);
$artists->push($temp_artist);
$temp_artist_count++;
}
}
return $artists;
}
public static function addNew($data)
{
if ($data['doors'] != null) {
$doors = Carbon::createFromFormat('H:i', $data['doors_submit']);
$doors_set = 1;
} else {
$doors = Carbon::createFromFormat('H:i', '00:00');
$doors_set = 0;
}
$event_at = Carbon::parse($data['event_at']);
$event_at->setTime($doors->format('H'), $doors->format('i'));
$event = self::create([
'name' => $data['name'],
'description' => $data['description'],
'status_id' => $data['event_status'],
'event_at' => $event_at,
'venue_id' => $data['venue_id'],
'creator_id' => Auth::user()->id,
]);
\App\Models\User::find($data['venue_id'])
->availability()
->whereDate('availability_at', $event_at)
->delete();
if (isset($data['tour_date_id']) && !empty($data['tour_date_id'])) {
$tour_planner_date = TourPlannerDate::findOrFail($data['tour_date_id']);
$tour_planner_date->addEvent($event);
}
$event->doors_set = $doors_set;
$event->save();
if (isset($data['curfew'])) {
$event_end_at = Carbon::parse($data['event_at']);
$curfew = Carbon::createFromFormat('H:i', $data['curfew_submit']);
$event_end_at->setTime($curfew->format('H'), $curfew->format('i'));
$event->event_end_at = $event_end_at;
$event->save();
}
$artist_ids = explode(',', $data['artist_ids']);
foreach ($artist_ids as $id) {
if (! strstr($id, 't')) {
$artist = User::where('id', $id)->firstOrFail();
} else {
$artist = new User;
$artist->id = $id;
$artist->tmp_id = $id;
$artist->artist_name = $data['temp_artist_'.$id];
$artist->created_at = now();
}
foreach ($data['artist_type'] as $key => $type) {
$exploded_key = explode(':', $key);
if (($exploded_key[0] == $artist->id) || ($key == $artist->tmp_id)) {
$slot = TourSlotType::findOrFail($type);
}
}
$event->addArtist($artist, $slot);
}
if (Auth::user()->isArtist()) {
$data['ticketing'] = 'on-door';
$data['set_price'] = 0;
}
if ($data['ticketing'] == 'internal') {
if (isset($data['tickets'])) {
foreach ($data['tickets'] as $ticket) {
$event->addTicketType(
$ticket['name'],
$ticket['qty'],
$ticket['price'],
$ticket['fee']
);
}
}
} elseif ($data['ticketing'] == 'external') {
$data['external_ticketing_link'] = str_replace('http://', '', $data['external_ticketing_link']);
$data['external_ticketing_link'] = str_replace('https://', '', $data['external_ticketing_link']);
$data['external_ticketing_link'] = 'http://'.$data['external_ticketing_link'];
$event->external_ticketing_link = $data['external_ticketing_link'];
$event->set_price = $data['set_price_external'];
$event->save();
} elseif ($data['ticketing'] == 'on-door') {
$event->on_door_ticketing = 1;
$event->set_price = $data['set_price'];
$event->save();
}
if ($event->status->id == 1) {
if (Auth::user()->isArtist() || Auth::user()->isPromoter()) {
event(new EventProposed($event, Auth::user()));
}
} elseif ($event->status->id == 3) {
$now = \Carbon\Carbon::now();
$event->announced_at = $now;
event(new EventAnnounced($event));
$event->save();
}
return $event;
}
public function addArtwork($image)
{
$filename = $this->id.'-'.time().'-thmb.'.$image->getClientOriginalExtension();
$web_location = 'events/'.$filename;
$processed_image = ImageLib::make($image->getRealPath());
$save = $processed_image->save();
Storage::disk('s3')->put($web_location, $save->__toString());
$this->deleteImage(14);
$this->setImage(14, $web_location);
}
public function deleteImage($type_id)
{
if ($this->images()->where('type_id', $type_id)->count() > 0) {
$this->images()->where('type_id', $type_id)->first()->remove();
}
}
public function setImage($type_id, $location)
{
$image = new Image;
$image->src = $location;
$image->imageable_id = $this->id;
$image->imageable_type = self::class;
$image->type_id = $type_id;
$image->save();
}
public function descriptionLength()
{
return strlen(strip_tags($this->description));
}
public function getTruncatedDescription($length = 100)
{
if ($this->descriptionLength() > $length) {
return truncate_html_safe($this->description, $length, [
'html' => true,
]);
} else {
return $this->description;
}
}
public function edit($data)
{
$this->name = $data['name'];
$this->description = $data['description'];
if (isset($data['promoter_id']) && !empty($data['promoter_id'])) {
$this->promoter_id = $data['promoter_id'];
} else {
$this->promoter_id = '';
}
if (isset($data['agent_id']) && !empty($data['agent_id'])) {
$this->agent_id = $data['agent_id'];
} else {
$this->agent_id = '';
}
if ($data['doors'] != null) {
$doors = Carbon::createFromFormat('H:i', $data['doors_submit']);
$this->doors_set = 1;
} else {
$doors = Carbon::createFromFormat('H:i', '00:00');
$this->doors_set = 0;
}
$event_at = clone $this->event_at;
$event_at = $event_at->setTime($doors->format('H'), $doors->format('i'));
$this->event_at = $event_at;
if (isset($data['curfew'])) {
$curfew = Carbon::createFromFormat('H:i', $data['curfew_submit']);
$event_end_at = clone $this->event_at;
$event_end_at = $event_at->setTime($curfew->format('H'), $curfew->format('i'));
$this->event_end_at = $event_end_at;
}
$this->removeArtists();
$artist_ids = explode(',', $data['artist_ids']);
foreach ($artist_ids as $id) {
if (! strstr($id, 't') && $id != 0) {
$artist = User::findOrFail($id);
} else {
$artist = new User;
$artist->id = $id;
$artist->tmp_id = $id;
$artist->artist_name = $data['temp_artist_'.$id];
$artist->created_at = \Carbon\Carbon::now();
}
$slot = TourSlotType::findOrFail(1);
foreach ($data['artist_type'] as $key => $type) {
$exploded_key = explode('-', $key);
if ($exploded_key[0] == (string) $artist->id || $key === $artist->tmp_id) {
$slot = TourSlotType::findOrFail($type);
}
}
$this->addArtist($artist, $slot);
}
if ($data['ticketing'] == 'internal') {
$this->on_door_ticketing = 0;
$this->external_ticketing_link = '';
$editted_tickets = [];
if (isset($data['tickets'])) {
foreach ($data['tickets'] as $k => $ticket_data) {
if (strstr($k, 'new-')) {
$ticket_type = $this->addTicketType(
$ticket_data['name'],
$ticket_data['qty'],
$ticket_data['price'],
$ticket_data['fee']
);
$editted_tickets[] = $ticket_type->id;
} else {
$ticket_type = TicketType::findOrFail($k);
$ticket_type->edit($ticket_data);
$editted_tickets[] = $ticket_type->id;
}
}
foreach ($this->ticketTypes as $type) {
if (! in_array($type->id, $editted_tickets)) {
$type->remove();
}
}
}
} elseif ($data['ticketing'] == 'external') {
$data['external_ticketing_link'] = str_replace('http://', '', $data['external_ticketing_link']);
$data['external_ticketing_link'] = str_replace('https://', '', $data['external_ticketing_link']);
$data['external_ticketing_link'] = 'http://'.$data['external_ticketing_link'];
$this->on_door_ticketing = 0;
$this->external_ticketing_link = $data['external_ticketing_link'];
$this->set_price = $data['set_price_external'];
} elseif ($data['ticketing'] == 'on-door') {
$this->on_door_ticketing = 1;
$this->external_ticketing_link = '';
$this->set_price = $data['set_price'];
}
$this->changeStatus(EventStatus::findOrFail($data['event_status']));
if ($this->status->id == 3) {
$now = \Carbon\Carbon::now();
$this->announced_at = $now;
}
$this->save();
}
public function addArtist(User $artist, TourSlotType $slot)
{
if (DB::table('event_artists')->where('event_id', $this->id)->where('artist_id', $artist->id)->count() == 0 || $artist->id == 0) {
$orderby = DB::table('event_artists')->where('event_id', $this->id)->count() * 10;
$now = Carbon::now();
DB::table('event_artists')->insert([
'event_id' => $this->id,
'artist_id' => $artist->id,
'artist_name' => ($artist->artist_name ? $artist->artist_name : ''),
'orderby' => $orderby,
'slot_type_id' => $slot->id,
'created_at' => $now,
'updated_at' => $now,
]);
}
}
public function addTicketType($name = 'General Admission', $qty = 0, $price = 10, $fee = 0)
{
$ticket_type = TicketType::create([
'ticket_type' => $name,
'allocation' => $qty,
'price' => $price,
'booking_fee' => $fee,
'event_id' => $this->id,
]);
return $ticket_type;
}
public function setEnquiry(Enquiry $enquiry)
{
$this->enquiry_id = $enquiry->id;
$this->save();
}
public function setPromoter(User $promoter)
{
$this->promoter_id = $promoter->id;
$this->save();
}
public function setAgent(User $agent)
{
$this->agent_id = $agent->id;
$this->save();
}
public function setArtist(User $artist)
{
$this->artist_id = $artist->id;
$this->save();
}
public function approveProposed()
{
//Remove the venue availability for this date
$avail = VenueAvailability::where([
'availability_at' => $this->event_at->setTime(0, 0, 0),
'venue_id' => $this->venue->id,
])->first();
if ($avail) {
$avail->remove();
}
foreach ($this->venue->enquiries()->get()->where('enquiry_at', $this->event_at->setTime(0, 0, 0)) as $enquiry) {
if ($enquiry->promoter) {
$thread = $enquiry->promoter_thread();
$thread->addMessage('This date is no longer available as another event has been added.', $this->venue);
}
}
event(new VenueApprovesProposedEvent($this));
$this->changeStatus(EventStatus::findOrFail(2));
}
public function denyProposed()
{
event(new VenueDeniesProposedEvent($this));
$this->changeStatus(EventStatus::findOrFail(4));
}
public function changeStatus(EventStatus $status)
{
if ($status->id != $this->status_id && $status->id == 3) {
event(new EventAnnounced($this));
$now = \Carbon\Carbon::now();
$this->announced_at = $now;
$this->save();
}
if ($status->id != $this->status_id && $status->id == 5) {
event(new EventCancelled($this));
}
$this->status_id = $status->id;
$this->save();
}
public function isProposed()
{
if ($this->status_id == 1) {
return true;
}
return false;
}
public function getLocalTime()
{
if ($this->venue) {
return $this->event_at->setTimezone($this->venue->timezone);
} else {
return $this->event_at->setTimezone('Europe/London');
}
}
public function getDefaultImage()
{
$image = new Image;
$image->src = ImageType::findOrFail(14)->default_image;
return $image;
}
public function getThumbnail()
{
return $this->image(14);
}
public function getThumbnailSrc()
{
return $this->getThumbnail()->full_url;
}
public function getName()
{
return $this->name.', '.$this->venue->getName();
}
public function getDescriptionExtract($length = 200)
{
if (strlen(strip_tags($this->description)) > $length) {
return substr(strip_tags($this->description), 0, $length - 3).'...';
} else {
return strip_tags($this->description);
}
}
public function image($image_type_id = 0)
{
if ($this->images()->where('type_id', $image_type_id)->count() > 0) {
return $this->images()->where('type_id', $image_type_id)->first();
} else {
$image = new Image;
$image->src = ImageType::findOrFail($image_type_id)->default_image;
return $image;
}
}
public function isInternallyTicketed()
{
if ($this->ticketTypes->count() > 0) {
return true;
}
return false;
}
public function totalAllocation()
{
$count = 0;
foreach ($this->ticketTypes as $type) {
$count += $type->allocation;
}
return $count;
}
public function totalTickets()
{
$count = 0;
foreach ($this->tickets as $tickets) {
$count += $tickets->quantity;
}
return $count;
}
public function ticketHolders()
{
$users = new Collection;
foreach ($this->tickets as $ticket) {
$users->push(User::findOrFail($ticket->user_id));
}
$users = $users->unique();
return $users;
}
public function readableTicketPrices()
{
if ($this->on_door_ticketing == 1 || $this->external_ticketing_link) {
return $this->set_price;
}
$prices = [];
foreach ($this->ticketTypes as $ticketType) {
$prices[] = $ticketType->price;
}
if ($prices != []) {
$prices = array_unique($prices);
if (count($prices) > 1) { //Multiple Prices
sort($prices);
$return = '£'.$prices[0].'-'.$prices[count($prices) - 1];
} else { //Only one price
$return = '£'.$prices[0];
}
} else { // No Tickets
$return = 'N/A';
}
return $return;
}
public function isSoldOut()
{
if (! $this->external_ticketing_link && ! $this->on_door_ticketing) {
if ($this->totalAllocation() > $this->totalTickets()) {
return false;
} else {
return true;
}
} else {
return false;
}
}
public function isPast()
{
if ($this->event_at < Carbon::now()) {
return true;
}
return false;
}
public function interestedCount()
{
return DB::table('event_interests')->where('event_id', $this->id)->count();
}
public function removeArtists()
{
DB::table('event_artists')->where('event_id', $this->id)->delete();
}
public function headliner()
{
return $this->artists('1')->first();
}
public function getTotalTicketsSold()
{
$total = 0;
if ($this->ticketTypes()->count() > 0) {
foreach ($this->ticketTypes as $ticket_type) {
if ($ticket_type->orderItems()->count() > 0) {
foreach ($ticket_type->orderItems() as $item) {
if (isset($item->order) && $item->order->status_id == 2) {
$total += $item->quantity;
}
}
}
}
}
return $total;
}
public function getTotalTicketRevenue()
{
$total = 0;
if ($this->ticketTypes()->count() > 0) {
foreach ($this->ticketTypes as $ticket_type) {
if ($ticket_type->orderItems()->count() > 0) {
foreach ($ticket_type->orderItems() as $item) {
if (isset($item->order) && $item->order->status_id == 2) {
$total += $item->total;
}
}
}
}
}
return $total;
}
public function getTotalBookingFeeRevenue()
{
$total_fee = 0;
if ($this->ticketTypes()->count() > 0) {
foreach ($this->ticketTypes as $ticket_type) {
if ($ticket_type->orderItems()->count() > 0) {
foreach ($ticket_type->orderItems() as $item) {
if (isset($item->order) && $item->order->status_id == 2) {
$total_fee += $item->booking_fee;
}
}
}
}
}
return $total_fee;
}
public function organiser()
{
if ($this->promoter) {
return $this->promoter;
} else {
return $this->venue;
}
}
public function getTotalToPayOrganiser()
{
$total = 0;
$total = $this->getTotalTicketRevenue() - $this->getTotalBookingFeeRevenue();
return $total;
}
public function hasDoorsSet()
{
return $this->doors_set;
}
public function isApprovedByVenue()
{
if ($this->status_id == 2 || $this->status_id == 3) {
return true;
}
return false;
}
public function isAnnounced()
{
if ($this->status_id == 3) {
return true;
}
return false;
}
public function isAnnounceable()
{
if (
! $this->isAnnounced() &&
$this->hasDoorsSet() &&
($this->isApprovedByVenue() || (Auth::check() && Auth::user()->isAdmin()))
) {
return true;
}
return false;
}
public function hasPermissionToAnnounce(User $user)
{
if (
$user->id == $this->venue->id ||
($this->promoter && $user->id == $this->promoter->id) ||
($this->headliner() && $user->id == $this->headliner()->id) ||
$user->isAdmin()
) {
return true;
}
return false;
}
public function announce()
{
$this->changeStatus(EventStatus::findOrFail(3));
}
public function markAsPaid()
{
$this->paid = 1;
$this->save();
}
public function hasPromoter()
{
if ($this->promoter_id) {
return true;
}
return false;
}
public function hasAgent()
{
if ($this->agent_id) {
return true;
}
return false;
}
public function checkCreator(User $user)
{
return $user->id == $this->creator_id;
}
public function hasPermissionToDelete(User $user)
{
if ($user->id == $this->venue_id) {
return true;
}
if ($user->id == $this->promoter_id) {
return true;
}
if (in_array($user->id, $this->venue->promoters()->pluck('id')->toArray())) {
return true;
}
return $this->checkCreator($user);
}
public function isDeleteable()
{
if ($this->totalTickets() > 0) {
return false;
}
return true;
}
public function remove()
{
foreach ($this->tickets as $ticket) {
//Unlinks ticket but doesn't delete it
$ticket->event_id = 0;
$ticket->save();
}
DB::table('event_interests')->where([
'event_id' => $this->id,
])->delete();
DB::table('event_non_interests')->where([
'event_id' => $this->id,
])->delete();
// DB::table('event_ticket_types')->where([
// 'event_id' => $this->id,
// ])->delete();
DB::table('comments')->where([
'commentable_id' => $this->id,
'commentable_type' => 'App\Event',
])->delete();
DB::table('likes')->where([
'likeable_id' => $this->id,
'likeable_type' => 'App\Event',
])->delete();
DB::table('tour_events')->where([
'event_id' => $this->id,
])->delete();
DB::table('tour_planner_date_events')->where([
'event_id' => $this->id,
])->delete();
Mail::to(User::where('type_id', 5)->get())->send(new AdminEventCancelled($this));
$this->delete();
}
}