Merge pull request #324 from nabeelio/265-editable-pilot-id
Backend changes separating id from pilot_id
This commit is contained in:
commit
0225a84a81
@ -90,7 +90,7 @@ if [ "$TRAVIS" = "true" ]; then
|
||||
# clear any app specific stuff that might have been loaded in
|
||||
find storage/app -mindepth 1 -not -name '.gitignore' -not -name public -not -name import -print0 -exec rm -rf {} +
|
||||
find storage/app/public -mindepth 1 -not -name '.gitignore' -not -name avatar -not -name uploads -print0 -exec rm -rf {} +
|
||||
find storage/app/public/avatar -mindepth 1 -not -name '.gitignore' -print0 -exec rm -rf {} +
|
||||
find storage/app/public/avatars -mindepth 1 -not -name '.gitignore' -print0 -exec rm -rf {} +
|
||||
find storage/app/public/uploads -mindepth 1 -not -name '.gitignore' -print0 -exec rm -rf {} +
|
||||
find storage/debugbar -mindepth 1 -not -name '.gitignore' -print0 -exec rm -rf {} +
|
||||
find storage/docker -mindepth 1 -not -name '.gitignore' -print0 -exec rm -rf {} +
|
||||
|
@ -8,6 +8,7 @@ $factory->define(App\Models\User::class, function (Faker $faker) {
|
||||
|
||||
return [
|
||||
'id' => null,
|
||||
'pilot_id' => 0,
|
||||
'name' => $faker->name,
|
||||
'email' => $faker->safeEmail,
|
||||
'password' => $password ?: $password = Hash::make('secret'),
|
||||
|
@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class UsersAddPilotId extends Migration
|
||||
{
|
||||
/**
|
||||
* Kinda of gross operations to change the pilot ID column
|
||||
* 1. Add an `pilot_id` column, which will get populated with the current ID
|
||||
* 2. Drop the `id` column, and then recreate it as a string field
|
||||
* 3. Iterate through all of the users and set their `id` to the `pilot_id`
|
||||
* 4. Change the other tables column types that reference `user_id`
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('pilot_id')
|
||||
->after('id')
|
||||
->unique()
|
||||
->nullable()
|
||||
->index('users_pilot_id');
|
||||
});
|
||||
|
||||
// Migrate the current pilot IDs
|
||||
DB::update('UPDATE `users` SET `pilot_id`=`id`');
|
||||
|
||||
// Drop the old ID column and add a new one
|
||||
/*Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropPrimary('users_id_primary');
|
||||
$table->dropColumn('id');
|
||||
$table->string('id', Model::ID_MAX_LENGTH)->primary();
|
||||
});
|
||||
|
||||
// Update the users to use the `pilot_id` (so we don't need to migrate data from other tables)
|
||||
$users = DB::table('users')->get(['id']);
|
||||
foreach ($users as $user) {
|
||||
$user->id = $user->pilot_id;
|
||||
$user->save();
|
||||
}*/
|
||||
|
||||
// role_user
|
||||
// permission_user
|
||||
// sessions
|
||||
// pireps
|
||||
// bids
|
||||
// news
|
||||
// user_awards
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('pilot_id');
|
||||
});
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ roles:
|
||||
|
||||
users:
|
||||
- id: 1
|
||||
pilot_id: 1
|
||||
name: Admin User
|
||||
email: admin@phpvms.net
|
||||
password: admin
|
||||
@ -34,6 +35,7 @@ users:
|
||||
created_at: now
|
||||
updated_at: now
|
||||
- id: 2
|
||||
pilot_id: 2
|
||||
name: Carla Walters
|
||||
email: carla.walters68@example.com
|
||||
password: admin
|
||||
@ -50,6 +52,7 @@ users:
|
||||
opt_in: 1
|
||||
toc_accepted: 1
|
||||
- id: 3
|
||||
pilot_id: 3
|
||||
name: Raymond Pearson
|
||||
email: raymond.pearson56@example.com
|
||||
password: admin
|
||||
|
9
app/Exceptions/UserPilotIdExists.php
Normal file
9
app/Exceptions/UserPilotIdExists.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
class UserPilotIdExists extends InternalError
|
||||
{
|
||||
public const FIELD = 'pilot_id';
|
||||
public const MESSAGE = 'A user with this pilot ID already exists';
|
||||
}
|
@ -292,7 +292,7 @@ class UserController extends Controller
|
||||
public function regen_apikey($id, Request $request)
|
||||
{
|
||||
$user = User::find($id);
|
||||
Log::info('Regenerating API key "'.$user->pilot_id.'"');
|
||||
Log::info('Regenerating API key "'.$user->ident.'"');
|
||||
|
||||
$user->api_key = Utils::generateApiKey();
|
||||
$user->save();
|
||||
|
@ -131,7 +131,7 @@ class AcarsController extends Controller
|
||||
$this->checkCancelled($pirep);
|
||||
|
||||
Log::debug(
|
||||
'Posting ACARS update (user: '.Auth::user()->pilot_id.', pirep id :'.$id.'): ',
|
||||
'Posting ACARS update (user: '.Auth::user()->ident.', pirep id :'.$id.'): ',
|
||||
$request->post()
|
||||
);
|
||||
|
||||
|
@ -49,7 +49,7 @@ class LoginController extends Controller
|
||||
|
||||
// TODO: How to handle ON_LEAVE?
|
||||
if ($user->state !== UserState::ACTIVE) {
|
||||
Log::info('Trying to login '.$user->pilot_id.', state '
|
||||
Log::info('Trying to login '.$user->ident.', state '
|
||||
.UserState::label($user->state));
|
||||
|
||||
// Log them out
|
||||
|
@ -133,7 +133,7 @@ class ProfileController extends Controller
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
Log::info('validator failed for user '.$user->pilot_id);
|
||||
Log::info('validator failed for user '.$user->ident);
|
||||
Log::info($validator->errors()->toArray());
|
||||
|
||||
return redirect(route('frontend.profile.edit', $id))
|
||||
@ -153,7 +153,7 @@ class ProfileController extends Controller
|
||||
}
|
||||
if ($request->hasFile('avatar')) {
|
||||
$avatar = $request->file('avatar');
|
||||
$file_name = $user->pilot_id.'.'.$avatar->getClientOriginalExtension();
|
||||
$file_name = $user->ident.'.'.$avatar->getClientOriginalExtension();
|
||||
$path = "avatars/{$file_name}";
|
||||
|
||||
// Create the avatar, resizing it and keeping the aspect ratio.
|
||||
@ -189,7 +189,7 @@ class ProfileController extends Controller
|
||||
public function regen_apikey(Request $request)
|
||||
{
|
||||
$user = User::find(Auth::user()->id);
|
||||
Log::info('Regenerating API key "'.$user->pilot_id.'"');
|
||||
Log::info('Regenerating API key "'.$user->ident.'"');
|
||||
|
||||
$user->api_key = Utils::generateApiKey();
|
||||
$user->save();
|
||||
|
@ -5,7 +5,7 @@ namespace App\Http\Requests;
|
||||
use App\Models\Pirep;
|
||||
use App\Repositories\PirepFieldRepository;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Log;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CreatePirepRequest extends FormRequest
|
||||
{
|
||||
|
@ -25,7 +25,10 @@ class CreateUserRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = User::$rules;
|
||||
|
||||
$rules['email'] .= '|unique:users,email';
|
||||
$rules['pilot_id'] .= '|unique:users,pilot_id';
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace App\Http\Requests;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use function request;
|
||||
|
||||
class UpdateUserRequest extends FormRequest
|
||||
{
|
||||
@ -24,6 +25,13 @@ class UpdateUserRequest extends FormRequest
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return User::$rules;
|
||||
$rules = User::$rules;
|
||||
|
||||
$user_id = request('id', null);
|
||||
|
||||
$rules['email'] .= '|unique:users,email,'.$user_id.',id';
|
||||
$rules['pilot_id'] .= '|unique:users,pilot_id,'.$user_id.',id';
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ class PirepComment extends Resource
|
||||
'user' => [
|
||||
'id' => $user->id,
|
||||
'pilot_id' => $user->pilot_id,
|
||||
'ident' => $user->ident,
|
||||
'name' => $user->name,
|
||||
],
|
||||
];
|
||||
|
@ -11,6 +11,7 @@ class User extends Resource
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'pilot_id' => $this->pilot_id,
|
||||
'ident' => $this->ident,
|
||||
'name' => $this->name,
|
||||
'email' => $this->email,
|
||||
'apikey' => $this->apikey,
|
||||
|
@ -68,7 +68,7 @@ class NotificationEvents extends Listener
|
||||
public function onUserRegister(UserRegistered $event): void
|
||||
{
|
||||
Log::info('onUserRegister: '
|
||||
.$event->user->pilot_id.' is '
|
||||
.$event->user->ident.' is '
|
||||
.UserState::label($event->user->state)
|
||||
.', sending active email');
|
||||
|
||||
|
26
app/Models/Observers/UserObserver.php
Normal file
26
app/Models/Observers/UserObserver.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Observers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Services\UserService;
|
||||
|
||||
class UserObserver
|
||||
{
|
||||
private $userSvc;
|
||||
|
||||
public function __construct(UserService $userSvc)
|
||||
{
|
||||
$this->userSvc = $userSvc;
|
||||
}
|
||||
|
||||
/**
|
||||
* After a user has been created, do some stuff
|
||||
*
|
||||
* @param User $user
|
||||
*/
|
||||
public function created(User $user): void
|
||||
{
|
||||
$this->userSvc->findAndSetPilotId($user);
|
||||
}
|
||||
}
|
@ -10,14 +10,17 @@ use Illuminate\Notifications\Notifiable;
|
||||
use Laratrust\Traits\LaratrustUserTrait;
|
||||
|
||||
/**
|
||||
* @property int id
|
||||
* @property int id
|
||||
* @property int pilot_id
|
||||
* @property string name
|
||||
* @property string email
|
||||
* @property string password
|
||||
* @property string api_key
|
||||
* @property mixed ident
|
||||
* @property mixed timezone
|
||||
* @property string ident
|
||||
* @property string curr_airport_id
|
||||
* @property string home_airport_id
|
||||
* @property Airline airline
|
||||
* @property Flight[] flights
|
||||
* @property string flight_time
|
||||
* @property string remember_token
|
||||
@ -45,9 +48,11 @@ class User extends Authenticatable
|
||||
public $journal_type = JournalType::USER;
|
||||
|
||||
protected $fillable = [
|
||||
'id',
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
'pilot_id',
|
||||
'airline_id',
|
||||
'rank_id',
|
||||
'api_key',
|
||||
@ -78,6 +83,8 @@ class User extends Authenticatable
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'id' => 'integer',
|
||||
'pilot_id' => 'integer',
|
||||
'flights' => 'integer',
|
||||
'flight_time' => 'integer',
|
||||
'transfer_time' => 'integer',
|
||||
@ -89,26 +96,19 @@ class User extends Authenticatable
|
||||
];
|
||||
|
||||
public static $rules = [
|
||||
'name' => 'required',
|
||||
'email' => 'required|email',
|
||||
'name' => 'required',
|
||||
'email' => 'required|email',
|
||||
'pilot_id' => 'required|integer',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getPilotIdAttribute()
|
||||
{
|
||||
$length = setting('pilots.id_length');
|
||||
|
||||
return $this->airline->icao.str_pad($this->id, $length, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIdentAttribute()
|
||||
{
|
||||
return $this->getPilotIdAttribute();
|
||||
$length = setting('pilots.id_length');
|
||||
|
||||
return $this->airline->icao.str_pad($this->pilot_id, $length, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,10 +15,12 @@ use App\Models\Observers\JournalTransactionObserver;
|
||||
use App\Models\Observers\SettingObserver;
|
||||
use App\Models\Observers\Sluggable;
|
||||
use App\Models\Observers\SubfleetObserver;
|
||||
use App\Models\Observers\UserObserver;
|
||||
use App\Models\PirepField;
|
||||
use App\Models\PirepFieldValue;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Subfleet;
|
||||
use App\Models\User;
|
||||
use App\Repositories\SettingRepository;
|
||||
use App\Services\ModuleService;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
@ -53,6 +55,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
|
||||
Setting::observe(SettingObserver::class);
|
||||
Subfleet::observe(SubfleetObserver::class);
|
||||
User::observe(UserObserver::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -425,7 +425,7 @@ class PirepService extends Service
|
||||
]);
|
||||
|
||||
if ($bid) {
|
||||
Log::info('Bid for user: '.$pirep->user->pilot_id.' on flight '.$flight->ident);
|
||||
Log::info('Bid for user: '.$pirep->user->ident.' on flight '.$flight->ident);
|
||||
$bid->delete();
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use App\Contracts\Service;
|
||||
use App\Events\UserRegistered;
|
||||
use App\Events\UserStateChanged;
|
||||
use App\Events\UserStatsChanged;
|
||||
use App\Exceptions\UserPilotIdExists;
|
||||
use App\Models\Enums\PirepState;
|
||||
use App\Models\Enums\UserState;
|
||||
use App\Models\Pirep;
|
||||
@ -16,6 +17,7 @@ use App\Repositories\AircraftRepository;
|
||||
use App\Repositories\SubfleetRepository;
|
||||
use App\Support\Units\Time;
|
||||
use Illuminate\Support\Collection;
|
||||
use function is_array;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
@ -67,7 +69,7 @@ class UserService extends Service
|
||||
// $user->attachRole($role);
|
||||
|
||||
// Attach any additional roles
|
||||
if (!empty($groups) && \is_array($groups)) {
|
||||
if (!empty($groups) && is_array($groups)) {
|
||||
foreach ($groups as $group) {
|
||||
$role = Role::where('name', $group)->first();
|
||||
$user->attachRole($role);
|
||||
@ -83,6 +85,65 @@ class UserService extends Service
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the next available pilot ID and set the current user's pilot_id to that +1
|
||||
* Called from UserObserver right now after a record is created
|
||||
*
|
||||
* @param User $user
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function findAndSetPilotId(User $user): User
|
||||
{
|
||||
if ($user->pilot_id !== null && $user->pilot_id > 0) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
$max = (int) User::max('pilot_id');
|
||||
$user->pilot_id = $max + 1;
|
||||
$user->save();
|
||||
|
||||
Log::info('Set pilot ID for user '.$user->id.' to '.$user->pilot_id);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
public function isPilotIdAlreadyUsed(int $pilot_id): bool
|
||||
{
|
||||
return User::where('pilot_id', '=', $pilot_id)->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change a user's pilot ID
|
||||
*
|
||||
* @param User $user
|
||||
* @param int $pilot_id
|
||||
*
|
||||
* @throws UserPilotIdExists
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public function changePilotId(User $user, int $pilot_id): User
|
||||
{
|
||||
if ($user->pilot_id === $pilot_id) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
if ($this->isPilotIdAlreadyUsed($pilot_id)) {
|
||||
Log::error('User with id '.$pilot_id.' already exists');
|
||||
|
||||
throw new UserPilotIdExists();
|
||||
}
|
||||
|
||||
$old_id = $user->pilot_id;
|
||||
$user->pilot_id = $pilot_id;
|
||||
$user->save();
|
||||
|
||||
Log::info('Changed pilot ID for user '.$user->id.' from '.$old_id.' to '.$user->pilot_id);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the subfleets this user is allowed access to,
|
||||
* based on their current rank
|
||||
@ -133,7 +194,7 @@ class UserService extends Service
|
||||
return $user;
|
||||
}
|
||||
|
||||
Log::info('User '.$user->pilot_id.' state changing from '
|
||||
Log::info('User '.$user->ident.' state changing from '
|
||||
.UserState::label($old_state).' to '
|
||||
.UserState::label($user->state));
|
||||
|
||||
|
@ -8,6 +8,7 @@ use App\Support\Units\Pressure;
|
||||
use App\Support\Units\Temperature;
|
||||
use App\Support\Units\Velocity;
|
||||
use function count;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use PhpUnitsOfMeasure\Exception\NonNumericValue;
|
||||
use PhpUnitsOfMeasure\Exception\NonStringUnitName;
|
||||
|
||||
@ -341,6 +342,7 @@ class Metar implements \ArrayAccess
|
||||
public function __construct($raw, $taf = false, $debug = false, $icao = true)
|
||||
{
|
||||
$this->debug_enabled = $debug;
|
||||
// Log::info('Parsing metar="'.$raw.'"');
|
||||
|
||||
$raw_lines = explode("\n", $raw, 2);
|
||||
if (isset($raw_lines[1])) {
|
||||
@ -408,7 +410,7 @@ class Metar implements \ArrayAccess
|
||||
*/
|
||||
protected function createAltitude($value, $unit)
|
||||
{
|
||||
return new Altitude($value, $unit);
|
||||
return new Altitude((float) $value, $unit);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -424,7 +426,7 @@ class Metar implements \ArrayAccess
|
||||
*/
|
||||
protected function createDistance($value, $unit)
|
||||
{
|
||||
return new Distance($value, $unit);
|
||||
return new Distance((float) $value, $unit);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -440,7 +442,7 @@ class Metar implements \ArrayAccess
|
||||
*/
|
||||
protected function createPressure($value, $unit)
|
||||
{
|
||||
return new Pressure($value, $unit);
|
||||
return new Pressure((float) $value, $unit);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -456,7 +458,7 @@ class Metar implements \ArrayAccess
|
||||
*/
|
||||
protected function createTemperature($value, $unit)
|
||||
{
|
||||
return new Temperature($value, $unit);
|
||||
return new Temperature((float) $value, $unit);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -472,7 +474,7 @@ class Metar implements \ArrayAccess
|
||||
*/
|
||||
protected function createVelocity($value, $unit)
|
||||
{
|
||||
return new Velocity($value, $unit);
|
||||
return new Velocity((float) $value, $unit);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1118,6 +1120,7 @@ class Metar implements \ArrayAccess
|
||||
$report = implode(' ', $report);
|
||||
$report_ft = implode(' ', $report_ft);
|
||||
|
||||
$observed['report'] = $this->createAltitude($report_ft, 'ft');
|
||||
$observed['report'] = ucfirst($report);
|
||||
$observed['report_ft'] = ucfirst($report_ft);
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
"anhskohbo/no-captcha": "3.0.*",
|
||||
"appstract/laravel-opcache": "^2.0",
|
||||
"arrilot/laravel-widgets": "3.13.*",
|
||||
"doctrine/dbal": "2.9.*",
|
||||
"fzaninotto/faker": "^1.8",
|
||||
"guzzlehttp/guzzle": "6.3.*",
|
||||
"hashids/hashids": "2.0.*",
|
||||
|
233
composer.lock
generated
233
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "b4e5994cf5891923a2ed410bacad5fc4",
|
||||
"content-hash": "99c96d01e78e1d4400295a887ac36667",
|
||||
"packages": [
|
||||
{
|
||||
"name": "akaunting/money",
|
||||
@ -857,6 +857,237 @@
|
||||
],
|
||||
"time": "2019-05-27T17:52:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
"version": "v1.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/cache.git",
|
||||
"reference": "d768d58baee9a4862ca783840eca1b9add7a7f57"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57",
|
||||
"reference": "d768d58baee9a4862ca783840eca1b9add7a7f57",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~7.1"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/common": ">2.2,<2.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"alcaeus/mongo-php-adapter": "^1.1",
|
||||
"doctrine/coding-standard": "^4.0",
|
||||
"mongodb/mongodb": "^1.1",
|
||||
"phpunit/phpunit": "^7.0",
|
||||
"predis/predis": "~1.0"
|
||||
},
|
||||
"suggest": {
|
||||
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Caching library offering an object-oriented API for many cache backends",
|
||||
"homepage": "https://www.doctrine-project.org",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching"
|
||||
],
|
||||
"time": "2018-08-21T18:01:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/dbal",
|
||||
"version": "v2.9.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/dbal.git",
|
||||
"reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/dbal/zipball/22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9",
|
||||
"reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/cache": "^1.0",
|
||||
"doctrine/event-manager": "^1.0",
|
||||
"ext-pdo": "*",
|
||||
"php": "^7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^5.0",
|
||||
"jetbrains/phpstorm-stubs": "^2018.1.2",
|
||||
"phpstan/phpstan": "^0.10.1",
|
||||
"phpunit/phpunit": "^7.4",
|
||||
"symfony/console": "^2.0.5|^3.0|^4.0",
|
||||
"symfony/phpunit-bridge": "^3.4.5|^4.0.5"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/console": "For helpful console commands such as SQL execution and import of files."
|
||||
},
|
||||
"bin": [
|
||||
"bin/doctrine-dbal"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.9.x-dev",
|
||||
"dev-develop": "3.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\DBAL\\": "lib/Doctrine/DBAL"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/dbal.html",
|
||||
"keywords": [
|
||||
"abstraction",
|
||||
"database",
|
||||
"dbal",
|
||||
"mysql",
|
||||
"persistence",
|
||||
"pgsql",
|
||||
"php",
|
||||
"queryobject"
|
||||
],
|
||||
"time": "2018-12-31T03:27:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/event-manager",
|
||||
"version": "v1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/event-manager.git",
|
||||
"reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3",
|
||||
"reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1"
|
||||
},
|
||||
"conflict": {
|
||||
"doctrine/common": "<2.9@dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^4.0",
|
||||
"phpunit/phpunit": "^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\": "lib/Doctrine/Common"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Marco Pivetta",
|
||||
"email": "ocramius@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Doctrine Event Manager component",
|
||||
"homepage": "https://www.doctrine-project.org/projects/event-manager.html",
|
||||
"keywords": [
|
||||
"event",
|
||||
"eventdispatcher",
|
||||
"eventmanager"
|
||||
],
|
||||
"time": "2018-06-11T11:59:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
"version": "v1.3.0",
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
return [
|
||||
'dashboard' => 'Dashboard',
|
||||
'administration' => 'Administration',
|
||||
'administration' => 'Admin',
|
||||
'flight' => 'Flight|Flights',
|
||||
'livemap' => 'Live Map',
|
||||
'pilot' => 'Pilot|Pilots',
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
return [
|
||||
'dashboard' => 'Tablero',
|
||||
'administration' => 'Administración',
|
||||
'administration' => 'Admin',
|
||||
'flight' => 'Vuelo|Vuelos',
|
||||
'livemap' => 'Mapa en vivo',
|
||||
'pilot' => 'Piloto|Pilotos',
|
||||
|
@ -32,6 +32,10 @@
|
||||
@ability('admin', 'finances')
|
||||
<li><a href="{{ url('/admin/finances') }}"><i class="pe-7s-display1"></i>finances</a></li>
|
||||
@endability
|
||||
|
||||
@ability('admin', 'users')
|
||||
<li><a href="{{ url('/admin/users') }}"><i class="pe-7s-users"></i>users</a></li>
|
||||
@endability
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
@ -55,10 +59,6 @@
|
||||
<li><a href="{{ url('/admin/expenses') }}"><i class="pe-7s-cash"></i>expenses</a></li>
|
||||
@endability
|
||||
|
||||
@ability('admin', 'users')
|
||||
<li><a href="{{ url('/admin/users') }}"><i class="pe-7s-users"></i>users</a></li>
|
||||
@endability
|
||||
|
||||
@ability('admin', 'ranks')
|
||||
<li><a href="{{ url('/admin/ranks') }}"><i class="pe-7s-graph1"></i>ranks</a></li>
|
||||
@endability
|
||||
|
@ -11,7 +11,7 @@
|
||||
<div class="col-md-8">
|
||||
<h5 style="margin-top: 0px;">
|
||||
Filed By: <a href="{{ route('admin.users.edit', [$pirep->user_id]) }}" target="_blank">
|
||||
{{ $pirep->user->pilot_id }} {{ $pirep->user->name }}
|
||||
{{ $pirep->user->ident }} {{ $pirep->user->name }}
|
||||
</a>
|
||||
</h5>
|
||||
</div>
|
||||
|
@ -1,17 +1,24 @@
|
||||
<div class="row">
|
||||
<div class="form-group col-sm-4">
|
||||
{{ Form::hidden('id') }}
|
||||
<div class="form-group col-sm-3">
|
||||
{{ Form::label('pilot_id', 'Pilot ID:') }}
|
||||
{{ Form::number('pilot_id', null, ['class' => 'form-control']) }}
|
||||
<p class="text-danger">{{ $errors->first('pilot_id') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-sm-3">
|
||||
{{ Form::label('name', 'Name:') }}
|
||||
{{ Form::text('name', null, ['class' => 'form-control']) }}
|
||||
<p class="text-danger">{{ $errors->first('name') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-sm-4">
|
||||
<div class="form-group col-sm-3">
|
||||
{{ Form::label('email', 'Email:') }}
|
||||
{{ Form::text('email', null, ['class' => 'form-control']) }}
|
||||
<p class="text-danger">{{ $errors->first('email') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-sm-4">
|
||||
<div class="form-group col-sm-3">
|
||||
{{ Form::label('password', 'Password:') }}
|
||||
{{ Form::password('password', ['class' => 'form-control']) }}
|
||||
<p class="text-danger">{{ $errors->first('password') }}</p>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<table class="table table-hover table-responsive" id="users-table">
|
||||
<thead>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Email</th>
|
||||
<th>Registered</th>
|
||||
@ -9,6 +10,7 @@
|
||||
<tbody>
|
||||
@foreach($users as $user)
|
||||
<tr>
|
||||
<td>{{ $user->ident }}</td>
|
||||
<td>
|
||||
@if(filled($user->country))
|
||||
<span class="flag-icon flag-icon-{{ $user->country }}"
|
||||
|
@ -13,7 +13,7 @@
|
||||
</div>
|
||||
<h3 class="title">{{ $user->name }}</h3>
|
||||
<h6><span class="flag-icon flag-icon-{{ $user->country }}"></span></h6>
|
||||
<h6>{{ $user->pilot_id }}</h6>
|
||||
<h6>{{ $user->ident }}</h6>
|
||||
<h6>{{ $user->rank->name }}</h6>
|
||||
<p class="description" style="color: #9A9A9A;">
|
||||
{{ $user->airline->name }}
|
||||
|
@ -2,7 +2,7 @@
|
||||
@foreach($users as $u)
|
||||
<tr>
|
||||
<td style="padding-right: 10px;">
|
||||
<span class="title">{{ $u->pilot_id }}</span>
|
||||
<span class="title">{{ $u->ident }}</span>
|
||||
</td>
|
||||
<td>{{ $u->name }}</td>
|
||||
</tr>
|
||||
|
@ -30,8 +30,8 @@ https://api.checkwx.com/#metar-decoded
|
||||
<tr>
|
||||
<td>@lang('widgets.weather.barometer')</td>
|
||||
<td>
|
||||
{{ number_format($metar['barometer'], 2) }} hPa
|
||||
/ {{ number_format($metar['barometer_in'], 2) }} inHg
|
||||
{{ number_format($metar['barometer']['hPa'], 2) }} hPa
|
||||
/ {{ number_format($metar['barometer']['inHg'], 2) }} inHg
|
||||
</td>
|
||||
</tr>
|
||||
@if($metar['clouds'])
|
||||
|
2
storage/app/public/.gitignore
vendored
2
storage/app/public/.gitignore
vendored
@ -1,4 +1,4 @@
|
||||
*
|
||||
!avatar
|
||||
!avatars
|
||||
!uploads
|
||||
!.gitignore
|
||||
|
@ -126,8 +126,6 @@ class MetarTest extends TestCase
|
||||
'Scattered at 4500 feet, cumulonimbus; broken sky at 6000 feet; overcast sky at 8000 feet',
|
||||
$parsed['clouds_report_ft']
|
||||
);
|
||||
|
||||
$this->assertNotNull($parsed);
|
||||
}
|
||||
|
||||
public function testMetarTrends3()
|
||||
@ -136,6 +134,15 @@ class MetarTest extends TestCase
|
||||
$metar = Metar::parse($metar);
|
||||
|
||||
$this->assertEquals('VFR', $metar['category']);
|
||||
$this->assertNotNull($metar);
|
||||
}
|
||||
|
||||
public function testMetar4Clouds()
|
||||
{
|
||||
$metar = 'KAUS 171153Z 18006KT 9SM FEW015 FEW250 26/24 A3003 RMK AO2 SLP156 T02560244 10267 20239 $';
|
||||
$metar = Metar::parse($metar);
|
||||
|
||||
$this->assertEquals(2, count($metar['clouds']));
|
||||
$this->assertEquals('A few at 457 meters; a few at 7620 meters', $metar['clouds_report']);
|
||||
$this->assertEquals('A few at 1500 feet; a few at 25000 feet', $metar['clouds_report_ft']);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Models\User;
|
||||
use App\Repositories\SettingRepository;
|
||||
use App\Services\UserService;
|
||||
|
||||
@ -149,14 +150,6 @@ class UserTest extends TestCase
|
||||
$subfleetB['subfleet']->id,
|
||||
]);
|
||||
|
||||
/*
|
||||
* Now we can do some actual tests
|
||||
*/
|
||||
|
||||
/*
|
||||
* Do some sanity checks first
|
||||
*/
|
||||
|
||||
// Make sure no flights are filtered out
|
||||
$this->settingsRepo->store('pilots.only_flights_from_current', false);
|
||||
|
||||
@ -195,4 +188,41 @@ class UserTest extends TestCase
|
||||
$body = $response->json()['data'];
|
||||
$this->assertCount(1, $body[0]['subfleets']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the pilot ID being added when a new user is created
|
||||
*
|
||||
* @expectedException \App\Exceptions\UserPilotIdExists
|
||||
*/
|
||||
public function testUserPilotIdChangeAlreadyExists()
|
||||
{
|
||||
$user1 = factory(App\Models\User::class)->create(['id' => 1]);
|
||||
$user2 = factory(App\Models\User::class)->create(['id' => 2]);
|
||||
|
||||
// Now try to change the original user's pilot_id to 2 (should conflict)
|
||||
$this->userSvc->changePilotId($user1, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the pilot ID being added when a new user is created
|
||||
*/
|
||||
public function testUserPilotIdAdded()
|
||||
{
|
||||
$new_user = factory(App\Models\User::class)->create(['id' => 1]);
|
||||
$user = $this->userSvc->createUser($new_user);
|
||||
$this->assertEquals($user->id, $user->pilot_id);
|
||||
|
||||
// Add a second user
|
||||
$new_user = factory(App\Models\User::class)->create(['id' => 2]);
|
||||
$user2 = $this->userSvc->createUser($new_user);
|
||||
$this->assertEquals($user2->id, $user2->pilot_id);
|
||||
|
||||
// Now try to change the original user's pilot_id to 3
|
||||
$user = $this->userSvc->changePilotId($user, 3);
|
||||
$this->assertEquals(3, $user->pilot_id);
|
||||
|
||||
// Create a new user and the pilot_id should be 4
|
||||
$user3 = factory(App\Models\User::class)->create(['id' => 3]);
|
||||
$this->assertEquals(4, $user3->pilot_id);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user