Merge remote-tracking branch 'upstream/master'

Conflicts:
	composer.lock
This commit is contained in:
bretto36 2016-06-14 21:06:33 -04:00
commit 3d1ff1455a
1080 changed files with 213227 additions and 62882 deletions

View File

@ -2,19 +2,19 @@ APP_ENV=production
APP_DEBUG=false
APP_URL=
APP_CIPHER=rijndael-128
APP_KEY=SomeRandomString
APP_KEY=
APP_TIMEZONE
DB_TYPE=mysql
DB_HOST=localhost
DB_TYPE=pgsql
DB_HOST=db
DB_DATABASE=attendize
DB_USERNAME=
DB_PASSWORD=
DB_USERNAME=attendize
DB_PASSWORD=attendize
MAIL_DRIVER=smtp
MAIL_PORT=587
MAIL_ENCRYPTION=tls
MAIL_HOST=
MAIL_PORT=25
MAIL_ENCRYPTION=
MAIL_HOST=maildev
MAIL_FROM_ADDRESS=
MAIL_FROM_NAME=
MAIL_PASSWORD=
@ -24,4 +24,4 @@ GOOGLE_ANALYTICS_ID=
TWITTER_WIDGET_ID=
LOG=single
LOG=errorlog

4
.gitignore vendored
View File

@ -1,3 +1,4 @@
/.env.testing
/.phpstorm.meta.php
/vendor
/node_modules
@ -8,4 +9,5 @@ installed
/.project
/.buildpath
/composer.phar
_ide_helper.php
_ide_helper.php
*.swp

2
Dockerfile-nginx Normal file
View File

@ -0,0 +1,2 @@
FROM nginx:latest
COPY nginx.conf /etc/nginx/conf.d/default.conf

13
Dockerfile-php Normal file
View File

@ -0,0 +1,13 @@
FROM php:fpm
RUN apt-get update && apt-get install -y \
libpq-dev \
libmcrypt-dev \
libpng12-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
libxrender1 \
libfontconfig \
libxext-dev \
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install -j$(nproc) pdo_pgsql pgsql mcrypt gd zip
WORKDIR /usr/share/nginx/html/attendize

View File

@ -1,141 +1,89 @@
module.exports = function(grunt) {
//Initializing the configuration object
module.exports = function (grunt) {
//Initializing the configuration object
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Task configuration
less: {
development: {
options: {
compress: true, //minifying the result
pkg: grunt.file.readJSON('package.json'),
// Task configuration
less: {
development: {
options: {
compress: true,
},
files: {
"./public/assets/stylesheet/application.css": "./public/assets/stylesheet/application.less",
"./public/assets/stylesheet/frontend.css": "./public/assets/stylesheet/frontend.less",
}
},
files: {
//compiling frontend.less into frontend.css
"./public/assets/stylesheet/application.css":"./public/assets/stylesheet/application.less",
"./public/assets/stylesheet/frontend.css":"./public/assets/stylesheet/frontend.less",
//compiling backend.less into backend.css
//"./public/assets/stylesheets/backend.css":"./app/assets/stylesheets/backend.less"
}
},
website: {
concat: {
options: {
compress: true, //minifying the result
separator: ';',
stripBanners: {
block: true,
line: true
},
},
js_frontend: {
src: [
'./public/vendor/jquery/dist/jquery.min.js',
'./public/vendor/bootstrap/dist/js/bootstrap.js',
'./public/vendor/jquery-form/jquery.form.js',
'./public/vendor/RRSSB/js/rrssb.js',
'./public/vendor/humane-js/humane.js',
'./public/assets/javascript/app-public.js'
],
dest: './public/assets/javascript/frontend.js',
},
js_backend: {
src: [
'./public/vendor/modernizr/modernizr.js',
'./public/vendor/html.sortable/dist/html.sortable.js',
'./public/vendor/bootstrap/dist/js/bootstrap.js',
'./public/vendor/jquery-form/jquery.form.js',
'./public/vendor/humane-js/humane.js',
'./public/vendor/RRSSB/js/rrssb.js',
'./public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.js',
'./public/vendor/curioussolutions-datetimepicker/dist/DateTimePicker.js',
'./public/vendor/jquery-minicolors/jquery.minicolors.min.js',
'./public/assets/javascript/app.js'
],
dest: './public/assets/javascript/backend.js',
},
files: {
"./public/website_assets/stylesheet/main.css":"./public/website_assets/stylesheet/main.less",
}
}
},
concat: {
options: {
separator: ';',
stripBanners: true,
},
js_frontend: {
src: [
'./public/vendor/jquery/jquery.js',
'./public/vendor/bootstrap/dist/js/bootstrap.js',
'./public/vendor/jquery-form/jquery.form.js',
'./public/vendor/RRSSB/js/rrssb.js',
'./public/vendor/humane-js/humane.js',
'./public/vendor/jquery-backstretch/jquery.backstretch.js',
'./public/assets/javascript/app-public.js'
],
dest: './public/assets/javascript/frontend.js',
},
js_backend: {
src: [
'./public/vendor/modernizr/modernizr.js',
'./public/vendor/bootstrap/dist/js/bootstrap.js',
'./public/vendor/jquery-form/jquery.form.js',
'./public/vendor/humane-js/humane.js',
'./public/vendor/RRSSB/js/rrssb.js',
'./public/vendor/bootstrap-touchspin/dist/jquery.bootstrap-touchspin.js',
'./public/vendor/curioussolutions-datetimepicker/dist/DateTimePicker.js',
'./public/vendor/jquery-minicolors/jquery.minicolors.min.js',
'./public/assets/javascript/app.js'
],
dest: './public/assets/javascript/backend.js',
},
},
uglify: {
options: {
mangle: true, // Use if you want the names of your functions and variables unchanged
preserveComments: false,
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */',
},
frontend: {
files: {
'./public/assets/javascript/frontend.js': './public/assets/javascript/frontend.js',
}
},
backend: {
files: {
'./public/assets/javascript/backend.js': './public/assets/javascript/backend.js',
}
},
},
phpunit: {
classes: {
},
options: {
}
},
// watch: {
// js_frontend: {
// files: [
// //watched files
// './bower_components/jquery/jquery.js',
// './bower_components/bootstrap/dist/js/bootstrap.js',
// './app/assets/javascript/frontend.js'
// ],
// tasks: ['concat:js_frontend','uglify:frontend'], //tasks to run
// options: {
// livereload: true //reloads the browser
// }
// },
// js_backend: {
// files: [
// //watched files
// './bower_components/jquery/jquery.js',
// './bower_components/bootstrap/dist/js/bootstrap.js',
// './app/assets/javascript/backend.js'
// ],
// tasks: ['concat:js_backend','uglify:backend'], //tasks to run
// options: {
// livereload: true //reloads the browser
// }
// },
// less: {
// files: ['./app/assets/stylesheets/*.less'], //watched files
// tasks: ['less'], //tasks to run
// options: {
// livereload: true //reloads the browser
// }
// },
// tests: {
// files: ['app/controllers/*.php','app/models/*.php'], //the task will run only when you save files in this location
// tasks: ['phpunit']
// }
// }
uglify: {
options: {
mangle: true, // Use if you want the names of your functions and variables unchanged
preserveComments: false,
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */',
},
frontend: {
files: {
'./public/assets/javascript/frontend.js': ['<%= concat.js_frontend.dest %>'],
}
},
backend: {
files: {
'./public/assets/javascript/backend.js': './public/assets/javascript/backend.js',
}
},
},
phpunit: {
classes: {},
options: {}
},
});
// Plugin loading
grunt.loadNpmTasks('grunt-contrib-concat');
//grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-uglify');
//grunt.loadNpmTasks('grunt-phpunit');
// Task definition
//grunt.registerTask('default', ['watch']);
grunt.registerTask('default', ['less', 'concat']);
grunt.registerTask('deploy', ['less', 'concat', 'uglify']);
grunt.registerTask('js', ['concat']);
grunt.registerTask('styles', ['concat']);
grunt.registerTask('minify', ['uglify']);
// Plugin loading
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-uglify');
//grunt.loadNpmTasks('grunt-phpunit');
// Task definition
grunt.registerTask('default', ['less', 'concat']);
grunt.registerTask('deploy', ['less', 'concat', 'uglify']);
grunt.registerTask('js', ['concat']);
grunt.registerTask('styles', ['concat']);
grunt.registerTask('minify', ['uglify']);
};

View File

@ -12,8 +12,7 @@ otherwise billable time invested in writing this and other freely available,
open-source software.
1. Redistributions of source code, in whole or part and with or without
modification requires the express permission of the author and must prominently
display "Powered by Attendize" or the Attendize logo in verifiable form
modification must prominently display "Powered by Attendize" or the Attendize logo in verifiable form
with hyperlink to said site.
2. Neither the name nor any trademark of the Author may be used to
endorse or promote products derived from this software without specific

View File

@ -1 +1 @@
0.4.0
0.8.0

View File

@ -4,6 +4,7 @@ namespace App\Attendize;
class Utils
{
public static function isRegistered()
{
return Auth::check() && Auth::user()->is_registered;

View File

@ -35,31 +35,28 @@ class AttendeeMailer extends Mailer
{
$event = $message_object->event;
$attendees = ($message_object->recipients == 0)
$attendees = ($message_object->recipients == 'all')
? $event->attendees // all attendees
: Attendee::where('ticket_id', '=', $message_object->recipients)->where('account_id', '=', $message_object->account_id)->get();
$toFields = [];
foreach ($attendees as $attendee) {
$toFields[$attendee->email] = $attendee->full_name;
foreach($attendees as $attendee) {
$data = [
'attendee' => $attendee,
'event' => $event,
'message_content' => $message_object->message,
'subject' => $message_object->subject,
'email_logo' => $attendee->event->organiser->full_logo_path,
];
Mail::send('Emails.messageAttendees', $data, function ($message) use ($attendee, $data) {
$message->to($attendee->email, $attendee->full_name)
->from(config('attendize.outgoing_email_noreply'), $attendee->event->organiser->name)
->replyTo($attendee->event->organiser->email, $attendee->event->organiser->name)
->subject($data['subject']);
});
}
$data = [
'event' => $event,
'message_content' => $message_object->message,
'subject' => $message_object->subject,
];
/*
* Mandril lets us send the email to multiple people at once.
*/
Mail::send('Emails.messageAttendees', $data, function ($message) use ($toFields, $event, $message_object) {
$message->to($toFields)
->from(config('attendize.outgoing_email_noreply'), $event->organiser->name)
->replyTo($event->organiser->email, $event->organiser->name)
->subject($message_object->subject);
});
$message_object->is_sent = 1;
$message_object->sent_at = Carbon::now();
$message_object->save();

View File

@ -1,26 +0,0 @@
<?php
namespace App\Attendize\mailers;
use Mail;
class Mailer
{
public function sendTo($toEmail, $fromEmail, $fromName, $subject, $view, $data = [], $attachment = false)
{
Mail::send($view, $data, function ($message) use ($toEmail, $fromEmail, $fromName, $subject, $attachment) {
$replyEmail = $fromEmail;
$fromEmail = config('attendize.outgoing_email');
if ($attachment) {
$message->attach($attachment);
}
$message
->to($toEmail)
->from($fromEmail, $fromName)
->replyTo($replyEmail, $fromName)
->subject($subject);
});
}
}

View File

@ -1,54 +0,0 @@
<?php
namespace App\Commands;
use App\Attendize\mailers\OrderMailer;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Log;
class OrderTicketsCommand extends Command implements ShouldQueue, SelfHandling
{
use InteractsWithQueue,
SerializesModels;
public $ticketOrder, $sendOrderConfirmation;
private $outSeperator = "\n ---------------------- \n";
/**
* OrderTicketsCommand constructor.
*
* @param \App\Models\Order $ticketOrder
* @param bool|true $sendOrderConfirmation
*/
public function __construct(\App\Models\Order $ticketOrder, $sendOrderConfirmation = true)
{
$this->ticketOrder = $ticketOrder;
$this->sendOrderConfirmation = $sendOrderConfirmation;
}
/**
* @param OrderMailer $mailer
*/
public function handle(OrderMailer $mailer)
{
Log::info(date('d m y H:i')." - Starting Job {$this->job->getJobId()} ".__CLASS__);
//1 - Notify event organiser
if ($this->sendOrderConfirmation) {
$mailer->sendOrderNotification($this->ticketOrder);
}
//2 - Generate PDF Tickets
$this->ticketOrder->generatePdfTickets();
//3 - Send Tickets / Order confirmation
$mailer->sendOrderConfirmation($this->ticketOrder);
Log::info(date('d m y H:i')." - Finished Job {$this->job->getJobId()} ".__CLASS__);
$this->delete();
}
}

View File

@ -1,80 +0,0 @@
<?php
namespace App\Commands;
use App\Attendize\mailers\AttendeeMailer;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Log;
use PDF;
class SendAttendeeTicketCommand extends Command implements ShouldQueue, SelfHandling
{
use InteractsWithQueue,
SerializesModels;
public $ticketOrder, $attendee;
/**
* OrderTicketsCommand constructor.
*
* @param \App\Models\Order $ticketOrder
* @param bool|true $sendOrderConfirmation
*/
public function __construct(\App\Models\Attendee $attendee)
{
$this->ticketOrder = $attendee->order;
$this->attendee = $attendee;
}
/**
* @param AttendeeMailer $mailer
*/
public function handle(AttendeeMailer $mailer)
{
Log::info(date('d m y H:i')." - Starting Job {$this->job->getJobId()} ".__CLASS__);
//1 - Generate PDF Tickets
$ticket_path = $this->generateAttendeeTicket();
//2 - Send Tickets / Order confirmation
$mailer->sendAttendeeTicket($this->attendee, $this->ticketOrder, $ticket_path);
Log::info(date('d m y H:i')." - Finished Job {$this->job->getJobId()} ".__CLASS__);
$this->delete();
}
/**
* Create a ticket for an attendee
*
* @todo should the path to the PDF be stored in the DB?
* @todo This probably shouldn't be done here
* @return bool|string
*/
public function generateAttendeeTicket() {
$data = [
'order' => $this->ticketOrder,
'event' => $this->attendee->event,
'tickets' => $this->attendee->event->tickets,
'attendees' => [$this->attendee],
];
$pdf_file_name = $this->ticketOrder->order_reference.'-'.$this->attendee->id;
$pdf_file_path = public_path(config('attendize.event_pdf_tickets_path')).'/'.$pdf_file_name;
$pdf_file = $pdf_file_path.'.pdf';
if (file_exists($pdf_file)) {
return $pdf_file;
}
PDF::setOutputMode('F'); // force to file
PDF::html('Public.ViewEvent.Partials.PDFTicket', $data, $pdf_file_path);
return $pdf_file;
}
}

View File

@ -3,8 +3,11 @@
namespace App\Exceptions;
use Exception;
use Illuminate\Validation\ValidationException;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Request;
//use Bugsnag\BugsnagLaravel\BugsnagExceptionHandler as ExceptionHandler;
@ -16,7 +19,10 @@ class Handler extends ExceptionHandler
* @var array
*/
protected $dontReport = [
'Symfony\Component\HttpKernel\Exception\HttpException',
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
ValidationException::class,
];
/**
@ -24,55 +30,23 @@ class Handler extends ExceptionHandler
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $e
*
* @param \Exception $e
* @return void
*/
public function report(Exception $e)
{
return parent::report($e);
parent::report($e);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($this->isHttpException($e)) {
return $this->renderHttpException($e);
}
if (config('app.debug')) {
return $this->renderExceptionWithWhoops($e);
}
return parent::render($request, $e);
}
/**
* Render an exception using Whoops.
*
* @param \Exception $e
*
* @return \Illuminate\Http\Response
*/
protected function renderExceptionWithWhoops(Exception $e)
{
$whoops = new \Whoops\Run();
if (Request::ajax()) {
$whoops->pushHandler(new \Whoops\Handler\JsonResponseHandler());
} else {
$whoops->pushHandler(new \Whoops\Handler\PrettyPageHandler());
}
return new \Illuminate\Http\Response(
$whoops->handleException($e), $e->getStatusCode(), $e->getHeaders()
);
}
}

View File

@ -1,33 +1,37 @@
<?php
/**
* @param int $amount
* @param string $currency_code
* @param int $decimals
* @param string $dec_point
* @param string $thousands_sep
*
* @return string
*/
function money($amount, $currency_code = '', $decimals = 2, $dec_point = '.', $thousands_sep = ',')
{
switch ($currency_code) {
case 'USD':
case 'AUD':
case 'CAD':
$currency_symbol = '$';
break;
case 'EUR':
$currency_symbol = '€';
break;
case 'GBP':
$currency_symbol = '£';
break;
if(!function_exists('money')) {
/**
* @param int $amount
* @param string $currency_code
* @param int $decimals
* @param string $dec_point
* @param string $thousands_sep
*
* @return string
*/
function money($amount, $currency_code = '', $decimals = 2, $dec_point = '.', $thousands_sep = ',')
{
switch ($currency_code) {
case 'USD':
case 'AUD':
case 'CAD':
$currency_symbol = '$';
break;
case 'EUR':
$currency_symbol = '€';
break;
case 'GBP':
$currency_symbol = '£';
break;
default:
$currency_symbol = '';
break;
default:
$currency_symbol = '';
break;
}
return $currency_symbol . number_format($amount, $decimals, $dec_point, $thousands_sep);
}
return $currency_symbol.number_format($amount, $decimals, $dec_point, $thousands_sep);
}

View File

@ -41,7 +41,7 @@ Form::macro('styledFile', function ($name, $multiple = false) {
$out = '<div class="styledFile" id="input-'.$name.'">
<div class="input-group">
<span class="input-group-btn">
<span class="btn btn-primary btn-file">
<span class="btn btn-primary btn-file ">
Browse&hellip; <input name="'.$name.'" type="file" '.($multiple ? 'multiple' : '').'>
</span>
</span>

View File

@ -0,0 +1,20 @@
<?php
namespace app\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\Request;
use Illuminate\Support\Facades\Auth;
class ApiBaseController extends Controller
{
protected $account_id;
public function __construct()
{
$this->account_id = Auth::guard('api')->user()->account_id;
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace app\Http\Controllers\API;
use App\Models\Attendee;
use Illuminate\Http\Request;
class AttendeesApiController extends ApiBaseController
{
/**
* @param Request $request
* @return mixed
*/
public function index(Request $request)
{
return Attendee::scope($this->account_id)->paginate($request->get('per_page', 25));
}
/**
* @param Request $request
* @param $attendee_id
* @return mixed
*/
public function show(Request $request, $attendee_id)
{
if($attendee_id) {
return Attendee::scope($this->account_id)->find($attendee_id);
}
return response('Attendee Not Found', 404);
}
public function store(Request $request) {}
public function update(Request $request) {}
public function destroy(Request $request) {}
}

View File

@ -0,0 +1,39 @@
<?php
namespace app\Http\Controllers\API;
use App\Models\Event;
use Illuminate\Http\Request;
class EventsApiController extends ApiBaseController
{
/**
* @param Request $request
* @return mixed
*/
public function index(Request $request)
{
return Event::scope($this->account_id)->paginate(20);
}
/**
* @param Request $request
* @param $attendee_id
* @return mixed
*/
public function show(Request $request, $attendee_id)
{
if($attendee_id) {
return Event::scope($this->account_id)->find($attendee_id);
}
return response('Event Not Found', 404);
}
public function store(Request $request) {}
public function update(Request $request) {}
public function destroy(Request $request) {}
}

View File

@ -2,11 +2,11 @@
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesCommands;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
abstract class Controller extends BaseController
{
use DispatchesCommands, ValidatesRequests;
use DispatchesJobs, ValidatesRequests;
}

View File

@ -2,8 +2,9 @@
namespace App\Http\Controllers;
use App\Commands\OrderTicketsCommand;
use App\Commands\SendAttendeeTicketCommand;
use App\Mailers\TicketMailer;
use App\Jobs\GenerateTicket;
use App\Commands\MessageAttendeesCommand;
use App\Models\Attendee;
use App\Models\Event;
use App\Models\EventStats;
@ -17,8 +18,9 @@ use DB;
use Excel;
use Mail;
use Response;
use Session;
use Validator;
use Config;
use Log;
class EventAttendeesController extends MyBaseController
{
@ -41,24 +43,24 @@ class EventAttendeesController extends MyBaseController
if ($searchQuery) {
$attendees = $event->attendees()
->withoutCancelled()
->join('orders', 'orders.id', '=', 'attendees.order_id')
->where(function ($query) use ($searchQuery) {
$query->where('orders.order_reference', 'like', $searchQuery.'%')
->orWhere('attendees.first_name', 'like', $searchQuery.'%')
->orWhere('attendees.email', 'like', $searchQuery.'%')
->orWhere('attendees.last_name', 'like', $searchQuery.'%');
})
->orderBy(($sort_by == 'order_reference' ? 'orders.' : 'attendees.').$sort_by, $sort_order)
->select('attendees.*', 'orders.order_reference')
->paginate();
->withoutCancelled()
->join('orders', 'orders.id', '=', 'attendees.order_id')
->where(function ($query) use ($searchQuery) {
$query->where('orders.order_reference', 'like', $searchQuery . '%')
->orWhere('attendees.first_name', 'like', $searchQuery . '%')
->orWhere('attendees.email', 'like', $searchQuery . '%')
->orWhere('attendees.last_name', 'like', $searchQuery . '%');
})
->orderBy(($sort_by == 'order_reference' ? 'orders.' : 'attendees.') . $sort_by, $sort_order)
->select('attendees.*', 'orders.order_reference')
->paginate();
} else {
$attendees = $event->attendees()
->join('orders', 'orders.id', '=', 'attendees.order_id')
->withoutCancelled()
->orderBy(($sort_by == 'order_reference' ? 'orders.' : 'attendees.').$sort_by, $sort_order)
->select('attendees.*', 'orders.order_reference')
->paginate();
->join('orders', 'orders.id', '=', 'attendees.order_id')
->withoutCancelled()
->orderBy(($sort_by == 'order_reference' ? 'orders.' : 'attendees.') . $sort_by, $sort_order)
->select('attendees.*', 'orders.order_reference')
->paginate();
}
$data = [
@ -73,13 +75,13 @@ class EventAttendeesController extends MyBaseController
}
/**
* Show the 'Create Attendee' modal
* Show the 'Invite Attendee' modal
*
* @param Request $request
* @param $event_id
* @return string|View
*/
public function showCreateAttendee(Request $request, $event_id)
public function showInviteAttendee(Request $request, $event_id)
{
$event = Event::scope()->find($event_id);
@ -88,29 +90,27 @@ class EventAttendeesController extends MyBaseController
* @todo This is a bit hackish
*/
if ($event->tickets->count() === 0) {
return '<script>showMessage("You need to create a ticket before you can add an attendee.");</script>';
return '<script>showMessage("You need to create a ticket before you can invite an attendee.");</script>';
}
return view('ManageEvent.Modals.CreateAttendee', [
'modal_id' => $request->get('modal_id'),
'event' => $event,
'tickets' => $event->tickets()->lists('title', 'id'),
return view('ManageEvent.Modals.InviteAttendee', [
'event' => $event,
'tickets' => $event->tickets()->lists('title', 'id'),
]);
}
/**
* Create an attendee
* Invite an attendee
*
* @param Request $request
* @param $event_id
* @return mixed
*/
public function postCreateAttendee(Request $request, $event_id)
public function postInviteAttendee(Request $request, $event_id)
{
$rules = [
'first_name' => 'required',
'ticket_id' => 'required|exists:tickets,id,account_id,'.\Auth::user()->account_id,
'ticket_price' => 'numeric|required',
'ticket_id' => 'required|exists:tickets,id,account_id,' . \Auth::user()->account_id,
'email' => 'email|required',
];
@ -123,75 +123,238 @@ class EventAttendeesController extends MyBaseController
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'messages' => $validator->messages()->toArray(),
'status' => 'error',
'messages' => $validator->messages()->toArray(),
]);
}
$ticket_id = $request->get('ticket_id');
$ticket_price = $request->get('ticket_price');
$attendee_first_name =$request->get('first_name');
$ticket_price = 0;
$attendee_first_name = $request->get('first_name');
$attendee_last_name = $request->get('last_name');
$attendee_email = $request->get('email');
$email_attendee = $request->get('email_ticket');
DB::beginTransaction();
/*
* Create the order
*/
$order = new Order();
$order->first_name = $attendee_first_name;
$order->last_name = $attendee_last_name;
$order->email = $attendee_email;
$order->order_status_id = config('attendize.order_complete');
$order->amount = $ticket_price;
$order->account_id = Auth::user()->account_id;
$order->event_id = $event_id;
$order->save();
try {
/*
* Update qty sold
*/
$ticket = Ticket::scope()->find($ticket_id);
$ticket->increment('quantity_sold');
$ticket->increment('sales_volume', $ticket_price);
$ticket->event->increment('sales_volume', $ticket_price);
/*
* Create the order
*/
$order = new Order();
$order->first_name = $attendee_first_name;
$order->last_name = $attendee_last_name;
$order->email = $attendee_email;
$order->order_status_id = config('attendize.order_complete');
$order->amount = $ticket_price;
$order->account_id = Auth::user()->account_id;
$order->event_id = $event_id;
$order->save();
/*
* Insert order item
*/
$orderItem = new OrderItem();
$orderItem->title = $ticket->title;
$orderItem->quantity = 1;
$orderItem->order_id = $order->id;
$orderItem->unit_price = $ticket_price;
$orderItem->save();
/*
* Update qty sold
*/
$ticket = Ticket::scope()->find($ticket_id);
$ticket->increment('quantity_sold');
$ticket->increment('sales_volume', $ticket_price);
$ticket->event->increment('sales_volume', $ticket_price);
/*
* Update the event stats
*/
$event_stats = new EventStats();
$event_stats->updateTicketsSoldCount($event_id, 1);
$event_stats->updateTicketRevenue($ticket_id, $ticket_price);
/*
* Insert order item
*/
$orderItem = new OrderItem();
$orderItem->title = $ticket->title;
$orderItem->quantity = 1;
$orderItem->order_id = $order->id;
$orderItem->unit_price = $ticket_price;
$orderItem->save();
/*
* Create the attendee
*/
$attendee = new Attendee();
$attendee->first_name = $attendee_first_name;
$attendee->last_name = $attendee_last_name;
$attendee->email = $attendee_email;
$attendee->event_id = $event_id;
$attendee->order_id = $order->id;
$attendee->ticket_id = $ticket_id;
$attendee->account_id = Auth::user()->account_id;
$attendee->reference = $order->order_reference.'-1';
$attendee->save();
/*
* Update the event stats
*/
$event_stats = new EventStats();
$event_stats->updateTicketsSoldCount($event_id, 1);
$event_stats->updateTicketRevenue($ticket_id, $ticket_price);
if ($email_attendee == '1') {
$this->dispatch(new OrderTicketsCommand($order, false));
/*
* Create the attendee
*/
$attendee = new Attendee();
$attendee->first_name = $attendee_first_name;
$attendee->last_name = $attendee_last_name;
$attendee->email = $attendee_email;
$attendee->event_id = $event_id;
$attendee->order_id = $order->id;
$attendee->ticket_id = $ticket_id;
$attendee->account_id = Auth::user()->account_id;
$attendee->reference_index = 1;
$attendee->save();
$this->dispatch(new GenerateTicket($order->order_reference."-".$attendee->reference_index));
if ($email_attendee == '1') {
TicketMailer::sendAttendeeInvite($attendee);
}
session()->flash('message', 'Attendee Successfully Invited');
DB::commit();
return response()->json([
'status' => 'success',
'redirectUrl' => route('showEventAttendees', [
'event_id' => $event_id,
]),
]);
} catch (Exception $e) {
Log::error($e);
DB::rollBack();
return response()->json([
'status' => 'error',
'error' => 'An error occurred while inviting this attendee. Please try again.'
]);
}
session()->flash('message', 'Attendee Successfully Created');
}
/**
* Show the 'Import Attendee' modal
*
* @param Request $request
* @param $event_id
* @return string|View
*/
public function showImportAttendee(Request $request, $event_id)
{
$event = Event::scope()->find($event_id);
/*
* If there are no tickets then we can't create an attendee
* @todo This is a bit hackish
*/
if ($event->tickets->count() === 0) {
return '<script>showMessage("You need to create a ticket before you can add an attendee.");</script>';
}
return view('ManageEvent.Modals.ImportAttendee', [
'event' => $event,
'tickets' => $event->tickets()->lists('title', 'id'),
]);
}
/**
* Import attendees
*
* @param Request $request
* @param $event_id
* @return mixed
*/
public function postImportAttendee(Request $request, $event_id)
{
$rules = [
'ticket_id' => 'required|exists:tickets,id,account_id,' . \Auth::user()->account_id,
'attendees_list' => 'required|mimes:csv,txt|max:5000|',
];
$messages = [
'ticket_id.exists' => 'The ticket you have selected does not exist',
];
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'messages' => $validator->messages()->toArray(),
]);
}
$ticket_id = $request->get('ticket_id');
$ticket_price = 0;
$email_attendee = $request->get('email_ticket');
$num_added = 0;
if ($request->file('attendees_list')) {
$the_file = Excel::load($request->file('attendees_list')->getRealPath(), function ($reader) {
})->get();
// Loop through
foreach ($the_file as $rows) {
if (!empty($rows['first_name']) && !empty($rows['last_name']) && !empty($rows['email'])) {
$num_added++;
$attendee_first_name = $rows['first_name'];
$attendee_last_name = $rows['last_name'];
$attendee_email = $rows['email'];
error_log($ticket_id . ' ' . $ticket_price . ' ' . $email_attendee);
/**
* Create the order
*/
$order = new Order();
$order->first_name = $attendee_first_name;
$order->last_name = $attendee_last_name;
$order->email = $attendee_email;
$order->order_status_id = config('attendize.order_complete');
$order->amount = $ticket_price;
$order->account_id = Auth::user()->account_id;
$order->event_id = $event_id;
$order->save();
/**
* Update qty sold
*/
$ticket = Ticket::scope()->find($ticket_id);
$ticket->increment('quantity_sold');
$ticket->increment('sales_volume', $ticket_price);
$ticket->event->increment('sales_volume', $ticket_price);
/**
* Insert order item
*/
$orderItem = new OrderItem();
$orderItem->title = $ticket->title;
$orderItem->quantity = 1;
$orderItem->order_id = $order->id;
$orderItem->unit_price = $ticket_price;
$orderItem->save();
/**
* Update the event stats
*/
$event_stats = new EventStats();
$event_stats->updateTicketsSoldCount($event_id, 1);
$event_stats->updateTicketRevenue($ticket_id, $ticket_price);
/**
* Create the attendee
*/
$attendee = new Attendee();
$attendee->first_name = $attendee_first_name;
$attendee->last_name = $attendee_last_name;
$attendee->email = $attendee_email;
$attendee->event_id = $event_id;
$attendee->order_id = $order->id;
$attendee->ticket_id = $ticket_id;
$attendee->account_id = Auth::user()->account_id;
$attendee->reference_index = 1;
$attendee->save();
$this->dispatch(new GenerateTicket($attendee->getReferenceAttribute()));
if ($email_attendee == '1') {
TicketMailer::sendAttendeeInvite($attendee);
}
}
};
}
session()->flash('message', $num_added . ' Attendees Successfully Invited');
return response()->json([
'status' => 'success',
@ -230,7 +393,6 @@ class EventAttendeesController extends MyBaseController
$data = [
'attendee' => $attendee,
'event' => $attendee->event,
'modal_id' => $request->get('modal_id'),
];
return view('ManageEvent.Modals.MessageAttendee', $data);
@ -254,8 +416,8 @@ class EventAttendeesController extends MyBaseController
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'messages' => $validator->messages()->toArray(),
'status' => 'error',
'messages' => $validator->messages()->toArray(),
]);
}
@ -271,18 +433,18 @@ class EventAttendeesController extends MyBaseController
Mail::send('Emails.messageAttendees', $data, function ($message) use ($attendee, $data) {
$message->to($attendee->email, $attendee->full_name)
->from(config('attendize.outgoing_email_noreply'), $attendee->event->organiser->name)
->replyTo($attendee->event->organiser->email, $attendee->event->organiser->name)
->subject($data['subject']);
->from(config('attendize.outgoing_email_noreply'), $attendee->event->organiser->name)
->replyTo($attendee->event->organiser->email, $attendee->event->organiser->name)
->subject($data['subject']);
});
/* Could bcc in the above? */
if ($request->get('send_copy') == '1') {
Mail::send('Emails.messageAttendees', $data, function ($message) use ($attendee, $data) {
$message->to($attendee->event->organiser->email, $attendee->event->organiser->name)
->from(config('attendize.outgoing_email_noreply'), $attendee->event->organiser->name)
->replyTo($attendee->event->organiser->email, $attendee->event->organiser->name)
->subject($data['subject'].'[ORGANISER COPY]');
->from(config('attendize.outgoing_email_noreply'), $attendee->event->organiser->name)
->replyTo($attendee->event->organiser->email, $attendee->event->organiser->name)
->subject($data['subject'] . '[ORGANISER COPY]');
});
}
@ -301,9 +463,8 @@ class EventAttendeesController extends MyBaseController
public function showMessageAttendees(Request $request, $event_id)
{
$data = [
'event' => Event::scope()->find($event_id),
'modal_id' => $request->get('modal_id'),
'tickets' => Event::scope()->find($event_id)->tickets()->lists('title', 'id')->toArray(),
'event' => Event::scope()->find($event_id),
'tickets' => Event::scope()->find($event_id)->tickets()->lists('title', 'id')->toArray(),
];
return view('ManageEvent.Modals.MessageAttendees', $data);
@ -328,21 +489,21 @@ class EventAttendeesController extends MyBaseController
if ($validator->fails()) {
return Response::json([
'status' => 'error',
'messages' => $validator->messages()->toArray(),
'status' => 'error',
'messages' => $validator->messages()->toArray(),
]);
}
$message = Message::createNew();
$message->message = $request->get('message');
$message->subject = $request->get('subject');
$message->recipients = $request->get('recipients');
if ($request->get('recipients') != "all") {
$message->recipients = $request->get('recipients');
}
$message->event_id = $event_id;
$message->save();
/*
* Add to the queue
*/
$this->dispatch(new MessageAttendeesCommand($message));
return response()->json([
'status' => 'success',
@ -350,6 +511,32 @@ class EventAttendeesController extends MyBaseController
]);
}
/**
* Downloads the ticket of an attendee as PDF
*
* @param $event_id
* @param $attendee_id
*/
public function showExportTicket($event_id, $attendee_id)
{
$attendee = Attendee::scope()->findOrFail($attendee_id);
Config::set('queue.default', 'sync');
Log::info("*********");
Log::info($attendee_id);
Log::info($attendee);
$this->dispatch(new GenerateTicket($attendee->order->order_reference."-".$attendee->reference_index));
$pdf_file_name = $attendee->order->order_reference.'-'.$attendee->reference_index;
$pdf_file_path = public_path(config('attendize.event_pdf_tickets_path')).'/'.$pdf_file_name;
$pdf_file = $pdf_file_path.'.pdf';
return response()->download($pdf_file);
}
/**
* Downloads an export of attendees
*
@ -358,13 +545,14 @@ class EventAttendeesController extends MyBaseController
*/
public function showExportAttendees($event_id, $export_as = 'xls')
{
Excel::create('attendees-as-of-'.date('d-m-Y-g.i.a'), function ($excel) use ($event_id) {
Excel::create('attendees-as-of-' . date('d-m-Y-g.i.a'), function ($excel) use ($event_id) {
$excel->setTitle('Attendees List');
// Chain the setters
$excel->setCreator(config('attendize.app_name'))
->setCompany(config('attendize.app_name'));
->setCompany(config('attendize.app_name'));
$excel->sheet('attendees_sheet_1', function ($sheet) use ($event_id) {
@ -372,18 +560,31 @@ class EventAttendeesController extends MyBaseController
$data = DB::table('attendees')
->where('attendees.event_id', '=', $event_id)
->where('attendees.is_cancelled', '=', 0)
->where('attendees.account_id', '=', Auth::user()->account_id)
->join('events', 'events.id', '=', 'attendees.event_id')
->join('orders', 'orders.id', '=', 'attendees.order_id')
->join('tickets', 'tickets.id', '=', 'attendees.ticket_id')
->select(
'attendees.first_name', 'attendees.last_name', 'attendees.email', 'attendees.reference', 'orders.order_reference', 'tickets.title', 'orders.created_at', DB::raw("(CASE WHEN attendees.has_arrived = 1 THEN 'YES' ELSE 'NO' END) AS `attendees.has_arrived`"), 'attendees.arrival_time')->get();
//DB::raw("(CASE WHEN UNIX_TIMESTAMP(`attendees.arrival_time`) = 0 THEN '---' ELSE 'd' END) AS `attendees.arrival_time`"))
->where('attendees.account_id', '=', Auth::user()->account_id)
->join('events', 'events.id', '=', 'attendees.event_id')
->join('orders', 'orders.id', '=', 'attendees.order_id')
->join('tickets', 'tickets.id', '=', 'attendees.ticket_id')
->select([
'attendees.first_name',
'attendees.last_name',
'attendees.email',
'orders.order_reference',
'tickets.title',
'orders.created_at',
DB::raw("(CASE WHEN attendees.has_arrived THEN 'YES' ELSE 'NO' END) AS has_arrived"),
'attendees.arrival_time',
])->get();
$sheet->fromArray($data);
$sheet->row(1, [
'First Name', 'Last Name', 'Email', 'Ticket Reference', 'Order Reference', 'Ticket Type', 'Purchase Date', 'Has Arrived', 'Arrival Time',
'First Name',
'Last Name',
'Email',
'Order Reference',
'Ticket Type',
'Purchase Date',
'Has Arrived',
'Arrival Time',
]);
// Set gray background on first row
@ -410,7 +611,6 @@ class EventAttendeesController extends MyBaseController
'attendee' => $attendee,
'event' => $attendee->event,
'tickets' => $attendee->event->tickets->lists('title', 'id'),
'modal_id' => $request->get('modal_id'),
];
return view('ManageEvent.Modals.EditAttendee', $data);
@ -428,7 +628,7 @@ class EventAttendeesController extends MyBaseController
{
$rules = [
'first_name' => 'required',
'ticket_id' => 'required|exists:tickets,id,account_id,'.Auth::user()->account_id,
'ticket_id' => 'required|exists:tickets,id,account_id,' . Auth::user()->account_id,
'email' => 'required|email',
];
@ -441,8 +641,8 @@ class EventAttendeesController extends MyBaseController
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'messages' => $validator->messages()->toArray(),
'status' => 'error',
'messages' => $validator->messages()->toArray(),
]);
}
@ -474,7 +674,6 @@ class EventAttendeesController extends MyBaseController
'attendee' => $attendee,
'event' => $attendee->event,
'tickets' => $attendee->event->tickets->lists('title', 'id'),
'modal_id' => $request->get('modal_id'),
];
return view('ManageEvent.Modals.CancelAttendee', $data);
@ -494,8 +693,8 @@ class EventAttendeesController extends MyBaseController
if ($attendee->is_cancelled) {
return Response::json([
'status' => 'success',
'message' => 'Attendee Already Cancelled',
'status' => 'success',
'message' => 'Attendee Already Cancelled',
]);
}
@ -511,9 +710,9 @@ class EventAttendeesController extends MyBaseController
if ($request->get('notify_attendee') == '1') {
Mail::send('Emails.notifyCancelledAttendee', $data, function ($message) use ($attendee) {
$message->to($attendee->email, $attendee->full_name)
->from(config('attendize.outgoing_email_noreply'), $attendee->event->organiser->name)
->replyTo($attendee->event->organiser->email, $attendee->event->organiser->name)
->subject('You\'re ticket has been cancelled');
->from(config('attendize.outgoing_email_noreply'), $attendee->event->organiser->name)
->replyTo($attendee->event->organiser->email, $attendee->event->organiser->name)
->subject('You\'re ticket has been cancelled');
});
}
@ -540,7 +739,6 @@ class EventAttendeesController extends MyBaseController
$data = [
'attendee' => $attendee,
'event' => $attendee->event,
'modal_id' => $request->get('modal_id'),
];
return view('ManageEvent.Modals.ResendTicketToAttendee', $data);
@ -557,7 +755,8 @@ class EventAttendeesController extends MyBaseController
{
$attendee = Attendee::scope()->findOrFail($attendee_id);
$this->dispatch(new SendAttendeeTicketCommand($attendee));
$this->dispatch(new GenerateTicket($attendee->getReferenceAttribute()));
TicketMailer::sendAttendeeTicket($attendee);
return response()->json([
'status' => 'success',

View File

@ -7,6 +7,7 @@ use App\Models\Attendee;
use App\Models\Event;
use Carbon\Carbon;
use DB;
use JavaScript;
class EventCheckInController extends MyBaseController
{
@ -18,12 +19,28 @@ class EventCheckInController extends MyBaseController
*/
public function showCheckIn($event_id)
{
$data['event'] = Event::scope()->findOrFail($event_id);
$data['attendees'] = $data['event']->attendees;
$event = Event::scope()->findOrFail($event_id);
$data = [
'event' => $event,
'attendees' => $event->attendees
];
JavaScript::put([
'qrcodeCheckInRoute' => route('postQRCodeCheckInAttendee', ['event_id' => $event->id]),
'checkInRoute' => route('postCheckInAttendee', ['event_id' => $event->id]),
'checkInSearchRoute' => route('postCheckInSearch', ['event_id' => $event->id]),
]);
return view('ManageEvent.CheckIn', $data);
}
public function showQRCodeModal(Request $request, $event_id)
{
return view('ManageEvent.Modals.QrcodeCheckIn');
}
/**
* Search attendees
*
@ -36,28 +53,30 @@ class EventCheckInController extends MyBaseController
$searchQuery = $request->get('q');
$attendees = Attendee::scope()->withoutCancelled()
->join('tickets', 'tickets.id', '=', 'attendees.ticket_id')
->where(function ($query) use ($event_id) {
$query->where('attendees.event_id', '=', $event_id);
})->where(function ($query) use ($searchQuery) {
$query->orWhere('attendees.first_name', 'like', $searchQuery.'%')
->orWhere(DB::raw("CONCAT_WS(' ', first_name, last_name)"), 'like', $searchQuery.'%')
->join('tickets', 'tickets.id', '=', 'attendees.ticket_id')
->join('orders', 'orders.id', '=', 'attendees.order_id')
->where(function ($query) use ($event_id) {
$query->where('attendees.event_id', '=', $event_id);
})->where(function ($query) use ($searchQuery) {
$query->orWhere('attendees.first_name', 'like', $searchQuery . '%')
->orWhere(DB::raw("CONCAT_WS(' ', attendees.first_name, attendees.last_name)"), 'like', $searchQuery . '%')
//->orWhere('attendees.email', 'like', $searchQuery . '%')
->orWhere('attendees.reference', 'like', $searchQuery.'%')
->orWhere('attendees.last_name', 'like', $searchQuery.'%');
})
->select([
'attendees.id',
'attendees.first_name',
'attendees.last_name',
'attendees.email',
'attendees.reference',
'attendees.arrival_time',
'attendees.has_arrived',
'tickets.title as ticket',
])
->orderBy('attendees.first_name', 'ASC')
->get();
->orWhere('orders.order_reference', 'like', $searchQuery . '%')
->orWhere('attendees.last_name', 'like', $searchQuery . '%');
})
->select([
'attendees.id',
'attendees.first_name',
'attendees.last_name',
'attendees.email',
'attendees.arrival_time',
'attendees.reference_index',
'attendees.has_arrived',
'tickets.title as ticket',
'orders.order_reference'
])
->orderBy('attendees.first_name', 'ASC')
->get();
return response()->json($attendees);
}
@ -71,7 +90,7 @@ class EventCheckInController extends MyBaseController
public function postCheckInAttendee(Request $request)
{
$attendee_id = $request->get('attendee_id');
$checking = $request->get('checking');
$checking = $request->get('checking');
$attendee = Attendee::scope()->find($attendee_id);
@ -80,10 +99,10 @@ class EventCheckInController extends MyBaseController
*/
if ((($checking == 'in') && ($attendee->has_arrived == 1)) || (($checking == 'out') && ($attendee->has_arrived == 0))) {
return response()->json([
'status' => 'error',
'message' => 'Warning: This Attendee Has Already Been Checked '.(($checking == 'in') ? 'In (at '.$attendee->arrival_time->format('H:i A, F j').')' : 'Out').'!',
'checked' => $checking,
'id' => $attendee->id,
'status' => 'error',
'message' => 'Attendee Already Checked ' . (($checking == 'in') ? 'In (at ' . $attendee->arrival_time->format('H:i A, F j') . ')' : 'Out') . '!',
'checked' => $checking,
'id' => $attendee->id,
]);
}
@ -92,10 +111,103 @@ class EventCheckInController extends MyBaseController
$attendee->save();
return response()->json([
'status' => 'success',
'checked' => $checking,
'message' => 'Attendee Successfully Checked '.(($checking == 'in') ? 'In' : 'Out'),
'id' => $attendee->id,
'status' => 'success',
'checked' => $checking,
'message' => 'Attendee Successfully Checked ' . (($checking == 'in') ? 'In' : 'Out'),
'id' => $attendee->id,
]);
}
/**
* Check in an attendee
*
* @param $event_id
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function postCheckInAttendeeQr($event_id, Request $request)
{
$event = Event::scope()->findOrFail($event_id);
$qrcodeToken = $request->get('attendee_reference');
$attendee = Attendee::scope()->withoutCancelled()
->join('tickets', 'tickets.id', '=', 'attendees.ticket_id')
->where(function ($query) use ($event, $qrcodeToken) {
$query->where('attendees.event_id', $event->id)
->where('attendees.private_reference_number', $qrcodeToken);
})->select([
'attendees.id',
'attendees.order_id',
'attendees.first_name',
'attendees.last_name',
'attendees.email',
'attendees.reference',
'attendees.arrival_time',
'attendees.has_arrived',
'tickets.title as ticket',
])->first();
if (is_null($attendee)) {
return response()->json([
'status' => 'error',
'message' => "Invalid Ticket! Please try again."
]);
}
$relatedAttendesCount = Attendee::where('id', '!=', $attendee->id)
->where([
'order_id' => $attendee->order_id,
'has_arrived' => false
])->count();
if ($relatedAttendesCount >= 1) {
$confirmOrderTicketsRoute = route('confirmCheckInOrderTickets', [$event->id, $attendee->order_id]);
/*
* @todo Incorporate this feature into the new design
*/
//$appendedText = '<br><br><form class="ajax" action="' . $confirmOrderTicketsRoute . '" method="POST">' . csrf_field() . '<button class="btn btn-primary btn-sm" type="submit"><i class="ico-ticket"></i> Check in all tickets associated to this order</button></form>';
} else {
$appendedText = '';
}
if ($attendee->has_arrived) {
return response()->json([
'status' => 'error',
'message' => 'Attendee already checked in at ' . $attendee->arrival_time->format('H:i A, F j') . $appendedText
]);
}
Attendee::find($attendee->id)->update(['has_arrived' => true, 'arrival_time' => Carbon::now()]);
return response()->json([
'status' => 'success',
'message' => 'Success !<br>Name: ' . $attendee->first_name . ' ' . $attendee->last_name . '<br>Reference: ' . $attendee->reference . '<br>Ticket: ' . $attendee->ticket . '.' . $appendedText
]);
}
/**
* Confirm tickets of same order.
*
* @param $event_id
* @param $order_id
* @return \Illuminate\Http\Response
*/
public function confirmOrderTicketsQr($event_id, $order_id)
{
$updateRowsCount = Attendee::scope()->where([
'event_id' => $event_id,
'order_id' => $order_id,
'has_arrived' => 0,
])->update([
'has_arrived' => 1,
'arrival_time' => Carbon::now(),
]);
return response()->json([
'message' => $updateRowsCount . ' Attendee(s) Checked in.'
]);
}
}

View File

@ -2,8 +2,8 @@
namespace App\Http\Controllers;
use App;
use App\Commands\OrderTicketsCommand;
use App\Jobs\GenerateTicket;
use App\Mailers\TicketMailer;
use App\Models\Affiliate;
use App\Models\Attendee;
use App\Models\Event;
@ -11,14 +11,16 @@ use App\Models\EventStats;
use App\Models\Order;
use App\Models\OrderItem;
use App\Models\ReservedTickets;
use App\Models\QuestionAnswer;
use App\Models\Ticket;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Cookie;
use DB;
use Illuminate\Http\Request;
use Log;
use Omnipay;
use PDF;
use PhpSpec\Exception\Exception;
use Validator;
class EventCheckoutController extends Controller
@ -80,7 +82,7 @@ class EventCheckoutController extends Controller
$quantity_available_validation_rules = [];
foreach ($ticket_ids as $ticket_id) {
$current_ticket_quantity = (int) $request->get('ticket_'.$ticket_id);
$current_ticket_quantity = (int)$request->get('ticket_' . $ticket_id);
if ($current_ticket_quantity < 1) {
continue;
@ -92,19 +94,22 @@ class EventCheckoutController extends Controller
$ticket_quantity_remaining = $ticket->quantity_remaining;
/*
* @todo Check max/min per person
*/
$max_per_person = min($ticket_quantity_remaining, $ticket->max_per_person);
$quantity_available_validation_rules['ticket_'.$ticket_id] = ['numeric', 'min:'.$ticket->min_per_person, 'max:'.$max_per_person];
$quantity_available_validation_messages = [
'ticket_'.$ticket_id.'.max' => 'The maximum number of tickets you can register is '.$ticket_quantity_remaining,
'ticket_'.$ticket_id.'.min' => 'You must select at least '.$ticket->min_per_person.' tickets.',
$quantity_available_validation_rules['ticket_' . $ticket_id] = [
'numeric',
'min:' . $ticket->min_per_person,
'max:' . $max_per_person
];
$validator = Validator::make(['ticket_'.$ticket_id => (int) $request->get('ticket_'.$ticket_id)], $quantity_available_validation_rules, $quantity_available_validation_messages);
$quantity_available_validation_messages = [
'ticket_' . $ticket_id . '.max' => 'The maximum number of tickets you can register is ' . $ticket_quantity_remaining,
'ticket_' . $ticket_id . '.min' => 'You must select at least ' . $ticket->min_per_person . ' tickets.',
];
$validator = Validator::make(['ticket_' . $ticket_id => (int)$request->get('ticket_' . $ticket_id)],
$quantity_available_validation_rules, $quantity_available_validation_messages);
if ($validator->fails()) {
return response()->json([
@ -127,7 +132,7 @@ class EventCheckoutController extends Controller
];
/*
* Reserve the tickets in the DB
* Reserve the tickets for X amount of minutes
*/
$reservedTickets = new ReservedTickets();
$reservedTickets->ticket_id = $ticket_id;
@ -137,21 +142,33 @@ class EventCheckoutController extends Controller
$reservedTickets->session_id = session()->getId();
$reservedTickets->save();
if ($event->ask_for_all_attendees_info) {
for ($i = 0; $i < $current_ticket_quantity; $i++) {
/*
* Create our validation rules here
*/
$validation_rules['ticket_holder_first_name.'.$i.'.'.$ticket_id] = ['required'];
$validation_rules['ticket_holder_last_name.'.$i.'.'.$ticket_id] = ['required'];
$validation_rules['ticket_holder_email.'.$i.'.'.$ticket_id] = ['required', 'email'];
for ($i = 0; $i < $current_ticket_quantity; $i++) {
/*
* Create our validation rules here
*/
$validation_rules['ticket_holder_first_name.' . $i . '.' . $ticket_id] = ['required'];
$validation_rules['ticket_holder_last_name.' . $i . '.' . $ticket_id] = ['required'];
$validation_rules['ticket_holder_email.' . $i . '.' . $ticket_id] = ['required', 'email'];
$validation_messages['ticket_holder_first_name.' . $i . '.' . $ticket_id . '.required'] = 'Ticket holder ' . ($i + 1) . '\'s first name is required';
$validation_messages['ticket_holder_last_name.' . $i . '.' . $ticket_id . '.required'] = 'Ticket holder ' . ($i + 1) . '\'s last name is required';
$validation_messages['ticket_holder_email.' . $i . '.' . $ticket_id . '.required'] = 'Ticket holder ' . ($i + 1) . '\'s email is required';
$validation_messages['ticket_holder_email.' . $i . '.' . $ticket_id . '.email'] = 'Ticket holder ' . ($i + 1) . '\'s email appears to be invalid';
/*
* Validation rules for custom questions
*/
foreach ($ticket->questions as $question) {
if ($question->is_required && $question->is_enabled) {
$validation_rules['ticket_holder_questions.' . $ticket_id . '.' . $i . '.' . $question->id] = ['required'];
$validation_messages['ticket_holder_questions.' . $ticket_id . '.' . $i . '.' . $question->id . '.required'] = "This question is required";
}
$validation_messages['ticket_holder_first_name.'.$i.'.'.$ticket_id.'.required'] = 'Ticket holder '.($i + 1).'\'s first name is required';
$validation_messages['ticket_holder_last_name.'.$i.'.'.$ticket_id.'.required'] = 'Ticket holder '.($i + 1).'\'s last name is required';
$validation_messages['ticket_holder_email.'.$i.'.'.$ticket_id.'.required'] = 'Ticket holder '.($i + 1).'\'s email is required';
$validation_messages['ticket_holder_email.'.$i.'.'.$ticket_id.'.email'] = 'Ticket holder '.($i + 1).'\'s email appears to be invalid';
}
}
}
if (empty($tickets)) {
@ -162,35 +179,39 @@ class EventCheckoutController extends Controller
}
/*
* @todo - Store this in something other than a session?
* The 'ticket_order' session stores everything we need to complete the transaction.
*/
session()->set('ticket_order_'.$event->id, [
'validation_rules' => $validation_rules,
'validation_messages' => $validation_messages,
'event_id' => $event->id,
'tickets' => $tickets, /* probably shouldn't store the whole ticket obj in session */
'total_ticket_quantity' => $total_ticket_quantity,
'order_started' => time(),
'expires' => $order_expires_time,
'reserved_tickets_id' => $reservedTickets->id,
'order_total' => $order_total,
'booking_fee' => $booking_fee,
'organiser_booking_fee' => $organiser_booking_fee,
'total_booking_fee' => $booking_fee + $organiser_booking_fee,
'order_requires_payment' => (ceil($order_total) == 0) ? false : true,
'account_id' => $event->account->id,
'affiliate_referral' => Cookie::get('affiliate_'.$event_id),
'account_payment_gateway' => $event->account->active_payment_gateway->exists() ? $event->account->active_payment_gateway : false,
'payment_gateway' => $event->account->active_payment_gateway->payment_gateway->exists() ? $event->account->active_payment_gateway->payment_gateway : false,
session()->set('ticket_order_' . $event->id, [
'validation_rules' => $validation_rules,
'validation_messages' => $validation_messages,
'event_id' => $event->id,
'tickets' => $tickets,
'total_ticket_quantity' => $total_ticket_quantity,
'order_started' => time(),
'expires' => $order_expires_time,
'reserved_tickets_id' => $reservedTickets->id,
'order_total' => $order_total,
'booking_fee' => $booking_fee,
'organiser_booking_fee' => $organiser_booking_fee,
'total_booking_fee' => $booking_fee + $organiser_booking_fee,
'order_requires_payment' => (ceil($order_total) == 0) ? false : true,
'account_id' => $event->account->id,
'affiliate_referral' => Cookie::get('affiliate_' . $event_id),
'account_payment_gateway' => count($event->account->active_payment_gateway) ? $event->account->active_payment_gateway : false,
'payment_gateway' => count($event->account->active_payment_gateway) ? $event->account->active_payment_gateway->payment_gateway : false,
]);
/*
* If we're this far assume everything is OK and redirect them
* to the the checkout page.
*/
if ($request->ajax()) {
return response()->json([
'status' => 'success',
'redirectUrl' => route('showEventCheckout', [
'event_id' => $event_id,
'is_embedded' => $this->is_embedded,
]).'#order_form',
]) . '#order_form',
]);
}
@ -206,8 +227,7 @@ class EventCheckoutController extends Controller
*/
public function showEventCheckout(Request $request, $event_id)
{
$order_session = session()->get('ticket_order_'.$event_id);
$order_session = session()->get('ticket_order_' . $event_id);
if (!$order_session || $order_session['expires'] < Carbon::now()) {
return redirect()->route('showEventPage', ['event_id' => $event_id]);
@ -237,19 +257,29 @@ class EventCheckoutController extends Controller
*/
public function postCreateOrder(Request $request, $event_id)
{
$mirror_buyer_info = ($request->get('mirror_buyer_info') == 'on');
/*
* If there's no session kill the request and redirect back to the event homepage.
*/
if (!session()->get('ticket_order_' . $event_id)) {
return response()->json([
'status' => 'error',
'message' => 'Your session has expired.',
'redirectUrl' => route('showEventPage', [
'event_id' => $event_id,
])
]);
}
$event = Event::findOrFail($event_id);
$order = new Order;
$ticket_order = session()->get('ticket_order_'.$event_id);
$ticket_order = session()->get('ticket_order_' . $event_id);
$validation_rules = $ticket_order['validation_rules'];
$validation_messages = $ticket_order['validation_messages'];
if (!$mirror_buyer_info && $event->ask_for_all_attendees_info) {
$order->rules = $order->rules + $validation_rules;
$order->messages = $order->messages + $validation_messages;
}
$order->rules = $order->rules + $validation_rules;
$order->messages = $order->messages + $validation_messages;
if (!$order->validate($request->all())) {
return response()->json([
@ -261,7 +291,7 @@ class EventCheckoutController extends Controller
/*
* Add the request data to a session in case payment is required off-site
*/
session()->push('ticket_order_' . $event_id .'.request_data', $request->except(['card-number', 'card-cvc']));
session()->push('ticket_order_' . $event_id . '.request_data', $request->except(['card-number', 'card-cvc']));
/*
* Begin payment attempt before creating the attendees etc.
@ -275,16 +305,16 @@ class EventCheckoutController extends Controller
'testMode' => config('attendize.enable_test_payments'),
]);
switch($ticket_order['payment_gateway']->id) {
switch ($ticket_order['payment_gateway']->id) {
case config('attendize.payment_gateway_paypal'):
case config('attendize.payment_gateway_coinbase'):
$transaction_data = [
'cancelUrl' => route('showEventCheckoutPaymentReturn' , [
$transaction_data = [
'cancelUrl' => route('showEventCheckoutPaymentReturn', [
'event_id' => $event_id,
'is_payment_cancelled' => 1
]),
'returnUrl' => route('showEventCheckoutPaymentReturn' , [
'returnUrl' => route('showEventCheckoutPaymentReturn', [
'event_id' => $event_id,
'is_payment_successful' => 1
]),
@ -312,7 +342,7 @@ class EventCheckoutController extends Controller
$transaction_data = [
'amount' => ($ticket_order['order_total'] + $ticket_order['organiser_booking_fee']),
'currency' => $event->currency->code,
'description' => 'Order for customer: '.$request->get('order_email'),
'description' => 'Order for customer: ' . $request->get('order_email'),
] + $transaction_data;
$transaction = $gateway->purchase($transaction_data);
@ -321,7 +351,8 @@ class EventCheckoutController extends Controller
if ($response->isSuccessful()) {
session()->push('ticket_order_' . $event_id .'.transaction_id', $response->getTransactionReference());
session()->push('ticket_order_' . $event_id . '.transaction_id', $response->getTransactionReference());
return $this->completeOrder($event_id);
} elseif ($response->isRedirect()) {
@ -329,7 +360,7 @@ class EventCheckoutController extends Controller
/*
* As we're going off-site for payment we need to store some into in a session
*/
session()->push('ticket_order_' . $event_id .'.transaction_data', $transaction_data);
session()->push('ticket_order_' . $event_id . '.transaction_data', $transaction_data);
return response()->json([
'status' => 'success',
@ -367,13 +398,21 @@ class EventCheckoutController extends Controller
}
/**
* Attempt to complete a user's payment when they return from
* an off-site gateway
*
* @param Request $request
* @param $event_id
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
*/
public function showEventCheckoutPaymentReturn(Request $request, $event_id)
{
if($request->get('is_payment_cancelled') == '1') {
if ($request->get('is_payment_cancelled') == '1') {
session()->flash('message', 'You cancelled your payment. You may try again.');
return response()->redirectToRoute('showEventCheckout', [
'event_id' => $event_id,
'event_id' => $event_id,
'is_payment_cancelled' => 1,
]);
}
@ -390,19 +429,18 @@ class EventCheckoutController extends Controller
$response = $transaction->send();
if ($response->isSuccessful()) {
session()->push('ticket_order_' . $event_id .'.transaction_id', $response->getTransactionReference());
session()->push('ticket_order_' . $event_id . '.transaction_id', $response->getTransactionReference());
return $this->completeOrder($event_id, false);
} else {
session()->flash('message', $response->getMessage());
return response()->redirectToRoute('showEventCheckout', [
'event_id' => $event_id,
'event_id' => $event_id,
'is_payment_failed' => 1,
]);
}
}
/**
* Complete an order
*
@ -410,134 +448,183 @@ class EventCheckoutController extends Controller
* @param bool|true $return_json
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
*/
public function completeOrder($event_id, $return_json=true)
public function completeOrder($event_id, $return_json = true)
{
$order = new Order();
$ticket_order = session()->get('ticket_order_' . $event_id);
$request_data = $ticket_order['request_data'][0];
$event = Event::findOrFail($ticket_order['event_id']);
$attendee_increment = 1;
$mirror_buyer_info = isset($request_data['mirror_buyer_info']) ? ($request_data['mirror_buyer_info'] == 'on') : false;
DB::beginTransaction();
/*
* Create the order
*/
if(isset($ticket_order['transaction_id']))
{
$order->transaction_id = $ticket_order['transaction_id'][0];
}
if($ticket_order['order_requires_payment']) {
$order->payment_gateway_id = $ticket_order['payment_gateway']->id;
}
$order->first_name = $request_data['order_first_name'];
$order->last_name = $request_data['order_last_name'];
$order->email = $request_data['order_email'];
$order->order_status_id = config('attendize.order_complete');
$order->amount = $ticket_order['order_total'];
$order->booking_fee = $ticket_order['booking_fee'];
$order->organiser_booking_fee = $ticket_order['organiser_booking_fee'];
$order->discount = 0.00;
$order->account_id = $event->account->id;
$order->event_id = $ticket_order['event_id'];
$order->save();
try {
/*
* Update the event sales volume
*/
$event->increment('sales_volume', $order->amount);
$event->increment('organiser_fees_volume', $order->organiser_booking_fee);
$order = new Order();
$ticket_order = session()->get('ticket_order_' . $event_id);
$request_data = $ticket_order['request_data'][0];
$event = Event::findOrFail($ticket_order['event_id']);
$attendee_increment = 1;
$ticket_questions = isset($request_data['ticket_holder_questions']) ? $request_data['ticket_holder_questions'] : [];
/*
* Update affiliates stats stats
*/
if ($ticket_order['affiliate_referral']) {
$affiliate = Affiliate::where('name', '=', $ticket_order['affiliate_referral'])
->where('event_id', '=', $event_id)->first();
$affiliate->increment('sales_volume', $order->amount + $order->organiser_booking_fee);
$affiliate->increment('tickets_sold', $ticket_order['total_ticket_quantity']);
}
/*
* Update the event stats
*/
$event_stats = EventStats::firstOrNew([
'event_id' => $event_id,
'date' => DB::raw('CURDATE()'),
]);
$event_stats->increment('tickets_sold', $ticket_order['total_ticket_quantity']);
if ($ticket_order['order_requires_payment']) {
$event_stats->increment('sales_volume', $order->amount);
$event_stats->increment('organiser_fees_volume', $order->organiser_booking_fee);
}
/*
* Add the attendees
*/
foreach ($ticket_order['tickets'] as $attendee_details) {
/*
* Update ticket's quantity sold
* Create the order
*/
$ticket = Ticket::findOrFail($attendee_details['ticket']['id']);
if (isset($ticket_order['transaction_id'])) {
$order->transaction_id = $ticket_order['transaction_id'][0];
}
if ($ticket_order['order_requires_payment']) {
$order->payment_gateway_id = $ticket_order['payment_gateway']->id;
}
$order->first_name = $request_data['order_first_name'];
$order->last_name = $request_data['order_last_name'];
$order->email = $request_data['order_email'];
$order->order_status_id = config('attendize.order_complete');
$order->amount = $ticket_order['order_total'];
$order->booking_fee = $ticket_order['booking_fee'];
$order->organiser_booking_fee = $ticket_order['organiser_booking_fee'];
$order->discount = 0.00;
$order->account_id = $event->account->id;
$order->event_id = $ticket_order['event_id'];
$order->save();
/*
* Update some ticket info
* Update the event sales volume
*/
$ticket->increment('quantity_sold', $attendee_details['qty']);
$ticket->increment('sales_volume', ($attendee_details['ticket']['price'] * $attendee_details['qty']));
$ticket->increment('organiser_fees_volume', ($attendee_details['ticket']['organiser_booking_fee'] * $attendee_details['qty']));
$event->increment('sales_volume', $order->amount);
$event->increment('organiser_fees_volume', $order->organiser_booking_fee);
/*
* Insert order items (for use in generating invoices)
* Update affiliates stats stats
*/
$orderItem = new OrderItem();
$orderItem->title = $attendee_details['ticket']['title'];
$orderItem->quantity = $attendee_details['qty'];
$orderItem->order_id = $order->id;
$orderItem->unit_price = $attendee_details['ticket']['price'];
$orderItem->unit_booking_fee = $attendee_details['ticket']['booking_fee'] + $attendee_details['ticket']['organiser_booking_fee'];
$orderItem->save();
if ($ticket_order['affiliate_referral']) {
$affiliate = Affiliate::where('name', '=', $ticket_order['affiliate_referral'])
->where('event_id', '=', $event_id)->first();
$affiliate->increment('sales_volume', $order->amount + $order->organiser_booking_fee);
$affiliate->increment('tickets_sold', $ticket_order['total_ticket_quantity']);
}
/*
* Create the attendees
* Update the event stats
*/
for ($i = 0; $i < $attendee_details['qty']; $i++) {
$attendee = new Attendee();
$attendee->first_name = $event->ask_for_all_attendees_info ? ($mirror_buyer_info ? $order->first_name : $request_data["ticket_holder_first_name.$i.{$attendee_details['ticket']['id']}"]) : $order->first_name;
$attendee->last_name = $event->ask_for_all_attendees_info ? ($mirror_buyer_info ? $order->last_name : $request_data["ticket_holder_last_name.$i.{$attendee_details['ticket']['id']}"]) : $order->last_name;
$attendee->email = $event->ask_for_all_attendees_info ? ($mirror_buyer_info ? $order->email : $request_data["ticket_holder_email.$i.{$attendee_details['ticket']['id']}"]) : $order->email;
$attendee->event_id = $event_id;
$attendee->order_id = $order->id;
$attendee->ticket_id = $attendee_details['ticket']['id'];
$attendee->account_id = $event->account->id;
$attendee->reference = $order->order_reference.'-'.($attendee_increment);
$attendee->save();
$event_stats = EventStats::firstOrNew([
'event_id' => $event_id,
'date' => DB::raw('CURRENT_DATE'),
]);
$event_stats->increment('tickets_sold', $ticket_order['total_ticket_quantity']);
if ($ticket_order['order_requires_payment']) {
$event_stats->increment('sales_volume', $order->amount);
$event_stats->increment('organiser_fees_volume', $order->organiser_booking_fee);
}
/*
* Add the attendees
*/
foreach ($ticket_order['tickets'] as $attendee_details) {
/*
* Queue an email to send to each attendee
* Update ticket's quantity sold
*/
$ticket = Ticket::findOrFail($attendee_details['ticket']['id']);
/* Keep track of total number of attendees */
$attendee_increment++;
/*
* Update some ticket info
*/
$ticket->increment('quantity_sold', $attendee_details['qty']);
$ticket->increment('sales_volume', ($attendee_details['ticket']['price'] * $attendee_details['qty']));
$ticket->increment('organiser_fees_volume',
($attendee_details['ticket']['organiser_booking_fee'] * $attendee_details['qty']));
/*
* Insert order items (for use in generating invoices)
*/
$orderItem = new OrderItem();
$orderItem->title = $attendee_details['ticket']['title'];
$orderItem->quantity = $attendee_details['qty'];
$orderItem->order_id = $order->id;
$orderItem->unit_price = $attendee_details['ticket']['price'];
$orderItem->unit_booking_fee = $attendee_details['ticket']['booking_fee'] + $attendee_details['ticket']['organiser_booking_fee'];
$orderItem->save();
/*
* Create the attendees
*/
for ($i = 0; $i < $attendee_details['qty']; $i++) {
$attendee = new Attendee();
$attendee->first_name = $request_data["ticket_holder_first_name"][$i][$attendee_details['ticket']['id']];
$attendee->last_name = $request_data["ticket_holder_last_name"][$i][$attendee_details['ticket']['id']];
$attendee->email = $request_data["ticket_holder_email"][$i][$attendee_details['ticket']['id']];
$attendee->event_id = $event_id;
$attendee->order_id = $order->id;
$attendee->ticket_id = $attendee_details['ticket']['id'];
$attendee->account_id = $event->account->id;
$attendee->reference_index = $attendee_increment;
$attendee->save();
/*
* Save the attendee's questions
*/
foreach ($attendee_details['ticket']->questions as $question) {
$ticket_answer = isset($ticket_questions[$attendee_details['ticket']->id][$i][$question->id]) ? $ticket_questions[$attendee_details['ticket']->id][$i][$question->id] : null;
if (is_null($ticket_answer)) {
continue;
}
/*
* If there are multiple answers to a question then join them with a comma
* and treat them as a single answer.
*/
$ticket_answer = is_array($ticket_answer) ? implode(', ', $ticket_answer) : $ticket_answer;
if (!empty($ticket_answer)) {
QuestionAnswer::create([
'answer_text' => $ticket_answer,
'attendee_id' => $attendee->id,
'event_id' => $event->id,
'account_id' => $event->account->id,
'question_id' => $question->id
]);
}
}
/* Keep track of total number of attendees */
$attendee_increment++;
}
}
/*
* Kill the session
*/
session()->forget('ticket_order_' . $event->id);
/*
* Queue up some tasks - Emails to be sent, PDFs etc.
*/
$this->dispatch(new GenerateTicket($order->order_reference));
TicketMailer::sendOrderTickets($order);
} catch (Exception $e) {
Log::error($e);
DB::rollBack();
return response()->json([
'status' => 'error',
'message' => 'Whoops! There was a problem processing your order. Please try again.'
]);
}
DB::commit();
/*
* Kill the session
*/
session()->forget('ticket_order_'.$event->id);
/*
* Queue up some tasks - Emails to be sent, PDFs etc.
*/
$this->dispatch(new OrderTicketsCommand($order));
if($return_json) {
if ($return_json) {
return response()->json([
'status' => 'success',
'redirectUrl' => route('showOrderDetails', [
@ -548,13 +635,13 @@ class EventCheckoutController extends Controller
}
return response()->redirectToRoute('showOrderDetails', [
'is_embedded' => $this->is_embedded,
'order_reference' => $order->order_reference,
]);
'is_embedded' => $this->is_embedded,
'order_reference' => $order->order_reference,
]);
}
/**
* Show the order details page
*
@ -604,6 +691,9 @@ class EventCheckoutController extends Controller
'event' => $order->event,
'tickets' => $order->event->tickets,
'attendees' => $order->attendees,
'css' => file_get_contents(public_path('assets/stylesheet/ticket.css')),
'image' => base64_encode(file_get_contents(public_path($order->event->organiser->full_logo_path))),
];
if ($request->get('download') == '1') {

View File

@ -144,7 +144,7 @@ class EventCustomizeController extends MyBaseController
]);
}
$event->barcode_type = $request->get('barcode_type');
//$event->barcode_type = $request->get('barcode_type');
$event->ticket_border_color = $request->get('ticket_border_color');
$event->ticket_bg_color = $request->get('ticket_bg_color');
$event->ticket_text_color = $request->get('ticket_text_color');
@ -224,7 +224,6 @@ class EventCustomizeController extends MyBaseController
$event->pre_order_display_message = trim($request->get('pre_order_display_message'));
$event->post_order_display_message = trim($request->get('post_order_display_message'));
$event->ask_for_all_attendees_info = ($request->get('ask_for_all_attendees_info') == 'on');
$event->save();
return response()->json([

View File

@ -46,6 +46,7 @@ class EventDashboardController extends MyBaseController
* I have no idea what I was doing here, but it seems to work;
*/
$result = [];
$tickets_data = [];
$i = 0;
foreach ($dateItter as $date) {
$views = 0;
@ -74,9 +75,17 @@ class EventDashboardController extends MyBaseController
];
}
foreach($event->tickets as $ticket) {
$tickets_data[] = [
'value' => $ticket->quantity_sold,
'label' => $ticket->title,
];
}
$data = [
'event' => $event,
'chartData' => json_encode($result),
'event' => $event,
'chartData' => json_encode($result),
'ticketData' => json_encode($tickets_data),
];
return view('ManageEvent.Dashboard', $data);

View File

@ -6,6 +6,7 @@ namespace App\Http\Controllers;
use App\Models\Attendee;
use App\Models\Event;
use App\Models\Order;
use Illuminate\Http\Request;
use DB;
use Excel;
use Log;
@ -78,7 +79,6 @@ class EventOrdersController extends MyBaseController
{
$data = [
'order' => Order::scope()->find($order_id),
'modal_id' => $request->get('modal_id'),
];
return view('ManageEvent.Modals.ManageOrder', $data);
@ -283,7 +283,6 @@ class EventOrdersController extends MyBaseController
$data = [
'order' => $order,
'event' => $order->event,
'modal_id' => $request->get('modal_id'),
];
return view('ManageEvent.Modals.MessageOrder', $data);

View File

@ -4,12 +4,16 @@ namespace App\Http\Controllers;
class EventPromoteController extends MyBaseController
{
/**
* @param $event_id
* @return mixed
*/
public function showPromote($event_id)
{
$data = [
'event' => Event::scope()->find($event_id),
];
return View::make('ManageEvent.Promote', $data);
return view('ManageEvent.Promote', $data);
}
}

View File

@ -0,0 +1,117 @@
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use App\Models\Attendee;
use App\Models\Event;
use Carbon\Carbon;
use Illuminate\Http\Request;
use JavaScript;
class EventQrcodeCheckInController extends Controller
{
/**
* Show the check-in page
*
* @param $event_id
* @return \Illuminate\View\View
*/
public function showCheckIn($event_id)
{
$event = Event::scope()->findOrFail($event_id);
JavaScript::put([
'qrcodeCheckInRoute' => route('postQRCodeCheckInAttendee', ['event_id' => $event->id])
]);
return view('ManageEvent.QrcodeCheckIn', compact('event'));
}
/**
* Check in an attendee
*
* @param $event_id
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function postCheckInAttendee($event_id, Request $request)
{
$event = Event::scope()->findOrFail($event_id);
$qrcodeToken = $request->get('qrcode_token');
$attendee = Attendee::scope()->withoutCancelled()
->join('tickets', 'tickets.id', '=', 'attendees.ticket_id')
->where(function ($query) use ($event, $qrcodeToken) {
$query->where('attendees.event_id', $event->id)
->where('attendees.private_reference_number', $qrcodeToken);
})->select([
'attendees.id',
'attendees.order_id',
'attendees.first_name',
'attendees.last_name',
'attendees.email',
'attendees.reference',
'attendees.arrival_time',
'attendees.has_arrived',
'tickets.title as ticket',
])->first();
if(is_null($attendee)){
return response()->json(['status' => 'error', 'message' => "Invalid Ticket! Please try again."]);
}
$relatedAttendesCount = Attendee::where('id', '!=', $attendee->id)
->where([
'order_id' => $attendee->order_id,
'has_arrived' => false
])->count();
if($relatedAttendesCount >= 1){
$confirmOrderTicketsRoute = route('confirmCheckInOrderTickets', [$event->id, $attendee->order_id]);
$appendedText = '<br><br><form class="ajax" action="'. $confirmOrderTicketsRoute .'" method="POST">'. csrf_field() .'<button class="btn btn-primary btn-sm" type="submit"><i class="ico-ticket"></i> Check in all tickets associated to this order</button></form>';
} else {
$appendedText = '';
}
if ($attendee->has_arrived) {
return response()->json([
'status' => 'error',
'message' => 'Warning: This attendee has already been checked in at '. $attendee->arrival_time->format('H:i A, F j'). '.' . $appendedText
]);
}
Attendee::find($attendee->id)->update(['has_arrived' => true, 'arrival_time' => Carbon::now()]);
return response()->json([
'status' => 'success',
'message' => 'Success !<br>Name: ' . $attendee->first_name . ' ' . $attendee->last_name . '<br>Reference: '. $attendee->reference . '<br>Ticket: '. $attendee->ticket . '.' . $appendedText
]);
}
/**
* Confirm tickets of same order.
*
* @param $event_id
* @param $order_id
* @return \Illuminate\Http\Response
*/
public function confirmOrderTickets($event_id, $order_id)
{
$updateRowsCount = Attendee::scope()->where([
'event_id' => $event_id,
'order_id' => $order_id,
'has_arrived' => false,
'arrival_time' => Carbon::now(),
])
->update(['has_arrived' => true, 'arrival_time' => Carbon::now()]);
return response()->json([
'message' => $updateRowsCount . ' Attendee(s) Checked in.'
]);
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace App\Http\Controllers;
/* Depreciated */
class EventQuestionsController extends MyBaseController
{
}

View File

@ -0,0 +1,358 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StoreEventQuestionRequest;
use App\Models\Event;
use App\Models\Attendee;
use App\Models\Question;
use App\Models\QuestionAnswer;
use App\Models\QuestionType;
use JavaScript;
use Illuminate\Http\Request;
use Excel;
/*
Attendize.com - Event Management & Ticketing
*/
class EventSurveyController extends MyBaseController
{
/**
* Show the event survey page
*
* @param Request $request
* @param $event_id
* @return mixed
*/
public function showEventSurveys(Request $request, $event_id)
{
$event = Event::scope()->findOrFail($event_id);
JavaScript::put([
'postUpdateQuestionsOrderRoute' => route('postUpdateQuestionsOrder', ['event_id' => $event_id]),
]);
$data = [
'event' => $event,
'questions' => $event->questions->sortBy('sort_order'),
'sort_order' => 'asc',
'sort_by' => 'title',
'q' => '',
];
return view('ManageEvent.Surveys', $data);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function showCreateEventQuestion(Request $request, $event_id)
{
$event = Event::scope()->findOrFail($event_id);
return view('ManageEvent.Modals.CreateQuestion', [
'event' => $event,
'question_types' => QuestionType::all(),
]);
}
/**
* Store a newly created resource in storage.
*
* @access public
* @param StoreEventQuestionRequest $request
* @return \Illuminate\Http\Response
*/
public function postCreateEventQuestion(StoreEventQuestionRequest $request, $event_id)
{
// Get the event or display a 'not found' warning.
$event = Event::findOrFail($event_id);
// Create question.
$question = Question::createNew(false, false, true);
$question->title = $request->get('title');
$question->is_required = ($request->get('is_required') == 'yes');
$question->question_type_id = $request->get('question_type_id');
$question->save();
// Get options.
$options = $request->get('option');
// Add options.
if ($options && is_array($options)) {
foreach ($options as $option_name) {
if (trim($option_name) !== '') {
$question->options()->create([
'name' => $option_name,
]);
}
}
}
// Get tickets.
$ticket_ids = $request->get('tickets');
$question->tickets()->attach($ticket_ids);
$event->questions()->attach($question->id);
session()->flash('message', 'Successfully Created Question');
return response()->json([
'status' => 'success',
'message' => 'Refreshing..',
'redirectUrl' => '',
]);
}
/**
* Show the Edit Question Modal
*
* @param Request $request
* @param $event_id
* @param $question_id
* @return mixed
*/
public function showEditEventQuestion(Request $request, $event_id, $question_id)
{
$question = Question::scope()->findOrFail($question_id);
$event = Event::scope()->findOrFail($event_id);
$data = [
'question' => $question,
'event' => $event,
'question_types' => QuestionType::all(),
];
return view('ManageEvent.Modals.EditQuestion', $data);
}
/**
* Edits a question
*
* @param Request $request
* @param $event_id
* @param $question_id
* @return mixed
*/
public function postEditEventQuestion(Request $request, $event_id, $question_id)
{
// Get the event or display a 'not found' warning.
$event = Event::scope()->findOrFail($event_id);
// Create question.
$question = Question::scope()->findOrFail($question_id);
$question->title = $request->get('title');
$question->is_required = $request->get('is_required');
$question->question_type_id = $request->get('question_type_id');
$question->save();
$question_type = QuestionType::find($question->question_type_id);
if ($question_type->has_options) {
// Get options.
$options = $request->get('option');
$question->options()->delete();
// Add options.
if ($options && is_array($options)) {
foreach ($options as $option_name) {
if (trim($option_name) !== '') {
$question->options()->create([
'name' => $option_name,
]);
}
}
}
}
// Get tickets.
$ticket_ids = (array) $request->get('tickets');
$question->tickets()->sync($ticket_ids);
session()->flash('message', 'Successfully Edited Question');
return response()->json([
'status' => 'success',
'message' => 'Refreshing..',
'redirectUrl' => '',
]);
}
/**
* Delete a question
*
* @param Request $request
* @param $event_id
* @return mixed
*/
public function postDeleteEventQuestion(Request $request, $event_id)
{
$question_id = $request->get('question_id');
$question = Question::scope()->find($question_id);
$question->answers()->delete();
if ($question->delete()) {
session()->flash('message', 'Question Successfully Deleted');
return response()->json([
'status' => 'success',
'message' => 'Refreshing..',
'redirectUrl' => '',
]);
}
return response()->json([
'status' => 'error',
'id' => $question->id,
'message' => 'This question can\'t be deleted.',
]);
}
/**
* Show all attendees answers to questions
*
* @param Request $request
* @param $event_id
* @param $question_id
* @return mixed
*/
public function showEventQuestionAnswers(Request $request, $event_id, $question_id)
{
$answers = QuestionAnswer::scope()->where('question_id', $question_id)->get();
$question = Question::scope()->withTrashed()->find($question_id);
$attendees = Attendee::scope()
->has('answers')
->where('event_id', $event_id)
->get();
$data = [
'answers' => $answers,
'question' => $question,
];
return view('ManageEvent.Modals.ViewAnswers', $data);
}
/**
* Export answers
*
* @todo This doesn't work :-|
* @param Request $request
* @param $event_id
* @param string $export_as
*/
public function showExportAnswers(Request $request, $event_id, $export_as = 'xlsx')
{
Excel::create('answers-as-of-' . date('d-m-Y-g.i.a'), function ($excel) use ($event_id) {
$excel->setTitle('Survey Answers');
// Chain the setters
$excel->setCreator(config('attendize.app_name'))
->setCompany(config('attendize.app_name'));
$excel->sheet('survey_answers_sheet_!', function ($sheet) use ($event_id) {
$event = Event::scope()->findOrFail($event_id);
$rows[] = array_merge([
'Order Ref',
'Attendee Name',
'Attendee Email',
'Attendee Ticket'
], $event->questions->lists('title')->toArray());
$attendees = $event->attendees()->has('answers')->get();
foreach ($attendees as $attendee) {
$rows[] = array_merge([
$attendee->order->order_reference,
$attendee->full_name,
$attendee->email,
$attendee->ticket->title
], $attendee->answers->lists('answer_text')->toArray());
}
$sheet->fromArray($rows);
// Set gray background on first row
$sheet->row(1, function ($row) {
$row->setBackground('#f5f5f5');
});
});
})->export($export_as);
}
public function postEnableQuestion(Request $request, $event_id, $question_id)
{
$question = Question::scope()->find($question_id);
$question->is_enabled = ($question->is_enabled == 1) ? 0 : 1;
if ($question->save()) {
return response()->json([
'status' => 'success',
'message' => 'Question Successfully Updated',
'id' => $question->id,
]);
}
return response()->json([
'status' => 'error',
'id' => $question->id,
'message' => 'Whoops!, looks like something went wrong. Please try again.',
]);
}
/**
* Updates the sort order of event questions
*
* @param Request $request
* @return mixed
*/
public function postUpdateQuestionsOrder(Request $request)
{
$question_ids = $request->get('question_ids');
$sort = 1;
foreach ($question_ids as $question_id) {
$question = Question::scope()->find($question_id);
$question->sort_order = $sort;
$question->save();
$sort++;
}
return response()->json([
'status' => 'success',
'message' => 'Question Order Successfully Updated',
]);
}
}

View File

@ -1,43 +0,0 @@
<?php
namespace App\Http\Controllers;
class EventTicketQuestionsController extends MyBaseController
{
public function showQuestions($event_id)
{
$data = [
'event' => Event::scope()->findOrFail($event_id),
'modal_id' => Input::get('modal_id'),
'question_types' => QuestionType::all(),
];
return View::make('ManageEvent.Modals.ViewQuestions', $data);
}
public function postCreateQuestion($event_id)
{
$event = Event::findOrFail($event_id);
$question = Question::createNew(false, false, true);
$question->title = Input::get('title');
$question->instructions = Input::get('instructions');
$question->options = Input::get('options');
$question->is_required = Input::get('title');
$question->question_type_id = Input::get('question_type_id');
$question->save();
$ticket_ids = Input::get('tickets');
foreach ($ticket_ids as $ticket_id) {
Ticket::scope()->find($ticket_id)->questions()->attach($question->id);
}
$event->questions()->attach($question->id);
return Response::json([
'status' => 'success',
'message' => 'Successfully Created Question',
]);
}
}

View File

@ -6,10 +6,7 @@ use App\Models\Event;
use App\Models\Ticket;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Input;
use Log;
use Response;
use View;
/*
Attendize.com - Event Management & Ticketing
@ -17,6 +14,11 @@ use View;
class EventTicketsController extends MyBaseController
{
/**
* @param Request $request
* @param $event_id
* @return mixed
*/
public function showTickets(Request $request, $event_id)
{
$allowed_sorts = [
@ -46,50 +48,67 @@ class EventTicketsController extends MyBaseController
return view('ManageEvent.Tickets', compact('event', 'tickets', 'sort_by', 'q', 'allowed_sorts'));
}
/**
* Show the edit ticket modal
*
* @param $event_id
* @param $ticket_id
* @return mixed
*/
public function showEditTicket($event_id, $ticket_id)
{
$data = [
'event' => Event::scope()->find($event_id),
'ticket' => Ticket::scope()->find($ticket_id),
'modal_id' => Input::get('modal_id'),
];
return view('ManageEvent.Modals.EditTicket', $data);
}
/**
* Show the create ticket modal
*
* @param $event_id
* @return \Illuminate\Contracts\View\View
*/
public function showCreateTicket($event_id)
{
return View::make('ManageEvent.Modals.CreateTicket', [
'modal_id' => Input::get('modal_id'),
'event' => Event::find($event_id),
return view('ManageEvent.Modals.CreateTicket', [
'event' => Event::scope()->find($event_id),
]);
}
public function postCreateTicket($event_id)
/**
* Creates a ticket
*
* @param $event_id
* @return \Illuminate\Http\JsonResponse
*/
public function postCreateTicket(Request $request, $event_id)
{
$ticket = Ticket::createNew();
if (!$ticket->validate(Input::all())) {
return Response::json([
if (!$ticket->validate($request->all())) {
return response()->json([
'status' => 'error',
'messages' => $ticket->errors(),
]);
}
$ticket->event_id = $event_id;
$ticket->title = Input::get('title');
$ticket->quantity_available = !Input::get('quantity_available') ? null : Input::get('quantity_available');
$ticket->start_sale_date = Input::get('start_sale_date') ? Carbon::createFromFormat('d-m-Y H:i', Input::get('start_sale_date')) : null;
$ticket->end_sale_date = Input::get('end_sale_date') ? Carbon::createFromFormat('d-m-Y H:i', Input::get('end_sale_date')) : null;
$ticket->price = Input::get('price');
$ticket->min_per_person = Input::get('min_per_person');
$ticket->max_per_person = Input::get('max_per_person');
$ticket->description = Input::get('description');
$ticket->title = $request->get('title');
$ticket->quantity_available = !$request->get('quantity_available') ? null : $request->get('quantity_available');
$ticket->start_sale_date = $request->get('start_sale_date') ? Carbon::createFromFormat('d-m-Y H:i', $request->get('start_sale_date')) : null;
$ticket->end_sale_date = $request->get('end_sale_date') ? Carbon::createFromFormat('d-m-Y H:i', $request->get('end_sale_date')) : null;
$ticket->price = $request->get('price');
$ticket->min_per_person = $request->get('min_per_person');
$ticket->max_per_person = $request->get('max_per_person');
$ticket->description = $request->get('description');
$ticket->save();
\Session::flash('message', 'Successfully Created Ticket');
session()->flash('message', 'Successfully Created Ticket');
return Response::json([
return response()->json([
'status' => 'success',
'id' => $ticket->id,
'message' => 'Refreshing...',
@ -99,16 +118,22 @@ class EventTicketsController extends MyBaseController
]);
}
public function postPauseTicket()
/**
* Pause ticket / take it off sale
*
* @param Request $request
* @return mixed
*/
public function postPauseTicket(Request $request)
{
$ticket_id = Input::get('ticket_id');
$ticket_id = $request->get('ticket_id');
$ticket = Ticket::scope()->find($ticket_id);
$ticket->is_paused = ($ticket->is_paused == 1) ? 0 : 1;
if ($ticket->save()) {
return Response::json([
return response()->json([
'status' => 'success',
'message' => 'Ticket Successfully Updated',
'id' => $ticket->id,
@ -119,21 +144,30 @@ class EventTicketsController extends MyBaseController
'ticket' => $ticket,
]);
return Response::json([
return response()->json([
'status' => 'error',
'id' => $ticket->id,
'message' => 'Whoops!, looks like something went wrong. Please try again.',
]);
}
public function postDeleteTicket()
/**
* Deleted a ticket
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function postDeleteTicket(Request $request)
{
$ticket_id = Input::get('ticket_id');
$ticket_id = $request->get('ticket_id');
$ticket = Ticket::scope()->find($ticket_id);
/*
* Don't allow deletion of tickets which have been sold already.
*/
if ($ticket->quantity_sold > 0) {
return Response::json([
return response()->json([
'status' => 'error',
'message' => 'Sorry, you can\'t delete this ticket as some have already been sold',
'id' => $ticket->id,
@ -141,7 +175,7 @@ class EventTicketsController extends MyBaseController
}
if ($ticket->delete()) {
return Response::json([
return response()->json([
'status' => 'success',
'message' => 'Ticket Successfully Deleted',
'id' => $ticket->id,
@ -152,19 +186,27 @@ class EventTicketsController extends MyBaseController
'ticket' => $ticket,
]);
return Response::json([
return response()->json([
'status' => 'error',
'id' => $ticket->id,
'message' => 'Whoops!, looks like something went wrong. Please try again.',
]);
}
public function postEditTicket($event_id, $ticket_id)
/**
* Edit a ticket
*
* @param Request $request
* @param $event_id
* @param $ticket_id
* @return \Illuminate\Http\JsonResponse
*/
public function postEditTicket(Request $request, $event_id, $ticket_id)
{
$ticket = Ticket::findOrFail($ticket_id);
$ticket = Ticket::scope()->findOrFail($ticket_id);
/*
* Override some vaidation rules
* Override some validation rules
*/
$validation_rules['quantity_available'] = ['integer', 'min:'.($ticket->quantity_sold + $ticket->quantity_reserved)];
$validation_messages['quantity_available.min'] = 'Quantity available can\'t be less the amount sold or reserved.';
@ -172,25 +214,25 @@ class EventTicketsController extends MyBaseController
$ticket->rules = $validation_rules + $ticket->rules;
$ticket->messages = $validation_messages + $ticket->messages;
if (!$ticket->validate(Input::all())) {
return Response::json([
if (!$ticket->validate($request->all())) {
return response()->json([
'status' => 'error',
'messages' => $ticket->errors(),
]);
}
$ticket->title = Input::get('title');
$ticket->quantity_available = !Input::get('quantity_available') ? null : Input::get('quantity_available');
$ticket->price = Input::get('price');
$ticket->start_sale_date = Input::get('start_sale_date') ? Carbon::createFromFormat('d-m-Y H:i', Input::get('start_sale_date')) : null;
$ticket->end_sale_date = Input::get('end_sale_date') ? Carbon::createFromFormat('d-m-Y H:i', Input::get('end_sale_date')) : null;
$ticket->description = Input::get('description');
$ticket->min_per_person = Input::get('min_per_person');
$ticket->max_per_person = Input::get('max_per_person');
$ticket->title = $request->get('title');
$ticket->quantity_available = !$request->get('quantity_available') ? null : $request->get('quantity_available');
$ticket->price = $request->get('price');
$ticket->start_sale_date = $request->get('start_sale_date') ? Carbon::createFromFormat('d-m-Y H:i', $request->get('start_sale_date')) : null;
$ticket->end_sale_date = $request->get('end_sale_date') ? Carbon::createFromFormat('d-m-Y H:i', $request->get('end_sale_date')) : null;
$ticket->description = $request->get('description');
$ticket->min_per_person = $request->get('min_per_person');
$ticket->max_per_person = $request->get('max_per_person');
$ticket->save();
return Response::json([
return response()->json([
'status' => 'success',
'id' => $ticket->id,
'message' => 'Refreshing...',

View File

@ -7,20 +7,28 @@ use App\Models\Event;
use App\Models\EventStats;
use Auth;
use Cookie;
use Input;
use Illuminate\Http\Request;
use Mail;
use Response;
use Validator;
use View;
class EventViewController extends Controller
{
public function showEventHome($event_id, $slug = '', $preview = false)
/**
* Show the homepage for an event
*
* @param Request $request
* @param $event_id
* @param string $slug
* @param bool $preview
* @return mixed
*/
public function showEventHome(Request $request, $event_id, $slug = '', $preview = false)
{
$event = Event::findOrFail($event_id);
if (!Auth::check() && !$event->is_live) {
return View::make('Public.ViewEvent.EventNotLivePage');
return view('Public.ViewEvent.EventNotLivePage');
}
$data = [
@ -31,7 +39,7 @@ class EventViewController extends Controller
/*
* Don't record stats if we're previewing the event page from the backend or if we own the event.
*/
if (!$preview || !Auth::check()) {
if (!$preview && !Auth::check()) {
$event_stats = new EventStats();
$event_stats->updateViewCount($event_id);
}
@ -39,12 +47,12 @@ class EventViewController extends Controller
/*
* See if there is an affiliate referral in the URL
*/
if ($affiliate_ref = \Input::get('ref')) {
if ($affiliate_ref = $request->get('ref')) {
$affiliate_ref = preg_replace("/\W|_/", '', $affiliate_ref);
if ($affiliate_ref) {
$affiliate = Affiliate::firstOrNew([
'name' => Input::get('ref'),
'name' => $request->get('ref'),
'event_id' => $event_id,
'account_id' => $event->account_id,
]);
@ -57,15 +65,28 @@ class EventViewController extends Controller
}
}
return View::make('Public.ViewEvent.EventPage', $data);
return view('Public.ViewEvent.EventPage', $data);
}
/**
* Show preview of event homepage / used for backend previewing
*
* @param $event_id
* @return mixed
*/
public function showEventHomePreview($event_id)
{
return showEventHome($event_id, true);
}
public function postContactOrganiser($event_id)
/**
* Sends a message to the organiser
*
* @param Request $request
* @param $event_id
* @return mixed
*/
public function postContactOrganiser(Request $request, $event_id)
{
$rules = [
'name' => 'required',
@ -73,10 +94,10 @@ class EventViewController extends Controller
'message' => ['required'],
];
$validator = Validator::make(Input::all(), $rules);
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return Response::json([
return response()->json([
'status' => 'error',
'messages' => $validator->messages()->toArray(),
]);
@ -85,9 +106,9 @@ class EventViewController extends Controller
$event = Event::findOrFail($event_id);
$data = [
'sender_name' => Input::get('name'),
'sender_email' => Input::get('email'),
'message_content' => strip_tags(Input::get('message')),
'sender_name' => $request->get('name'),
'sender_email' => $request->get('email'),
'message_content' => strip_tags($request->get('message')),
'event' => $event,
];
@ -98,7 +119,7 @@ class EventViewController extends Controller
->subject('Message Regarding: '.$event->title);
});
return Response::json([
return response()->json([
'status' => 'success',
'message' => 'Message Successfully Sent',
]);

View File

@ -3,10 +3,16 @@
namespace App\Http\Controllers;
use App\Models\Event;
use View;
class EventViewEmbeddedController extends Controller
{
/**
* Show an embedded version of the event page
*
* @param $event_id
* @return mixed
*/
public function showEmbeddedEvent($event_id)
{
$event = Event::findOrFail($event_id);
@ -17,6 +23,6 @@ class EventViewEmbeddedController extends Controller
'is_embedded' => '1',
];
return View::make('Public.ViewEvent.Embedded.EventPage', $data);
return view('Public.ViewEvent.Embedded.EventPage', $data);
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StoreEventQuestionRequest;
use App\Models\Event;
use App\Models\Question;
use App\Models\QuestionType;
use Illuminate\Http\Request;
/*
Attendize.com - Event Management & Ticketing
*/
class EventWidgetsController extends MyBaseController
{
/**
* Show the event widgets page
*
* @param Request $request
* @param $event_id
* @return mixed
*/
public function showEventWidgets(Request $request, $event_id)
{
$event = Event::scope()->findOrFail($event_id);
$data = [
'event' => $event,
];
return view('ManageEvent.Widgets', $data);
}
}

View File

@ -4,6 +4,15 @@ namespace App\Http\Controllers;
class ImageController extends Controller
{
/**
* Generate a thumbnail for a given image
*
* @param $image_src
* @param bool $width
* @param bool $height
* @param int $quality
*/
public function generateThumbnail($image_src, $width = false, $height = false, $quality = 90)
{
$img = Image::make('public/foo.jpg');

View File

@ -6,6 +6,7 @@ use App\Models\Timezone;
use Artisan;
use Config;
use DB;
use Illuminate\Http\Request;
use Input;
use Redirect;
use Response;
@ -13,15 +14,31 @@ use View;
class InstallerController extends Controller
{
/**
* InstallerController constructor.
*/
public function __construct()
{
/**
* If we're already installed kill the request
* @todo Check if DB is installed etc.
*/
if (file_exists(base_path('installed'))) {
abort(403, 'Unauthorized action.');
}
}
/**
* Show the application installer
*
* @return mixed
*/
public function showInstaller()
{
/*
* Path we need to make sure are writable
*/
$data['paths'] = [
storage_path('app'),
storage_path('framework'),
@ -29,8 +46,14 @@ class InstallerController extends Controller
public_path(config('attendize.event_images_path')),
public_path(config('attendize.organiser_images_path')),
public_path(config('attendize.event_pdf_tickets_path')),
base_path('bootstrap/cache'),
base_path('.env'),
base_path(),
];
/*
* Required PHP extensions
*/
$data['requirements'] = [
'openssl',
'pdo',
@ -38,57 +61,72 @@ class InstallerController extends Controller
'fileinfo',
'tokenizer',
'gd',
'zip',
];
return View::make('Installer.Installer', $data);
/*
* Optional PHP extensions
*/
$data['optional_requirements'] = [
'pdo_pgsql',
'pdo_mysql',
];
return view('Installer.Installer', $data);
}
public function postInstaller()
/**
* Attempts to install the system
*
* @param Request $request
* @return \Illuminate\Http\RedirectResponse
*/
public function postInstaller(Request $request)
{
set_time_limit(300);
$database['type'] = 'mysql';
$database['host'] = Input::get('database_host');
$database['name'] = Input::get('database_name');
$database['username'] = Input::get('database_username');
$database['password'] = Input::get('database_password');
$database['type'] = $request->get('database_type');
$database['host'] = $request->get('database_host');
$database['name'] = $request->get('database_name');
$database['username'] = $request->get('database_username');
$database['password'] = $request->get('database_password');
$mail['driver'] = Input::get('mail_driver');
$mail['port'] = Input::get('mail_port');
$mail['username'] = Input::get('mail_username');
$mail['password'] = Input::get('mail_password');
$mail['encryption'] = Input::get('mail_encryption');
$mail['from_address'] = Input::get('mail_from_address');
$mail['from_name'] = Input::get('mail_from_name');
$mail['host'] = Input::get('mail_host');
$mail['driver'] = $request->get('mail_driver');
$mail['port'] = $request->get('mail_port');
$mail['username'] = $request->get('mail_username');
$mail['password'] = $request->get('mail_password');
$mail['encryption'] = $request->get('mail_encryption');
$mail['from_address'] = $request->get('mail_from_address');
$mail['from_name'] = $request->get('mail_from_name');
$mail['host'] = $request->get('mail_host');
$app_url = Input::get('app_url');
$app_url = $request->get('app_url');
$app_key = str_random(16);
$version = file_get_contents(base_path('VERSION'));
if (Input::get('test') === 'db') {
if ($request->get('test') === 'db') {
$is_db_valid = self::testDatabase($database);
if ($is_db_valid === 'yes') {
return Response::json([
return [
'status' => 'success',
'message' => 'Success, Your connection works!',
'test' => 1,
]);
];
}
return Response::json([
return [
'status' => 'error',
'message' => 'Unable to connect! Please check your settings',
'test' => 1,
]);
];
}
$config = "APP_ENV=production\n".
"APP_DEBUG=false\n".
"APP_URL={$app_url}\n".
"APP_KEY={$app_key}\n\n".
"DB_TYPE=mysql\n".
"APP_KEY={$app_key}\n".
"DB_TYPE={$database['type']}\n".
"DB_HOST={$database['host']}\n".
"DB_DATABASE={$database['name']}\n".
"DB_USERNAME={$database['username']}\n".
@ -98,7 +136,7 @@ class InstallerController extends Controller
"MAIL_ENCRYPTION={$mail['encryption']}\n".
"MAIL_HOST={$mail['host']}\n".
"MAIL_USERNAME={$mail['username']}\n".
"MAIL_FROM_NAME={$mail['from_name']}\n".
"MAIL_FROM_NAME=\"{$mail['from_name']}\"\n".
"MAIL_FROM_ADDRESS={$mail['from_address']}\n".
"MAIL_PASSWORD={$mail['password']}\n\n";
@ -107,13 +145,16 @@ class InstallerController extends Controller
fclose($fp);
Config::set('database.default', $database['type']);
Config::set('database.connections.mysql.host', $database['host']);
Config::set('database.connections.mysql.database', $database['name']);
Config::set('database.connections.mysql.username', $database['username']);
Config::set('database.connections.mysql.password', $database['password']);
Config::set("database.connections.{$database['type']}.host", $database['host']);
Config::set("database.connections.{$database['type']}.database", $database['name']);
Config::set("database.connections.{$database['type']}.username", $database['username']);
Config::set("database.connections.{$database['type']}.password", $database['password']);
DB::reconnect();
//force laravel to regenerate a new key (see key:generate sources)
Config::set('app.key', $app_key);
Artisan::call('key:generate');
Artisan::call('migrate', ['--force' => true]);
if (Timezone::count() == 0) {
Artisan::call('db:seed', ['--force' => true]);
@ -124,16 +165,16 @@ class InstallerController extends Controller
fwrite($fp, $version);
fclose($fp);
return Redirect::route('showSignup', ['first_run' => 'yup']);
return redirect()->route('showSignup', ['first_run' => 'yup']);
}
private function testDatabase($database)
{
Config::set('database.default', $database['type']);
Config::set('database.connections.mysql.host', $database['host']);
Config::set('database.connections.mysql.database', $database['name']);
Config::set('database.connections.mysql.username', $database['username']);
Config::set('database.connections.mysql.password', $database['password']);
Config::set("database.connections.{$database['type']}.host", $database['host']);
Config::set("database.connections.{$database['type']}.database", $database['name']);
Config::set("database.connections.{$database['type']}.username", $database['username']);
Config::set("database.connections.{$database['type']}.password", $database['password']);
try {
DB::reconnect();

View File

@ -13,14 +13,21 @@ use HttpClient;
use Illuminate\Http\Request;
use Input;
use Response;
use View;
use Validator;
use Hash;
use Mail;
class ManageAccountController extends MyBaseController
{
/**
* Show the account modal
*
* @param Request $request
* @return mixed
*/
public function showEditAccount(Request $request)
{
$data = [
'modal_id' => $request->get('modal_id'),
'account' => Account::find(Auth::user()->account_id),
'timezones' => Timezone::lists('location', 'id'),
'currencies' => Currency::lists('title', 'id'),
@ -31,6 +38,7 @@ class ManageAccountController extends MyBaseController
return view('ManageAccount.Modals.EditAccount', $data);
}
public function showStripeReturn()
{
$error_message = 'There was an error connecting your Stripe account. Please try again.';
@ -45,7 +53,7 @@ class ManageAccountController extends MyBaseController
'url' => 'https://connect.stripe.com/oauth/token',
'params' => [
'client_secret' => STRIPE_SECRET_KEY, //sk_test_iXk2Ky0DlhIcTcKMvsDa8iKI',
'client_secret' => STRIPE_SECRET_KEY,
'code' => Input::get('code'),
'grant_type' => 'authorization_code',
],
@ -73,6 +81,12 @@ class ManageAccountController extends MyBaseController
return redirect()->route('showEventsDashboard');
}
/**
* Edit an account
*
* @return \Illuminate\Http\JsonResponse
*/
public function postEditAccount()
{
$account = Account::find(Auth::user()->account_id);
@ -141,6 +155,11 @@ class ManageAccountController extends MyBaseController
]);
}
/**
* Invite a user to the application
*
* @return \Illuminate\Http\JsonResponse
*/
public function postInviteUser()
{
$rules = [
@ -153,10 +172,10 @@ class ManageAccountController extends MyBaseController
'email.unique' => 'E-mail already in use for this account.',
];
$validation = \Validator::make(Input::all(), $rules, $messages);
$validation = Validator::make(Input::all(), $rules, $messages);
if ($validation->fails()) {
return \Response::json([
return Response::json([
'status' => 'error',
'messages' => $validation->messages()->toArray(),
]);
@ -166,7 +185,7 @@ class ManageAccountController extends MyBaseController
$user = new User();
$user->email = Input::get('email');
$user->password = \Hash::make($temp_password);
$user->password = Hash::make($temp_password);
$user->account_id = Auth::user()->account_id;
$user->save();
@ -176,9 +195,9 @@ class ManageAccountController extends MyBaseController
'inviter' => Auth::user(),
];
\Mail::send('Emails.inviteUser', $data, function ($message) use ($data) {
Mail::send('Emails.inviteUser', $data, function ($message) use ($data) {
$message->to($data['user']->email)
->subject($data['inviter']->first_name . ' ' . $data['inviter']->last_name . ' added you to an Attendize Ticketing account.');
->subject($data['inviter']->first_name . ' ' . $data['inviter']->last_name . ' added you to an '. config('attendize.app_name') .' account.');
});
return Response::json([

View File

@ -5,15 +5,57 @@ namespace App\Http\Controllers;
use App\Models\Event;
use App\Models\Organiser;
use Auth;
use JavaScript;
use View;
class MyBaseController extends Controller
{
public function __construct()
{
/*
* Set up JS across all views
*/
JavaScript::put([
'User' => [
'full_name' => Auth::user()->full_name,
'email' => Auth::user()->email,
'is_confirmed' => Auth::user()->is_confirmed,
],
/*
* @todo These should be user selectable
*/
'DateFormat' =>'dd-MM-yyyy',
'DateTimeFormat' => 'dd-MM-yyyy hh:mm',
'GenericErrorMessage' => 'Whoops!, An unknown error has occurred. Please try again or contact support if the problem persists.'
]);
/*
* Share the organizers across all views
*/
View::share('organisers', Organiser::scope()->get());
}
/**
* Returns data which is required in each view, optionally combined with additional data.
*
* @param int $event_id
* @param array $additional_data
*
* @return arrau
*/
public function getEventViewData($event_id, $additional_data = [])
{
$event = Event::scope()->findOrFail($event_id);
return array_merge([
'event' => $event,
'questions' => $event->questions()->get(),
], $additional_data);
}
/**
* Setup the layout used by the controller.
*
@ -25,19 +67,4 @@ class MyBaseController extends Controller
$this->layout = View::make($this->layout);
}
}
/**
* Returns data which is required in each view, optionally combined with additional data.
*
* @param int $event_id
* @param array $additional_data
*
* @return arrau
*/
public function getEventViewData($event_id, $additional_data = [])
{
return array_merge([
'event' => Event::scope()->findOrFail($event_id),
], $additional_data);
}
}

View File

@ -2,98 +2,68 @@
namespace App\Http\Controllers;
use App\Models\Event;
use App\Models\Organiser;
use Illuminate\Http\Request;
use Image;
use Input;
use Response;
use View;
class OrganiserController extends MyBaseController
{
/**
* Show the select organiser page
*
* @return \Illuminate\Contracts\View\View
*/
public function showSelectOragniser()
{
return View::make('ManageOrganiser.SelectOrganiser');
return view('ManageOrganiser.SelectOrganiser');
}
public function showOrganiserDashboard($organiser_id = false)
{
$allowed_sorts = ['created_at', 'start_date', 'end_date', 'title'];
$searchQuery = Input::get('q');
//$sort_order = Input::get('sort_order') == 'asc' ? 'asc' : 'desc';
$sort_by = (in_array(Input::get('sort_by'), $allowed_sorts) ? Input::get('sort_by') : 'start_date');
$events = $searchQuery
? Event::scope()->where('title', 'like', '%'.$searchQuery.'%')->orderBy($sort_by, 'desc')->where('organiser_id', '=', $organiser_id)->paginate(12)
: Event::scope()->where('organiser_id', '=', $organiser_id)->orderBy($sort_by, 'desc')->paginate(12);
$data = [
'events' => $events,
'organisers' => Organiser::scope()->orderBy('name')->get(),
'current_organiser' => Organiser::scope()->find($organiser_id),
'q' => $searchQuery ? $searchQuery : '', //Redundant
'search' => [
'q' => $searchQuery ? $searchQuery : '',
'sort_by' => $sort_by,
'showPast' => Input::get('past'),
],
];
return View::make('ManageEvents.OrganiserDashboard', $data);
}
public function showEditOrganiser($organiser_id)
{
$organiser = Organiser::scope()->findOrfail($organiser_id);
return View::make('ManageEvents.Modals.EditOrganiser', [
'modal_id' => Input::get('modal_id'),
'organiser' => $organiser,
]);
}
/**
* Show the create organiser page
*
* @return \Illuminate\Contracts\View\View
*/
public function showCreateOrganiser()
{
return View::make('ManageOrganiser.CreateOrganiser', [
'modal_id' => 'createOrganiser',
]);
return View::make('ManageEvents.Modals.CreateOrganiser', [
'modal_id' => Input::get('modal_id'),
]);
return view('ManageOrganiser.CreateOrganiser');
}
public function postCreateOrganiser()
/**
* Create the organiser
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function postCreateOrganiser(Request $request)
{
$organiser = Organiser::createNew(false, false, true);
if (!$organiser->validate(Input::all())) {
return Response::json([
if (!$organiser->validate($request->all())) {
return response()->json([
'status' => 'error',
'messages' => $organiser->errors(),
]);
}
$organiser->name = Input::get('name');
$organiser->about = Input::get('about');
$organiser->email = Input::get('email');
$organiser->facebook = Input::get('facebook');
$organiser->twitter = Input::get('twitter');
$organiser->confirmation_key = md5(time().rand(0, 999999));
$organiser->name = $request->get('name');
$organiser->about = $request->get('about');
$organiser->email = $request->get('email');
$organiser->facebook = $request->get('facebook');
$organiser->twitter = $request->get('twitter');
$organiser->confirmation_key = str_random(15);
if (Input::hasFile('organiser_logo')) {
if ($request->hasFile('organiser_logo')) {
$path = public_path().'/'.config('attendize.organiser_images_path');
$filename = 'organiser_logo-'.$organiser->id.'.'.strtolower(Input::file('organiser_logo')->getClientOriginalExtension());
$filename = 'organiser_logo-'.$organiser->id.'.'.strtolower($request->file('organiser_logo')->getClientOriginalExtension());
$file_full_path = $path.'/'.$filename;
Input::file('organiser_logo')->move($path, $filename);
$request->file('organiser_logo')->move($path, $filename);
$img = Image::make($file_full_path);
$img->resize(250, 250, function ($constraint) {
//$constraint->aspectRatio();
$constraint->upsize();
});
@ -105,9 +75,9 @@ class OrganiserController extends MyBaseController
}
$organiser->save();
\Session::flash('message', 'Successfully Created Organiser');
session()->flash('message', 'Successfully Created Organiser');
return Response::json([
return response()->json([
'status' => 'success',
'message' => 'Refreshing..',
'redirectUrl' => route('showOrganiserDashboard', [

View File

@ -5,53 +5,58 @@ namespace App\Http\Controllers;
use App\Models\Organiser;
use File;
use Image;
use Input;
use Response;
use Session;
use View;
use Illuminate\Http\Request;
use Validator;
class OrganiserCustomizeController extends MyBaseController
{
/**
* Show organiser setting page
*
* @param $organiser_id
* @return mixed
*/
public function showCustomize($organiser_id)
{
$data = [
'organiser' => Organiser::scope()->findOrFail($organiser_id),
];
return View::make('ManageOrganiser.Customize', $data);
return view('ManageOrganiser.Customize', $data);
}
public function postEditOrganiser($organiser_id)
/**
* Edits organiser settings / design etc.
*
* @param Request $request
* @param $organiser_id
* @return mixed
*/
public function postEditOrganiser(Request $request, $organiser_id)
{
$organiser = Organiser::scope()->find($organiser_id);
if (!$organiser->validate(Input::all())) {
return Response::json([
if (!$organiser->validate($request->all())) {
return response()->json([
'status' => 'error',
'messages' => $organiser->errors(),
]);
}
$organiser->name = Input::get('name');
$organiser->about = Input::get('about');
$organiser->email = Input::get('email');
$organiser->facebook = Input::get('facebook');
$organiser->twitter = Input::get('twitter');
$organiser->name = $request->get('name');
$organiser->about = $request->get('about');
$organiser->email = $request->get('email');
$organiser->enable_organiser_page = $request->get('enable_organiser_page');
$organiser->facebook = $request->get('facebook');
$organiser->twitter = $request->get('twitter');
/*
* If the email has been changed the user must confirm the email.
*/
if ($organiser->email !== Input::get('email')) {
$organiser->is_email_confirmed = 0;
}
if (Input::get('remove_current_image') == '1') {
if ($request->get('remove_current_image') == '1') {
$organiser->logo_path = '';
}
if (Input::hasFile('organiser_logo')) {
$the_file = \File::get(Input::file('organiser_logo')->getRealPath());
$file_name = str_slug($organiser->name).'-logo-'.$organiser->id.'.'.strtolower(Input::file('organiser_logo')->getClientOriginalExtension());
if ($request->hasFile('organiser_logo')) {
$the_file = \File::get($request->file('organiser_logo')->getRealPath());
$file_name = str_slug($organiser->name).'-logo-'.$organiser->id.'.'.strtolower($request->file('organiser_logo')->getClientOriginalExtension());
$relative_path_to_file = config('attendize.organiser_images_path').'/'.$file_name;
$full_path_to_file = public_path($relative_path_to_file);
@ -72,13 +77,53 @@ class OrganiserCustomizeController extends MyBaseController
$organiser->save();
Session::flash('message', 'Successfully Updated Organiser');
session()->flash('message', 'Successfully Updated Organiser');
return Response::json([
return response()->json([
'status' => 'success',
'redirectUrl' => route('showOrganiserCustomize', [
'organiser_id' => $organiser->id,
]),
'redirectUrl' => '',
]);
}
/**
* Edits organiser profile page colors / design
*
* @param Request $request
* @param $organiser_id
* @return mixed
*/
public function postEditOrganiserPageDesign(Request $request, $organiser_id)
{
$event = Organiser::scope()->findOrFail($organiser_id);
$rules = [
'page_bg_color' => ['required'],
'page_header_bg_color' => ['required'],
'page_text_color' => ['required'],
];
$messages = [
'page_header_bg_color.required' => 'Please enter a header background color.',
'page_bg_color.required' => 'Please enter a background color.',
];
$validator = Validator::make($request->all(), $rules, $messages);
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'messages' => $validator->messages()->toArray(),
]);
}
$event->page_bg_color = $request->get('page_bg_color');
$event->page_header_bg_color = $request->get('page_header_bg_color');
$event->page_text_color = $request->get('page_text_color');
$event->save();
return response()->json([
'status' => 'success',
'message' => 'Organiser Design Successfully Updated',
]);
}
}

View File

@ -4,25 +4,41 @@ namespace App\Http\Controllers;
use App\Models\Organiser;
use Carbon\Carbon;
use View;
use DB;
class OrganiserDashboardController extends MyBaseController
{
/**
* Show the organiser dashboard
*
* @param $organiser_id
* @return mixed
*/
public function showDashboard($organiser_id)
{
$organiser = Organiser::scope()->findOrFail($organiser_id);
$upcoming_events = $organiser->events()->where('end_date', '>=', Carbon::now())->get();
$calendar_events = [];
/* Prepare JSON array for events for use in the dashboard calendar */
foreach($organiser->events as $event) {
$calendar_events[] =[
'title' => $event->title,
'start' => $event->start_date->toIso8601String(),
'end' => $event->end_date->toIso8601String(),
'url' => route('showEventDashboard', [
'event_id' => $event->id
]),
'color' => '#4E558F'
];
}
$data = [
'organiser' => $organiser,
'upcoming_events' => $upcoming_events,
'search' => [
'sort_by' => 's',
'q' => '',
],
'q' => 'dd',
'calendar_events' => json_encode($calendar_events),
];
return View::make('ManageOrganiser.Dashboard', $data);
return view('ManageOrganiser.Dashboard', $data);
}
}

View File

@ -4,19 +4,26 @@ namespace App\Http\Controllers;
use App\Models\Event;
use App\Models\Organiser;
use Input;
use View;
use Illuminate\Http\Request;
class OrganiserEventsController extends MyBaseController
{
public function showEvents($organiser_id)
/**
* Show the organiser events page
*
* @param Request $request
* @param $organiser_id
* @return mixed
*/
public function showEvents(Request $request, $organiser_id)
{
$organiser = Organiser::scope()->findOrfail($organiser_id);
$allowed_sorts = ['created_at', 'start_date', 'end_date', 'title'];
$searchQuery = Input::get('q');
$sort_by = (in_array(Input::get('sort_by'), $allowed_sorts) ? Input::get('sort_by') : 'start_date');
$searchQuery = $request->get('q');
$sort_by = (in_array($request->get('sort_by'), $allowed_sorts) ? $request->get('sort_by') : 'start_date');
$events = $searchQuery
? Event::scope()->where('title', 'like', '%'.$searchQuery.'%')->orderBy($sort_by, 'desc')->where('organiser_id', '=', $organiser_id)->paginate(12)
@ -27,11 +34,13 @@ class OrganiserEventsController extends MyBaseController
'organiser' => $organiser,
'search' => [
'q' => $searchQuery ? $searchQuery : '',
'sort_by' => Input::get('sort_by') ? Input::get('sort_by') : '',
'showPast' => Input::get('past'),
'sort_by' => $request->get('sort_by') ? $request->get('sort_by') : '',
'showPast' => $request->get('past'),
],
];
return View::make('ManageOrganiser.Events', $data);
return view('ManageOrganiser.Events', $data);
}
}

View File

@ -3,15 +3,41 @@
namespace App\Http\Controllers;
use App\Models\Organiser;
use View;
use Carbon\Carbon;
use Auth;
use Illuminate\Http\Request;
class OrganiserViewController extends Controller
{
public function showOrganiserHome($organiser_id, $slug = '', $preview = false)
/**
* Show the public organiser page
*
* @param $organiser_id
* @param string $slug
* @param bool $preview
* @return \Illuminate\Contracts\View\View
*/
public function showOrganiserHome(Request $request, $organiser_id, $slug = '', $preview = false)
{
$organiser = Organiser::findOrFail($organiser_id);
if(!$organiser->enable_organiser_page && !Auth::check()) {
abort(404);
}
/*
* If we are previewing styles from the backend we set them here.
*/
if($request->get('preview_styles') && Auth::check()) {
$query_string = rawurldecode($request->get('preview_styles'));
parse_str($query_string, $preview_styles);
$organiser->page_bg_color = $preview_styles['page_bg_color'];
$organiser->page_header_bg_color = $preview_styles['page_header_bg_color'];
$organiser->page_text_color = $preview_styles['page_text_color'];
}
$upcoming_events = $organiser->events()->where('end_date', '>=', Carbon::now())->get();
$past_events = $organiser->events()->where('end_date', '<', Carbon::now())->get();
@ -20,12 +46,18 @@ class OrganiserViewController extends Controller
'tickets' => $organiser->events()->orderBy('created_at', 'desc')->get(),
'is_embedded' => 0,
'upcoming_events' => $upcoming_events,
'past_events' => $past_events
'past_events' => $past_events,
];
return View::make('Public.ViewOrganiser.OrganiserPage', $data);
return view('Public.ViewOrganiser.OrganiserPage', $data);
}
/**
* Show the backend preview of the organiser page
*
* @param $event_id
* @return mixed
*/
public function showEventHomePreview($event_id)
{
return showEventHome($event_id, true);

View File

@ -2,24 +2,35 @@
namespace App\Http\Controllers;
use App\Models\User;
use Auth;
use Illuminate\Http\Request;
use Input;
use Response;
use Hash;
use Validator;
class UserController extends Controller
{
/**
* Show the edit user modal
*
* @return \Illuminate\Contracts\View\View
*/
public function showEditUser()
{
$data = [
'user' => \Auth::user(),
'modal_id' => \Input::get('modal_id'),
'user' => Auth::user(),
];
return \View::make('ManageUser.Modals.EditUser', $data);
return view('ManageUser.Modals.EditUser', $data);
}
public function postEditUser()
/**
* Updates the current user
*
* @param Request $request
* @return mixed
*/
public function postEditUser(Request $request)
{
$rules = [
'email' => ['required', 'email', 'exists:users,email,account_id,'.Auth::user()->account_id],
@ -37,10 +48,10 @@ class UserController extends Controller
'first_name.required' => 'Please enter your first name.',
];
$validation = \Validator::make(Input::all(), $rules, $messages);
$validation = Validator::make($request->all(), $rules, $messages);
if ($validation->fails()) {
return Response::json([
return response()->json([
'status' => 'error',
'messages' => $validation->messages()->toArray(),
]);
@ -48,17 +59,16 @@ class UserController extends Controller
$user = Auth::user();
if (Input::get('password')) {
$user->password = \Hash::make(Input::get('new_password'));
if ($request->get('password')) {
$user->password = Hash::make(Input::get('new_password'));
}
$user->first_name = Input::get('first_name');
$user->last_name = Input::get('last_name');
$user->first_name = $request->get('first_name');
$user->last_name = $request->get('last_name');
//$user->email = Input::get('email');
$user->save();
return Response::json([
return response()->json([
'status' => 'success',
'message' => 'Successfully Edited User',
]);

View File

@ -3,7 +3,6 @@
namespace App\Http\Controllers;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Routing\Controller;
class UserLogoutController extends Controller
{
@ -14,10 +13,15 @@ class UserLogoutController extends Controller
$this->auth = $auth;
}
/**
* Log a use out and redirect them
*
* @return mixed
*/
public function doLogout()
{
$this->auth->logout();
return \Redirect::to('/?logged_out=yup');
return redirect()->to('/?logged_out=yup');
}
}

View File

@ -73,6 +73,12 @@ class UserSignupController extends Controller
return redirect('login');
}
/**
* Confirm a user email
*
* @param $confirmation_code
* @return mixed
*/
public function confirmEmail($confirmation_code)
{
$user = User::whereConfirmationCode($confirmation_code)->first();

View File

@ -1,36 +1,54 @@
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
'App\Http\Middleware\VerifyCsrfToken',
'App\Http\Middleware\GeneralChecks',
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Cookie\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\App\Http\Middleware\GeneralChecks::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\Illuminate\Cookie\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
],
'api' => [
'throttle:60,1',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => 'App\Http\Middleware\Authenticate',
'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth',
'guest' => 'App\Http\Middleware\RedirectIfAuthenticated',
'first.run' => 'App\Http\Middleware\FirstRunMiddleware',
'installed' => 'App\Http\Middleware\CheckInstalled',
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'first.run' => \App\Http\Middleware\FirstRunMiddleware::class,
'installed' => \App\Http\Middleware\CheckInstalled::class,
];
}

View File

@ -3,47 +3,27 @@
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Support\Facades\Auth;
class Authenticate
{
/**
* The Guard implementation.
*
* @var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* @param Guard $auth
*
* @return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next)
public function handle($request, Closure $next, $guard = null)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
if (Auth::guard($guard)->guest()) {
if ($request->is('api/*') || $request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
}
return $next($request);
}
}
}

View File

@ -3,6 +3,7 @@
namespace app\Http\Middleware;
use App\Attendize\Utils;
use App\Models\Account;
use Closure;
use Redirect;
use Request;
@ -19,10 +20,20 @@ class CheckInstalled
*/
public function handle($request, Closure $next)
{
/*
* Check if the 'installed' file has been created
*/
if (!file_exists(base_path('installed')) && !Utils::isAttendize()) {
return Redirect::to('install');
}
/*
* Redirect user to signup page if there are no accounts
*/
if(Account::count() === 0 && !$request->is('signup*')) {
return redirect()->to('signup');
}
$response = $next($request);
return $response;

View File

@ -19,7 +19,7 @@ class FirstRunMiddleware
*/
public function handle($request, Closure $next)
{
/*
* If there are no organisers then redirect the user to create one
* else - if there's only one organiser bring the user straight there.

View File

@ -21,7 +21,7 @@ class GeneralChecks
if (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(?i)msie [2-8]/', $_SERVER['HTTP_USER_AGENT'])) {
Session::flash('message', 'Please update your browser. This application requires a modern browser.');
}
$response = $next($request);
return $response;

View File

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
class StoreEventQuestionRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required',
'option' => 'array',
];
}
}

55
app/Http/api_routes.php Normal file
View File

@ -0,0 +1,55 @@
<?php
Route::group(['prefix' => 'api', 'middleware' => 'auth:api'], function () {
/*
* ---------------
* Organisers
* ---------------
*/
/*
* ---------------
* Events
* ---------------
*/
Route::resource('events', 'API\EventsApiController');
/*
* ---------------
* Attendees
* ---------------
*/
Route::resource('attendees', 'API\AttendeesApiController');
/*
* ---------------
* Orders
* ---------------
*/
/*
* ---------------
* Users
* ---------------
*/
/*
* ---------------
* Check-In / Check-Out
* ---------------
*/
Route::get('/', function () {
return response()->json([
'Hello' => Auth::guard('api')->user()->full_name . '!'
]);
});
});

View File

@ -1,18 +1,14 @@
<?php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
* Include our API routes file
*/
include_once('api_routes.php');
/*
* -------------------------
* Installer
* -------------------------
*/
Route::get('install', [
'as' => 'showInstaller',
@ -125,7 +121,7 @@ Route::group(['prefix' => 'e'], function () {
]);
Route::post('/{event_id}/contact_organiser', [
'as' => 'postContactOrganiser',
'as' => 'postContactOrganiser',
'uses' => 'EventViewController@postContactOrganiser',
]);
@ -153,7 +149,6 @@ Route::group(['prefix' => 'e'], function () {
]);
Route::post('{event_id}/checkout/create', [
'as' => 'postCreateOrder',
'uses' => 'EventCheckoutController@postCreateOrder',
@ -161,7 +156,7 @@ Route::group(['prefix' => 'e'], function () {
});
/*
* View order
* Public view order routes
*/
Route::get('order/{order_reference}', [
'as' => 'showOrderDetails',
@ -174,25 +169,25 @@ Route::get('order/{order_reference}/tickets', [
]);
/*
* Begin logged in stuff
* Backend routes
*/
Route::group(['middleware' => ['auth', 'first.run']], function () {
/*
* Edit User
*/
Route::group(['prefix' => 'user'], function () {
Route::group(['prefix' => 'user'], function () {
Route::get('/', [
Route::get('/', [
'as' => 'showEditUser',
'uses' => 'UserController@showEditUser',
]);
Route::post('/', [
Route::post('/', [
'as' => 'postEditUser',
'uses' => 'UserController@postEditUser',
]);
});
});
/*
* Manage account
@ -221,42 +216,48 @@ Route::group(['middleware' => ['auth', 'first.run']], function () {
});
Route::get('select_organiser', [
'as' => 'showSelectOrganiser',
'uses' => 'OrganiserController@showSelectOragniser',
'as' => 'showSelectOrganiser',
'uses' => 'OrganiserController@showSelectOragniser',
]);
/*
* New organiser dashboard
* Organiser routes
*/
Route::group(['prefix' => 'organiser'], function () {
/*
* -----------
* Organiser Dashboard
* -----------
*/
Route::get('{organiser_id}/dashboard', [
'as' => 'showOrganiserDashboard',
'uses' => 'OrganiserDashboardController@showDashboard',
]);
/*
* -----------
* Organiser events
* -----------
*/
Route::get('{organiser_id}/events', [
'as' => 'showOrganiserEvents',
'uses' => 'OrganiserEventsController@showEvents',
]);
/*
* -----------
* Organiser events
* -----------
*/
Route::get('{organiser_id}/customize', [
'as' => 'showOrganiserCustomize',
'uses' => 'OrganiserCustomizeController@showCustomize',
]);
Route::get('create', [
'as' => 'showCreateOrganiser',
'uses' => 'OrganiserController@showCreateOrganiser',
]);
Route::post('create', [
'as' => 'postCreateOrganiser',
'uses' => 'OrganiserController@postCreateOrganiser',
]);
Route::get('{organiser_id}/edit', [
'as' => 'showEditOrganiser',
'uses' => 'OrganiserController@showEditOrganiser',
]);
Route::post('{organiser_id}/edit', [
'as' => 'postEditOrganiser',
'uses' => 'OrganiserCustomizeController@postEditOrganiser',
]);
Route::post('{organiser_id}/page_design', [
'as' => 'postEditOrganiserPageDesign',
'uses' => 'OrganiserCustomizeController@postEditOrganiserPageDesign'
]);
});
/*
@ -264,36 +265,6 @@ Route::group(['middleware' => ['auth', 'first.run']], function () {
*/
Route::group(['prefix' => 'events'], function () {
/*
* -----------
* Events Dashboard - Organisers
* -----------
*/
Route::get('/organiser/create', [
'as' => 'showCreateOrganiser',
'uses' => 'OrganiserController@showCreateOrganiser',
]);
Route::post('/organiser/create', [
'as' => 'postCreateOrganiser',
'uses' => 'OrganiserController@postCreateOrganiser',
]);
Route::get('/organiser/{organiser_id}', [
'as' => 'showOrganiserEventsDashboard',
'uses' => 'OrganiserController@showOrganiserDashboard',
]);
Route::get('/organiser/{organiser_id?}', [
'as' => 'showSearchEventsDashboard',
'uses' => 'OrganiserController@showOrganiserDashboard',
]);
Route::get('/organiser/{organiser_id}/edit', [
'as' => 'showEditOrganiser',
'uses' => 'OrganiserController@showEditOrganiser',
]);
Route::post('/organiser/{organiser_id}/edit', [
'as' => 'postEditOrganiser',
'uses' => 'OrganiserCustomizeController@postEditOrganiser',
]);
/*
* ----------
* Create Event
@ -319,39 +290,42 @@ Route::group(['middleware' => ['auth', 'first.run']], function () {
]);
/*
* Event Management Stuff
* Event management routes
*/
Route::group(['prefix' => 'event'], function () {
/*
* -------
* Dashboard
* -------
*/
Route::get('{event_id}/dashboard/', [
'as' => 'showEventDashboard',
'uses' => 'EventDashboardController@showDashboard', ]
'as' => 'showEventDashboard',
'uses' => 'EventDashboardController@showDashboard',
]
);
Route::get('{event_id}', function ($event_id) {
return Redirect::route('showEventDashboard', [
'event_id' => $event_id,
'event_id' => $event_id,
]);
});
/*
* @todo Move to a controller
*/
Route::get('{event_id}/go_live', ['as' => 'MakeEventLive', function ($event_id) {
$event = \App\Models\Event::scope()->findOrFail($event_id);
$event->is_live = 1;
$event->save();
\Session::flash('message', 'Event Successfully Made Live! You can undo this action in event settings page.');
Route::get('{event_id}/go_live', [
'as' => 'MakeEventLive',
function ($event_id) {
$event = \App\Models\Event::scope()->findOrFail($event_id);
$event->is_live = 1;
$event->save();
\Session::flash('message',
'Event Successfully Made Live! You can undo this action in event settings page.');
return Redirect::route('showEventDashboard', [
'event_id' => $event_id,
]);
}]);
return Redirect::route('showEventDashboard', [
'event_id' => $event_id,
]);
}
]);
/*
* -------
@ -439,14 +413,24 @@ Route::group(['middleware' => ['auth', 'first.run']], function () {
'uses' => 'EventAttendeesController@postResendTicketToAttendee',
]);
Route::get('{event_id}/attendees/create', [
'as' => 'showCreateAttendee',
'uses' => 'EventAttendeesController@showCreateAttendee',
Route::get('{event_id}/attendees/invite', [
'as' => 'showInviteAttendee',
'uses' => 'EventAttendeesController@showInviteAttendee',
]);
Route::post('{event_id}/attendees/create', [
'as' => 'postCreateAttendee',
'uses' => 'EventAttendeesController@postCreateAttendee',
Route::post('{event_id}/attendees/invite', [
'as' => 'postInviteAttendee',
'uses' => 'EventAttendeesController@postInviteAttendee',
]);
Route::get('{event_id}/attendees/import', [
'as' => 'showImportAttendee',
'uses' => 'EventAttendeesController@showImportAttendee',
]);
Route::post('{event_id}/attendees/import', [
'as' => 'postImportAttendee',
'uses' => 'EventAttendeesController@postImportAttendee',
]);
Route::get('{event_id}/attendees/print', [
@ -454,6 +438,11 @@ Route::group(['middleware' => ['auth', 'first.run']], function () {
'uses' => 'EventAttendeesController@showPrintAttendees',
]);
Route::get('{event_id}/attendees/{attendee_id}/export_ticket', [
'as' => 'showExportTicket',
'uses' => 'EventAttendeesController@showExportTicket',
]);
Route::get('{event_id}/attendees/export/{export_as?}', [
'as' => 'showExportAttendees',
'uses' => 'EventAttendeesController@showExportAttendees',
@ -563,6 +552,73 @@ Route::group(['middleware' => ['auth', 'first.run']], function () {
'uses' => 'EventCustomizeController@postEditEventFees',
]);
/*
* -------
* Event Widget page
* -------
*/
Route::get('{event_id}/widgets', [
'as' => 'showEventWidgets',
'uses' => 'EventWidgetsController@showEventWidgets',
]);
/*
* -------
* Event Survey page
* -------
*/
Route::get('{event_id}/surveys', [
'as' => 'showEventSurveys',
'uses' => 'EventSurveyController@showEventSurveys',
]);
Route::get('{event_id}/question/create', [
'as' => 'showCreateEventQuestion',
'uses' => 'EventSurveyController@showCreateEventQuestion'
]);
Route::post('{event_id}/question/create', [
'as' => 'postCreateEventQuestion',
'uses' => 'EventSurveyController@postCreateEventQuestion'
]);
Route::get('{event_id}/question/{question_id}', [
'as' => 'showEditEventQuestion',
'uses' => 'EventSurveyController@showEditEventQuestion'
]);
Route::post('{event_id}/question/{question_id}', [
'as' => 'postEditEventQuestion',
'uses' => 'EventSurveyController@postEditEventQuestion'
]);
Route::post('{event_id}/question/delete/{question_id}', [
'as' => 'postDeleteEventQuestion',
'uses' => 'EventSurveyController@postDeleteEventQuestion'
]);
Route::get('{event_id}/question/{question_id}/answers', [
'as' => 'showEventQuestionAnswers',
'uses' => 'EventSurveyController@showEventQuestionAnswers',
]);
Route::post('{event_id}/questions/update_order', [
'as' => 'postUpdateQuestionsOrder',
'uses' => 'EventSurveyController@postUpdateQuestionsOrder'
]);
Route::get('{event_id}/answers/export/{export_as?}', [
'as' => 'showExportAnswers',
'uses' => 'EventSurveyController@showExportAnswers',
]);
Route::post('{event_id}/question/{question_id}/enable', [
'as' => 'postEnableQuestion',
'uses' => 'EventSurveyController@postEnableQuestion',
]);
/*
* -------
* Check In App
@ -581,6 +637,38 @@ Route::group(['middleware' => ['auth', 'first.run']], function () {
'uses' => 'EventCheckInController@postCheckInAttendee',
]);
Route::post('{event_id}/qrcode_check_in', [
'as' => 'postQRCodeCheckInAttendee',
'uses' => 'EventCheckInController@postCheckInAttendeeQr',
]);
Route::post('{event_id}/confirm_order_tickets/{order_id}', [
'as' => 'confirmCheckInOrderTickets',
'uses' => 'EventCheckInController@confirmOrderTicketsQr',
]);
/*
* -------
* QRCode Check In App
* -------
Route::get('{event_id}/qrcode_check_in', [
'as' => 'showQRCodeChechIn',
'uses' => 'EventQrcodeCheckInController@showCheckIn',
]);
Route::post('{event_id}/qrcode_check_in', [
'as' => 'postQRCodeCheckInAttendee',
'uses' => 'EventQrcodeCheckInController@postCheckInAttendee',
]);
Route::match(['PUT', 'PATCH'], '{event_id}/confirm_order_tickets/{order_id}', [
'as' => 'confirmCheckInOrderTickets',
'uses' => 'EventQrcodeCheckInController@confirmOrderTickets',
]);
*/
/*
* -------
* Promote
@ -593,20 +681,14 @@ Route::group(['middleware' => ['auth', 'first.run']], function () {
});
});
Route::post('queue/push', function () {
// set_time_limit(300);
return Queue::marshal();
});
Route::get('/', function () {
return Redirect::route('showSelectOrganiser');
});
Route::get('/terms_and_conditions', ['as' => 'termsAndConditions', function () {
Route::get('/terms_and_conditions', [
'as' => 'termsAndConditions',
function () {
return 'TODO: add terms and cond';
}
]);
return 'TODO: add terms and cond';
//return View::make('Public.Website.Terms_and_Cond');
}]);

View File

@ -0,0 +1,80 @@
<?php
namespace App\Jobs;
use App\Jobs\Job;
use App\Models\Order;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Log;
use PDF;
class GenerateTicket extends Job implements ShouldQueue
{
use InteractsWithQueue, SerializesModels;
protected $reference;
protected $order_reference;
protected $attendee_reference_index;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($reference)
{
Log::info("Generating ticket: #".$reference);
$this->reference = $reference;
$this->order_reference = explode("-", $reference)[0];
if (strpos($reference, "-")) {
$this->attendee_reference_index = explode("-", $reference)[1];
}
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
$file_name = $this->reference;
$file_path = public_path(config('attendize.event_pdf_tickets_path')).'/'.$file_name;
$file_with_ext = $file_path.".pdf";
if (file_exists($file_with_ext)) {
Log::info("Use ticket from cache: ".$file_with_ext);
return;
}
$order = Order::where('order_reference', $this->order_reference)->first();
Log::info($order);
$event = $order->event;
$query = $order->attendees();
if ($this->isAttendeeTicket()) {
$query = $query->where('reference_index', '=', $this->attendee_reference_index);
}
$attendees = $query->get();
$data = [
'order' => $order,
'event' => $event,
'attendees' => $attendees,
'css' => file_get_contents(public_path('assets/stylesheet/ticket.css')),
'image' => base64_encode(file_get_contents(public_path($event->organiser->full_logo_path))),
];
PDF::setOutputMode('F'); // force to file
PDF::html('Public.ViewEvent.Partials.PDFTicket', $data, $file_path);
Log::info("Ticket generated!");
}
private function isAttendeeTicket() {
return ($this->attendee_reference_index != null);
}
}

20
app/Jobs/Job.php Normal file
View File

@ -0,0 +1,20 @@
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
abstract class Job
{
/*
|--------------------------------------------------------------------------
| Queueable Jobs
|--------------------------------------------------------------------------
|
| This job base class provides a central location to place any logic that
| is shared across all of your jobs. The trait included with the class
| provides access to the "onQueue" and "delay" queue helper methods.
|
*/
use Queueable;
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Mailers;
use Mail;
use Log;
class TicketMailer
{
public static function sendOrderTickets($order) {
Log::info("Sending ticket to: ".$order->email);
$data = [
'order' => $order,
];
Mail::queue('Mailers.TicketMailer.SendOrderTickets', $data, function($message) use ($order) {
$message->to($order->email);
$message->subject('Your tickets for the event '.$order->event->title);
$file_name = $order->order_reference;
$file_path = public_path(config('attendize.event_pdf_tickets_path')).'/'.$file_name.'.pdf';
$message->attach($file_path);
});
}
public static function sendAttendeeTicket($attendee) {
Log::info("Sending ticket to: ".$attendee->email);
$data = [
'attendee' => $attendee,
];
Mail::queue('Mailers.TicketMailer.SendAttendeeTicket', $data, function($message) use ($attendee) {
$message->to($attendee->email);
$message->subject('Your ticket for the event '.$attendee->order->event->title);
$file_name = $attendee->getReferenceAttribute();
$file_path = public_path(config('attendize.event_pdf_tickets_path')).'/'.$file_name.'.pdf';
$message->attach($file_path);
});
}
public static function sendAttendeeInvite($attendee) {
Log::info("Sending invite to: ".$attendee->email);
$data = [
'attendee' => $attendee,
];
Mail::queue('Mailers.TicketMailer.SendAttendeeInvite', $data, function($message) use ($attendee) {
$message->to($attendee->email);
$message->subject('Your ticket for the event '.$attendee->order->event->title);
$file_name = $attendee->getReferenceAttribute();
$file_path = public_path(config('attendize.event_pdf_tickets_path')).'/'.$file_name.'.pdf';
$message->attach($file_path);
});
}
}

View File

@ -95,7 +95,7 @@ class Account extends MyBaseModel
*/
public function currency()
{
return $this->hasOne('\App\Models\Currency');
return $this->belongsTo('\App\Models\Currency');
}
/**

View File

@ -32,6 +32,8 @@ class Attendee extends MyBaseModel
'ticket_id',
'account_id',
'reference',
'has_arrived',
'arrival_time'
];
/**
@ -76,6 +78,14 @@ class Attendee extends MyBaseModel
{
return $this->belongsTo('\App\Models\Event');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function answers()
{
return $this->hasMany('App\Models\QuestionAnswer');
}
/**
* Scope a query to return attendees that have not cancelled.
@ -89,10 +99,15 @@ class Attendee extends MyBaseModel
return $query->where('attendees.is_cancelled', '=', 0);
}
//
// public function getReferenceAttribute() {
// return $this->order->order_reference
// }
/**
* Get the attendee reference
*
* @return string
*/
public function getReferenceAttribute() {
return $this->order->order_reference . '-' . $this->reference_index;
}
/**
* Get the full name of the attendee.
@ -104,6 +119,8 @@ class Attendee extends MyBaseModel
return $this->first_name.' '.$this->last_name;
}
/**
* The attributes that should be mutated to dates.
*

8
app/Models/Country.php Normal file
View File

@ -0,0 +1,8 @@
<?php
namespace App\Models;
class Country extends \Illuminate\Database\Eloquent\Model
{
}

View File

@ -10,7 +10,7 @@ use URL;
class Event extends MyBaseModel
{
use SoftDeletes;
/**
* The validation rules.
*
@ -51,6 +51,16 @@ class Event extends MyBaseModel
return $this->belongsToMany('\App\Models\Question', 'event_question');
}
/**
* The questions associated with the event.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function questions_with_tashed()
{
return $this->belongsToMany('\App\Models\Question', 'event_question')->withTrashed();
}
/**
* The attendees associated with the event.
*
@ -192,7 +202,7 @@ class Event extends MyBaseModel
}
/**
* Get the currency sybol.
* Get the currency symbol.
*
* @return \Illuminate\Support\Collection
*/

View File

@ -33,10 +33,11 @@ class EventStats extends \Illuminate\Database\Eloquent\Model
$amount = $amount * -1;
}
$ticket->ticket_revenue = $ticket->ticket_revenue + $amount;
$ticket->sales_volume = $ticket->sales_volume + $amount;
return $ticket->save();
}
/**
* Update the amount of views a ticket has earned.
@ -49,7 +50,7 @@ class EventStats extends \Illuminate\Database\Eloquent\Model
{
$stats = $this->firstOrNew([
'event_id' => $event_id,
'date' => DB::raw('CURDATE()'),
'date' => DB::raw('CURRENT_DATE'),
]);
$cookie_name = 'visitTrack_'.$event_id.'_'.date('dmy');
@ -73,7 +74,7 @@ class EventStats extends \Illuminate\Database\Eloquent\Model
{
$stats = $this->firstOrNew([
'event_id' => $event_id,
'date' => DB::raw('CURDATE()'),
'date' => DB::raw('CURRENT_DATE'),
]);
$stats->sales_volume = $stats->sales_volume + $amount;
@ -93,7 +94,7 @@ class EventStats extends \Illuminate\Database\Eloquent\Model
{
$stats = $this->firstOrNew([
'event_id' => $event_id,
'date' => DB::raw('CURDATE()'),
'date' => DB::raw('CURRENT_DATE'),
]);
$stats->increment('tickets_sold', $count);

View File

@ -126,7 +126,12 @@ class MyBaseModel extends \Illuminate\Database\Eloquent\Model
}
/**
* @param int $accountId
* Ensures each query looks for account_id
*
* @param $query
* @param bool $accountId
* @param Request $request
* @return mixed
*/
public function scopeScope($query, $accountId = false)
{

View File

@ -98,6 +98,7 @@ class Order extends MyBaseModel
return $this->belongsTo('\App\Models\OrderStatus');
}
/**
* Get the organizer fee of the order.
*
@ -125,7 +126,7 @@ class Order extends MyBaseModel
*/
public function getFullNameAttribute()
{
return $this->first_name.' '.$this->last_name;
return $this->first_name . ' ' . $this->last_name;
}
/**
@ -142,23 +143,25 @@ class Order extends MyBaseModel
'event' => $this->event,
'tickets' => $this->event->tickets,
'attendees' => $this->attendees,
'css' => file_get_contents(public_path('assets/stylesheet/ticket.css')),
'image' => base64_encode(file_get_contents(public_path($this->event->organiser->full_logo_path))),
];
$pdf_file_path = public_path(config('attendize.event_pdf_tickets_path')).'/'.$this->order_reference;
$pdf_file = $pdf_file_path.'.pdf';
$pdf_file_path = public_path(config('attendize.event_pdf_tickets_path')) . '/' . $this->order_reference;
$pdf_file = $pdf_file_path . '.pdf';
if (file_exists($pdf_file)) {
return true;
}
if (!is_dir($pdf_file_path)) {
File::makeDirectory($pdf_file_path, 0777, true, true);
File::makeDirectory(dirname($pdf_file_path), 0777, true, true);
}
PDF::setOutputMode('F'); // force to file
PDF::html('Public.ViewEvent.Partials.PDFTicket', $data, $pdf_file_path);
$this->ticket_pdf_path = config('attendize.event_pdf_tickets_path').'/'.$this->order_reference.'.pdf';
$this->ticket_pdf_path = config('attendize.event_pdf_tickets_path') . '/' . $this->order_reference . '.pdf';
$this->save();
return file_exists($pdf_file);
@ -172,7 +175,7 @@ class Order extends MyBaseModel
parent::boot();
static::creating(function ($order) {
$order->order_reference = strtoupper(str_random(5)).date('jn');
$order->order_reference = strtoupper(str_random(5)) . date('jn');
});
}
}

View File

@ -29,6 +29,16 @@ class Organiser extends MyBaseModel
'organiser_logo.mimes' => 'Please select a valid image type (jpeg, jpg, png)',
];
/**
* The account associated with the organiser
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function account()
{
return $this->belongsTo('\App\Models\Account');
}
/**
* The events associated with the organizer.
*
@ -49,6 +59,16 @@ class Organiser extends MyBaseModel
return $this->hasManyThrough('\App\Models\Attendee', '\App\Models\Event');
}
/**
* Get the orders related to an organiser
*
* @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
*/
public function orders()
{
return $this->hasManyThrough('\App\Models\Order', '\App\Models\Event');
}
/**
* Get the full logo path of the organizer.
*

View File

@ -16,6 +16,7 @@ class Question extends MyBaseModel
/**
* The events associated with the question.
*
* @access public
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function events()
@ -26,10 +27,44 @@ class Question extends MyBaseModel
/**
* The type associated with the question.
*
* @access public
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function question_types()
public function question_type()
{
return $this->hasOne('\App\Models\QuestionType');
return $this->belongsTo('\App\Models\QuestionType');
}
public function answers()
{
return $this->hasMany('\App\Models\QuestionAnswer');
}
/**
* The options associated with the question.
*
* @access public
* @return \Illuminate\Database\Eloquent\Relations\HasOne
*/
public function options()
{
return $this->hasMany('\App\Models\QuestionOption');
}
public function tickets()
{
return $this->belongsToMany('\App\Models\Ticket');
}
/**
* Scope a query to only include active questions.
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeIsEnabled($query)
{
return $query->where('is_enabled', 1);
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Models;
class QuestionAnswer extends MyBaseModel
{
protected $fillable = [
'question_id',
'event_id',
'attendee_id',
'account_id',
'answer_text',
'questionable_id',
'questionable_type',
];
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function event()
{
return $this->belongsToMany('\App\Models\Event');
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function question()
{
return $this->belongsTo('\App\Models\Question')->withTrashed();
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function attendee()
{
return $this->belongsTo('\App\Models\Attendee');
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class QuestionOption extends MyBaseModel
{
/**
* The attributes that are mass assignable.
*
* @access protected
* @var array
*/
protected $fillable = ['name'];
/**
* Indicates if the model should be timestamped.
*
* @access public
* @var bool
*/
public $timestamps = false;
/**
* The question associated with the question option.
*
* @access public
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function question()
{
return $this->belongsTo('\App\Models\Question');
}
}

View File

@ -61,7 +61,7 @@ class Ticket extends MyBaseModel
*/
public function questions()
{
return $this->belongsToMany('\App\Models\Question', 'ticket_question');
return $this->belongsToMany('\App\Models\Question');
}
/**

View File

@ -133,6 +133,16 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
return 'remember_token';
}
/**
* Get the full name of the user.
*
* @return string
*/
public function getFullNameAttribute()
{
return $this->first_name.' '.$this->last_name;
}
/**
* Boot all of the bootable traits on the model.
*/
@ -142,6 +152,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
static::creating(function ($user) {
$user->confirmation_code = str_random();
$user->api_token = str_random(60);
});
}
}

View File

@ -13,7 +13,7 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot()
{
require app_path('Attendize/constants.php');
//require app_path('Attendize/constants.php');
}
/**

View File

@ -0,0 +1,31 @@
<?php
namespace App\Providers;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any application authentication / authorization services.
*
* @param \Illuminate\Contracts\Auth\Access\Gate $gate
* @return void
*/
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
//
}
}

View File

@ -1,5 +1,5 @@
{
"name": "Attendize - Ticket Selling & Event Management",
"name": "attendize-event-ticketing",
"version": "1.0.0",
"authors": [
"daveearley <dave@attendize.com>"
@ -27,7 +27,11 @@
"fontawesome": "~4.2.0",
"simplemde": "~1.8.1",
"bootstrap-touchspin": "~3.0.1",
"jquery-minicolors": "~2.2.3"
"jquery-minicolors": "^2.2.4",
"fullcalendar": "^2.7.1",
"vue": "^1.0.24",
"vue-resource": "^0.7.0",
"html.sortable": "^0.3.1"
},
"resolutions": {
"jquery": ">=1.5",

View File

@ -6,8 +6,8 @@
"type": "project",
"homepage" : "https://www.attendize.com",
"require": {
"laravel/framework": "5.1.20",
"illuminate/html": "~5.0",
"laravel/framework": "5.2.*",
"laravelcollective/html": "~5.0",
"milon/barcode": "dev-master",
"iron-io/iron_mq": "2.*",
"intervention/image": "dev-master",
@ -25,13 +25,17 @@
"omnipay/paypal": "*",
"omnipay/bitpay": "dev-master",
"omnipay/coinbase": "dev-master",
"barryvdh/laravel-ide-helper": "^2.1"
"laracasts/utilities": "^2.1",
"predis/predis": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
"phpspec/phpspec": "~2.1",
"fzaninotto/faker": "^1.5"
"fzaninotto/faker": "^1.5",
"symfony/dom-crawler": "~3.0",
"symfony/css-selector": "~3.0",
"doctrine/dbal": "~2.3",
"barryvdh/laravel-ide-helper": "^2.1"
},
"autoload": {

5849
composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,107 +3,133 @@
return [
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
|--------------------------------------------------------------------------
| Application Environment
|--------------------------------------------------------------------------
|
| This value determines the "environment" your application is currently
| running in. This may determine how you prefer to configure various
| services your application utilizes. Set this in your ".env" file.
|
*/
'env' => env('APP_ENV', 'production'),
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => env('APP_URL'),
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
'fallback_locale' => 'en',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => env('APP_KEY', 'SomeRandomString'),
'cipher' => MCRYPT_RIJNDAEL_128,
/*
|--------------------------------------------------------------------------
| Logging Configuration
|--------------------------------------------------------------------------
|
| Here you may configure the log settings for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Settings: "single", "daily", "syslog", "errorlog"
|
*/
'log' => 'daily',
|--------------------------------------------------------------------------
| Logging Configuration
|--------------------------------------------------------------------------
|
| Here you may configure the log settings for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Settings: "single", "daily", "syslog", "errorlog"
|
*/
'log' => env('LOG', 'errorlog'),
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Foundation\Providers\ArtisanServiceProvider::class,
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Routing\ControllerServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
@ -120,19 +146,16 @@ return [
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
Illuminate\Html\HtmlServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\BusServiceProvider::class,
App\Providers\ConfigServiceProvider::class,
App\Providers\AuthServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\HelpersServiceProvider::class,
Collective\Html\HtmlServiceProvider::class,
/*
* Third Party Service Providers...
@ -146,17 +169,21 @@ return [
Mews\Purifier\PurifierServiceProvider::class,
MaxHoffmann\Parsedown\ParsedownServiceProvider::class,
Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
Laracasts\Utilities\JavaScript\JavaScriptServiceProvider::class,
],
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
@ -191,8 +218,8 @@ return [
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Form' => Illuminate\Html\FormFacade::class,
'HTML' => Illuminate\Html\HtmlFacade::class,
'Form' => Collective\Html\FormFacade::class,
'HTML' => Collective\Html\HtmlFacade::class,
'Str' => Illuminate\Support\Str::class,
'Utils' => App\Attendize\Utils::class,
'Carbon' => Carbon\Carbon::class,

View File

@ -2,6 +2,10 @@
return [
'version' => file_get_contents(base_path('VERSION')),
'ticket_status_sold_out' => 1,
'ticket_status_after_sale_date' => 2,//
'enable_test_payments' => env('ENABLE_TEST_PAYMENTS', false),
'payment_gateway_stripe' => 1,
@ -21,13 +25,11 @@ return [
'event_pdf_tickets_path' => 'user_content/pdf_tickets',
'event_bg_images' => 'assets/images/public/EventPage/backgrounds',
'fallback_organiser_logo_url' => '/assets/images/logo-100x100-lightBg.png',
'fallback_organiser_logo_url' => '/assets/images/logo-dark.png',
'cdn_url' => '',
'checkout_timeout_after' => app()->environment('local', 'development') ? 30 : 8, #mintutes
'checkout_timeout_after' => env('CHECKOUT_TIMEOUT_AFTER', 30), #minutes
'ticket_status_sold_out' => 1,
'ticket_status_after_sale_date' => 2,
'ticket_status_before_sale_date' => 3,
'ticket_status_on_sale' => 4,
'ticket_status_off_sale' => 5,
@ -35,11 +37,21 @@ return [
'ticket_booking_fee_fixed' => 0,
'ticket_booking_fee_percentage' => 0,
/* Order statuses */
'order_complete' => 1,
'order_refunded' => 2,
'order_partially_refunded' => 3,
'order_cancelled' => 4,
/* Attendee question types */
'question_textbox_single' => 1,
'question_textbox_multi' => 2,
'question_dropdown_single' => 3,
'question_dropdown_multi' => 4,
'question_checkbox_multi' => 5,
'question_radio_single' => 6,
'default_timezone' => 30, #Europe/Dublin
'default_currency' => 2, #Euro
'default_date_format' => 'j M, Y',

View File

@ -4,64 +4,104 @@ return [
/*
|--------------------------------------------------------------------------
| Default Authentication Driver
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the authentication driver that will be utilized.
| This driver manages the retrieval and authentication of the users
| attempting to get access to protected areas of your application.
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'driver' => 'eloquent',
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Authentication Model
|--------------------------------------------------------------------------
|
| When using the "Eloquent" authentication driver, we need to know which
| Eloquent model should be used to retrieve your users. Of course, it
| is often just the "User" model but you may use whatever you like.
|
*/
'model' => 'App\Models\User',
/*
|--------------------------------------------------------------------------
| Authentication Table
|--------------------------------------------------------------------------
|
| When using the "Database" authentication driver, we need to know which
| table should be used to retrieve your users. We have chosen a basic
| default value but you may easily change it to any table you like.
|
*/
'table' => 'users',
/*
|--------------------------------------------------------------------------
| Password Reset Settings
| Resetting Passwords
|--------------------------------------------------------------------------
|
| Here you may set the options for resetting passwords including the view
| that is your password reset e-mail. You can also set the name of the
| that is your password reset e-mail. You may also set the name of the
| table that maintains all of the reset tokens for your application.
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'password' => [
'email' => 'Emails.Auth.Reminder',
'table' => 'password_resets',
'expire' => 60,
'passwords' => [
'users' => [
'provider' => 'users',
'email' => 'Emails.Auth.Reminder',
'table' => 'password_resets',
'expire' => 60,
],
],
];

View File

@ -16,8 +16,6 @@ return [
'files' => [
realpath(__DIR__.'/../app/Providers/AppServiceProvider.php'),
realpath(__DIR__.'/../app/Providers/BusServiceProvider.php'),
realpath(__DIR__.'/../app/Providers/ConfigServiceProvider.php'),
realpath(__DIR__.'/../app/Providers/EventServiceProvider.php'),
realpath(__DIR__.'/../app/Providers/RouteServiceProvider.php'),

View File

@ -115,7 +115,7 @@ return [
'cluster' => false,
'default' => [
'host' => '127.0.0.1',
'host' => 'redis',
'port' => 6379,
'database' => 0,
],

30
config/javascript.php Normal file
View File

@ -0,0 +1,30 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| View to Bind JavaScript Vars To
|--------------------------------------------------------------------------
|
| Set this value to the name of the view (or partial) that
| you want to prepend all JavaScript variables to.
| This can be a single view, or an array of views.
| Example: 'footer' or ['footer', 'bottom']
|
*/
'bind_js_vars_to_this_view' => ['Shared.Layouts.ViewJavascript'],
/*
|--------------------------------------------------------------------------
| JavaScript Namespace
|--------------------------------------------------------------------------
|
| By default, we'll add variables to the global window object. However,
| it's recommended that you change this to some namespace - anything.
| That way, you can access vars, like "SomeNamespace.someVariable."
|
*/
'js_namespace' => 'Attendize'
];

View File

@ -106,19 +106,5 @@ return [
|
*/
'sendmail' => '/usr/sbin/sendmail -bs',
/*
|--------------------------------------------------------------------------
| Mail "Pretend"
|--------------------------------------------------------------------------
|
| When this option is enabled, e-mail will not actually be sent over the
| web and will instead be written to your application's logs files so
| you may inspect the message. This is great for local development.
|
*/
'pretend' => false,
'sendmail' => '/usr/sbin/sendmail -bs'
];

View File

@ -36,5 +36,9 @@ return [
'twitter' => [
'widget_id' => env('TWITTER_WIDGET_ID'),
],
'sparkpost' => [
'secret' => env('SPARKPOST_SECRET')
]
];

View File

@ -44,7 +44,7 @@ $factory->define(App\Models\Timezone::class, function (Faker\Generator $faker) {
});
$factory->define(App\Models\Timezone::class, function (Faker\Generator $faker) {
$factory->define(App\Models\DateFormat::class, function (Faker\Generator $faker) {
return [
'format' => "Y-m-d",
'picker_format' => "Y-m-d",
@ -81,9 +81,9 @@ $factory->define(App\Models\Account::class, function (Faker\Generator $faker) {
'last_name' => $faker->lastName,
'email' => $faker->email,
'timezone_id' => factory(App\Models\Timezone::class)->create()->id,
'date_format_id' => factory(App\Models\Timezone::class)->create()->id,
'date_format_id' => factory(App\Models\DateFormat::class)->create()->id,
'datetime_format_id' => factory(App\Models\DateTimeFormat::class)->create()->id,
'currency_id' => factory()->create()->id,
'currency_id' => factory(App\Models\Currency::class)->create()->id,
'name' => $faker->name,
'last_ip' => "127.0.0.1",
'last_login_date' => Carbon::now()->subDays(2),
@ -92,7 +92,7 @@ $factory->define(App\Models\Account::class, function (Faker\Generator $faker) {
'city' => $faker->city,
'state' => $faker->stateAbbr,
'postal_code' => $faker->postcode,
'country_id' => factory(App\Models\Country::class)->create()->id,
// 'country_id' => factory(App\Models\Country::class)->create()->id,
'email_footer' => 'Email footer text',
'is_active' => false,
'is_banned' => false,
@ -101,14 +101,13 @@ $factory->define(App\Models\Account::class, function (Faker\Generator $faker) {
'stripe_refresh_token' => str_random(10),
'stripe_secret_key' => str_random(10),
'stripe_publishable_key' => str_random(10),
'stripe_raw_data' => $faker->text,
];
});
$factory->define(App\Models\User::class, function (Faker\Generator $faker) {
return [
'account_id' => $faker->randomDigit,
'account_id' => factory(App\Models\Account::class)->create()->id,
'first_name' => $faker->firstName,
'last_name' => $faker->lastName,
'phone' => $faker->phoneNumber,
@ -168,7 +167,6 @@ $factory->define(App\Models\Event::class, function (Faker\Generator $faker) {
'location_lat' => $faker->latitude,
'location_long' => $faker->longitude,
'location_google_place_id' => $faker->randomDigit,
'ask_for_all_attendees_info' => 0,
'pre_order_display_message' => $faker->text,
'post_order_display_message' => $faker->text,
'social_share_text' => 'Check Out [event_title] - [event_url]',
@ -270,7 +268,7 @@ $factory->define(App\Models\Attendee::class, function (Faker\Generator $faker) {
];
});
$faker->define(App\Models\Message::class, function (Faker\Generator $faker) {
$factory->define(App\Models\Message::class, function (Faker\Generator $faker) {
return [
'message' => $faker->text,
'subject' => $faker->text,
@ -279,7 +277,7 @@ $faker->define(App\Models\Message::class, function (Faker\Generator $faker) {
];
});
$faker->define(App\Models\EventImage::class, function (Faker\Generator $faker) {
$factory->define(App\Models\EventImage::class, function (Faker\Generator $faker) {
return [
'image_path' => $faker->imageUrl(),
'event_id' => factory(App\Models\Event::class)->create()->id,

View File

@ -28,7 +28,7 @@ class CreateUsersTable extends Migration
$table->integer('quantity_reserved');
$table->datetime('expires');
$table->string('session_id', 45);
$table->timestamps();
$table->nullableTimestamps();
});
Schema::create('timezones', function ($t) {
@ -47,6 +47,7 @@ class CreateUsersTable extends Migration
Schema::create('datetime_formats', function ($t) {
$t->increments('id');
$t->string('format');
$t->string('picker_format');
$t->string('label');
});
@ -62,7 +63,7 @@ class CreateUsersTable extends Migration
$table->string('decimal_point', 3);
$table->string('thousand_point', 3);
$table->integer('status');
$table->timestamps();
$table->nullableTimestamps();
});
@ -82,30 +83,30 @@ class CreateUsersTable extends Migration
$t->unsignedInteger('currency_id')->nullable();
//$t->unsignedInteger('payment_gateway_id')->default(config('attendize.default_payment_gateway'));
$t->timestamps();
$t->nullableTimestamps();
$t->softDeletes();
$t->string('name');
$t->string('last_ip');
$t->timestamp('last_login_date');
$t->string('name')->nullable();
$t->string('last_ip')->nullable();
$t->timestamp('last_login_date')->nullable();
$t->string('address1');
$t->string('address2');
$t->string('city');
$t->string('state');
$t->string('postal_code');
$t->string('address1')->nullable();
$t->string('address2')->nullable();
$t->string('city')->nullable();
$t->string('state')->nullable();
$t->string('postal_code')->nullable();
$t->unsignedInteger('country_id')->nullable();
$t->text('email_footer');
$t->text('email_footer')->nullable();
$t->boolean('is_active')->default(false);
$t->boolean('is_banned')->default(false);
$t->boolean('is_beta')->default(false);
$t->string('stripe_access_token', 55);
$t->string('stripe_refresh_token', 55);
$t->string('stripe_secret_key', 55);
$t->string('stripe_publishable_key', 55);
$t->text('stripe_data_raw', 55);
$t->string('stripe_access_token', 55)->nullable();
$t->string('stripe_refresh_token', 55)->nullable();
$t->string('stripe_secret_key', 55)->nullable();
$t->string('stripe_publishable_key', 55)->nullable();
$t->text('stripe_data_raw', 55)->nullable();
$t->foreign('timezone_id')->references('id')->on('timezones');
$t->foreign('date_format_id')->references('id')->on('date_formats');
@ -121,12 +122,12 @@ class CreateUsersTable extends Migration
$t->increments('id');
$t->unsignedInteger('account_id')->index();
$t->timestamps();
$t->nullableTimestamps();
$t->softDeletes();
$t->string('first_name');
$t->string('last_name');
$t->string('phone');
$t->string('first_name')->nullable();
$t->string('last_name')->nullable();
$t->string('phone')->nullable();
$t->string('email');
$t->string('password');
$t->string('confirmation_code');
@ -142,7 +143,7 @@ class CreateUsersTable extends Migration
$table->increments('id')->index();
$table->timestamps();
$table->nullableTimestamps();
$table->softDeletes();
$table->unsignedInteger('account_id')->index();
@ -150,11 +151,11 @@ class CreateUsersTable extends Migration
$table->string('name');
$table->text('about');
$table->string('email');
$table->string('phone');
$table->string('phone')->nullable();
$table->string('confirmation_key', 20);
$table->string('facebook');
$table->string('twitter');
$table->string('logo_path');
$table->string('logo_path')->nullable();
$table->boolean('is_email_confirmed')->default(0);
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
@ -166,10 +167,10 @@ class CreateUsersTable extends Migration
$t->increments('id');
$t->string('title');
$t->string('location');
$t->string('location')->nullable();
$t->string('bg_type', 15)->default('color');
$t->string('bg_color')->default(config('attendize.event_default_bg_color'));
$t->string('bg_image_path');
$t->string('bg_image_path')->nullable();
$t->text('description');
$t->dateTime('start_date')->nullable();
@ -186,34 +187,34 @@ class CreateUsersTable extends Migration
$t->unsignedInteger('currency_id')->nullable();
$t->foreign('currency_id')->references('id')->on('currencies');
$t->decimal('sales_volume', 13, 2);
$t->decimal('organiser_fees_volume', 13, 2);
$t->decimal('sales_volume', 13, 2)->nullable();
$t->decimal('organiser_fees_volume', 13, 2)->nullable();
$t->decimal('organiser_fee_fixed', 13, 2)->default(0);
$t->decimal('organiser_fee_percentage', 4, 3)->default(0);
$t->unsignedInteger('organiser_id');
$t->foreign('organiser_id')->references('id')->on('organisers');
$t->string('venue_name');
$t->string('venue_name_full');
$t->string('location_address', 355);
$t->string('venue_name_full')->nullable();
$t->string('location_address', 355)->nullable();
$t->string('location_address_line_1', 355);
$t->string('location_address_line_2', 355);
$t->string('location_country');
$t->string('location_country_code');
$t->string('location_country')->nullable();
$t->string('location_country_code')->nullable();
$t->string('location_state');
$t->string('location_post_code');
$t->string('location_street_number');
$t->string('location_lat');
$t->string('location_long');
$t->string('location_google_place_id');
$t->string('location_street_number')->nullable();
$t->string('location_lat')->nullable();
$t->string('location_long')->nullable();
$t->string('location_google_place_id')->nullable();
$t->unsignedInteger('ask_for_all_attendees_info')->default(0);
$t->text('pre_order_display_message');
$t->text('pre_order_display_message')->nullable();
$t->text('post_order_display_message');
$t->text('post_order_display_message')->nullable();
$t->text('social_share_text', 'Check Out [event_title] - [event_url]');
$t->text('social_share_text')->nullable();
$t->boolean('social_show_facebook')->default(true);
$t->boolean('social_show_linkedin')->default(true);
$t->boolean('social_show_twitter')->default(true);
@ -224,7 +225,7 @@ class CreateUsersTable extends Migration
$t->boolean('is_live')->default(false);
$t->timestamps();
$t->nullableTimestamps();
$t->softDeletes();
});
@ -235,30 +236,30 @@ class CreateUsersTable extends Migration
$t->increments('id');
$t->unsignedInteger('account_id')->index();
$t->unsignedInteger('order_status_id');
$t->timestamps();
$t->nullableTimestamps();
$t->softDeletes();
$t->string('first_name');
$t->string('last_name');
$t->string('email');
$t->string('ticket_pdf_path', 155);
$t->string('ticket_pdf_path', 155)->nullable();
$t->string('order_reference', 15);
$t->string('transaction_id', 50);
$t->string('transaction_id', 50)->nullable();
$t->decimal('discount', 8, 2);
$t->decimal('booking_fee', 8, 2);
$t->decimal('organiser_booking_fee', 8, 2);
$t->decimal('discount', 8, 2)->nullable();
$t->decimal('booking_fee', 8, 2)->nullable();
$t->decimal('organiser_booking_fee', 8, 2)->nullable();
$t->date('order_date')->nullable();
$t->text('notes');
$t->text('notes')->nullable();
$t->boolean('is_deleted')->default(0);
$t->boolean('is_cancelled')->default(0);
$t->boolean('is_partially_refunded')->default(0);
$t->boolean('is_refunded')->default(0);
$t->decimal('amount', 13, 2);
$t->decimal('amount_refunded', 13, 2);
$t->decimal('amount_refunded', 13, 2)->nullable();
$t->unsignedInteger('event_id')->index();
$t->foreign('event_id')->references('id')->on('events')->onDelete('cascade');
@ -273,7 +274,7 @@ class CreateUsersTable extends Migration
Schema::create('tickets', function ($t) {
$t->increments('id');
$t->timestamps();
$t->nullableTimestamps();
$t->softDeletes();
$t->unsignedInteger('edited_by_user_id')->nullable();
@ -296,8 +297,8 @@ class CreateUsersTable extends Migration
$t->dateTime('start_sale_date')->nullable();
$t->dateTime('end_sale_date')->nullable();
$t->decimal('sales_volume', 13, 2);
$t->decimal('organiser_fees_volume', 13, 2);
$t->decimal('sales_volume', 13, 2)->nullable();
$t->decimal('organiser_fees_volume', 13, 2)->nullable();
$t->tinyInteger('is_paused')->default(0);
@ -305,7 +306,7 @@ class CreateUsersTable extends Migration
$t->foreign('order_id')->references('id')->on('orders');
$t->foreign('edited_by_user_id')->references('id')->on('users');
$t->unsignedInteger('public_id')->index();
$t->unsignedInteger('public_id')->nullable()->index();
$t->unsignedInteger('user_id');
$t->foreign('user_id')->references('id')->on('users');
@ -316,7 +317,7 @@ class CreateUsersTable extends Migration
$table->string('title', 255);
$table->integer('quantity');
$table->decimal('unit_price', 13, 2);
$table->decimal('unit_booking_fee', 13, 2);
$table->decimal('unit_booking_fee', 13, 2)->nullable();
$table->unsignedInteger('order_id');
$table->foreign('order_id')->references('id')->on('orders')->onDelete('cascade');
$table->softDeletes();
@ -333,7 +334,7 @@ class CreateUsersTable extends Migration
//
//
// Schema::create('questions', function($t) {
// $t->timestamps();
// $t->nullableTimestamps();
// $t->softDeletes();
//
// $t->increments('id');
@ -428,8 +429,8 @@ class CreateUsersTable extends Migration
$table->integer('unique_views')->default(0);
$table->integer('tickets_sold')->default(0);
$table->decimal('sales_volume', 13, 2);
$table->decimal('organiser_fees_volume', 13, 2);
$table->decimal('sales_volume', 13, 2)->nullable();
$table->decimal('organiser_fees_volume', 13, 2)->nullable();
$table->unsignedInteger('event_id')->index();
@ -449,12 +450,12 @@ class CreateUsersTable extends Migration
$t->string('reference', 20);
$t->integer('private_reference_number')->index();
$t->timestamps();
$t->nullableTimestamps();
$t->softDeletes();
$t->boolean('is_cancelled')->default(false);
$t->boolean('has_arrived')->default(false);
$t->dateTime('arrival_time');
$t->dateTime('arrival_time')->nullable();
$t->unsignedInteger('account_id')->index();
$t->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
@ -468,13 +469,13 @@ class CreateUsersTable extends Migration
$table->increments('id');
$table->text('message');
$table->string('subject');
$table->integer('recipients'); //ticket_id or 0 for all
$table->integer('recipients')->nullable(); //ticket_id or null for all
$table->unsignedInteger('account_id')->index();
$table->unsignedInteger('user_id');
$table->unsignedInteger('event_id');
$table->unsignedInteger('is_sent', 0);
$table->dateTime('sent_at');
$table->timestamps();
$table->unsignedInteger('is_sent')->default(0);
$table->dateTime('sent_at')->nullable();
$table->nullableTimestamps();
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$table->foreign('event_id')->references('id')->on('events')->onDelete('cascade');
@ -485,7 +486,7 @@ class CreateUsersTable extends Migration
$t->increments('id');
$t->string('image_path');
$t->timestamps();
$t->nullableTimestamps();
$t->unsignedInteger('event_id');
$t->foreign('event_id')->references('id')->on('events')->onDelete('cascade');

View File

@ -15,7 +15,7 @@ class CreatePasswordResetsTable extends Migration
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token')->index();
$table->timestamp('created_at');
$table->timestamp('created_at')->useCurrent();
});
}

View File

@ -20,7 +20,7 @@ class AddAffiliatesTable extends Migration
$table->timestamp('last_visit');
$table->unsignedInteger('account_id')->index();
$table->unsignedInteger('event_id');
$table->timestamps();
$table->nullableTimestamps();
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$table->foreign('event_id')->references('id')->on('events')->onDelete('cascade');

View File

@ -17,7 +17,7 @@ class CreateFailedJobsTable extends Migration
$table->text('connection');
$table->text('queue');
$table->text('payload');
$table->timestamp('failed_at');
$table->timestamp('failed_at')->useCurrent();
});
}

View File

@ -16,11 +16,11 @@ class AddTicketDesignOptions extends Migration
/*
* @see https://github.com/milon/barcode
*/
$table->string('barcode_type', 10)->default('QRCODE');
$table->string('ticket_border_color', 10)->default('#000000');
$table->string('ticket_bg_color', 10)->default('#FFFFFF');
$table->string('ticket_text_color', 10)->default('#000000');
$table->string('ticket_sub_text_color', 10)->default('#999999');
$table->string('barcode_type', 20)->default('QRCODE');
$table->string('ticket_border_color', 20)->default('#000000');
$table->string('ticket_bg_color', 20)->default('#FFFFFF');
$table->string('ticket_text_color', 20)->default('#000000');
$table->string('ticket_sub_text_color', 20)->default('#999999');
});
}

View File

@ -27,7 +27,7 @@ class CreateGatewaysTable extends Migration
$table->unsignedInteger('payment_gateway_id');
$table->text('config');
$table->softDeletes();
$table->timestamps();
$table->nullableTimestamps();
$table->foreign('payment_gateway_id')->references('id')->on('payment_gateways')->onDelete('cascade');
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');

View File

@ -0,0 +1,40 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class OrganiserPageDesignUpdate extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('organisers', function (Blueprint $table) {
$table->boolean('show_twitter_widget')->default(false);
$table->boolean('show_facebook_widget')->default(false);
$table->string('page_header_bg_color', 20)->default('#76a867');
$table->string('page_bg_color', 20)->default('#EEEEEE');
$table->string('page_text_color', 20)->default('#FFFFFF');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('organisers', function (Blueprint $table) {
$table->dropColumn('show_twitter_widget');
$table->dropColumn('show_facebook_widget');
$table->dropColumn('page_header_bg_color');
$table->dropColumn('page_bg_color');
$table->dropColumn('page_text_color');
});
}
}

View File

@ -0,0 +1,113 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAttendeesQuestions extends Migration
{
/**
* Run the migrations.
*
* @access public
* @return void
*/
public function up()
{
/**
* Checkbox, dropdown, radio, text etc.
*/
Schema::create('question_types', function (Blueprint $table)
{
$table->increments('id');
$table->string('alias');
$table->string('name');
$table->boolean('has_options')->default(false);
$table->boolean('allow_multiple')->default(false);
});
/**
* The questions.
*/
Schema::create('questions', function (Blueprint $table)
{
$table->increments('id');
$table->string('title', 255);
$table->text('instructions');
$table->unsignedInteger('question_type_id');
$table->unsignedInteger('account_id')->index();
$table->tinyInteger('is_required')->default(0);
$table->timestamps();
$table->softDeletes();
$table->foreign('question_type_id')->references('id')->on('question_types');
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
});
/**
* Used for the questions that allow options (checkbox, radio, dropdown).
*/
Schema::create('question_options', function (Blueprint $table)
{
$table->increments('id');
$table->string('name');
$table->integer('question_id')->unsigned()->index();
$table->foreign('question_id')->references('id')->on('questions')->onDelete('cascade');
});
/**
* Event / Question pivot table.
*/
Schema::create('event_question', function(Blueprint $table)
{
$table->increments('id');
$table->integer('event_id')->unsigned()->index();
$table->integer('question_id')->unsigned()->index();
$table->foreign('event_id')->references('id')->on('events')->onDelete('cascade');
$table->foreign('question_id')->references('id')->on('questions')->onDelete('cascade');
});
/**
* Question / Ticket pivot table.
*/
Schema::create('question_ticket', function (Blueprint $table)
{
$table->increments('id');
$table->integer('question_id')->unsigned()->index();
$table->integer('ticket_id')->unsigned()->index();
$table->foreign('ticket_id')->references('id')->on('tickets')->onDelete('cascade');
$table->foreign('question_id')->references('id')->on('questions')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @access public
* @return void
*/
public function down()
{
$tables = [
'question_types',
'questions',
'question_options',
'event_question',
'question_ticket',
];
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
foreach ($tables as $table) {
Schema::drop($table);
}
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
}
}

View File

@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddOrganiserPageToggle extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('organisers', function (Blueprint $table) {
$table->boolean('enable_organiser_page')->default(1);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('organisers', function (Blueprint $table) {
$table->dropColumn('enable_organiser_page');
});
}
}

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class OrderPageUpdate extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('events', function (Blueprint $table) {
$table->string('questions_collection_type', 10)->default('buyer'); // buyer or attendee
$table->integer('checkout_timeout_after')->default(8); // timeout in mins for checkout
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('events', function (Blueprint $table) {
$table->dropColumn(['checkout_timeout_after', 'questions_collection_type']);
});
}
}

View File

@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddQuestionAnswersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('question_answers', function (Blueprint $table) {
$table->increments('id');
$table->integer('attendee_id')->unsigned()->index();
$table->integer('event_id')->unsigned()->index();
$table->integer('question_id')->unsigned()->index();
$table->integer('account_id')->unsigned()->index();
$table->text('answer_text');
$table->nullableTimestamps();
$table->foreign('question_id')->references('id')->on('questions');
$table->foreign('account_id')->references('id')->on('accounts')->onDelete('cascade');
$table->foreign('attendee_id')->references('id')->on('attendees')->onDelete('cascade');
$table->foreign('event_id')->references('id')->on('events')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
Schema::drop('question_answers');
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
}
}

View File

@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddApiKeyUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('api_token', 60)->unique()->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('api_token');
});
}
}

View File

@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class RemoveInstructionsFieldQuestionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('questions', function (Blueprint $table) {
$table->dropColumn('instructions');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('questions', function (Blueprint $table) {
$table->string('instructions');
});
}
}

View File

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use App\Models\Message;
class FixMessagesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('messages', function ($table) {
$table->string('recipients')->nullable()->change();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Message::where('recipients', null)->delete();
Schema::table('messages', function ($table) {
$table->string('recipients')->nullable(false)->change();
});
}
}

View File

@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class UpdateQuestionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('questions', function (Blueprint $table) {
$table->integer('sort_order')->default(1);
$table->tinyInteger('is_enabled')->default(1);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('questions', function (Blueprint $table) {
$table->dropColumn('sort_order');
$table->dropColumn('is_enabled');
});
}
}

View File

@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class RemoveAskForInEvents extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('events', function (Blueprint $table) {
$table->dropColumn('ask_for_all_attendees_info');
});
}
public function down()
{
}
}

Some files were not shown because too many files have changed in this diff Show More