diff --git a/app/Http/Controllers/Auth/EsiScopeController.php b/app/Http/Controllers/Auth/EsiScopeController.php new file mode 100644 index 0000000..13cb943 --- /dev/null +++ b/app/Http/Controllers/Auth/EsiScopeController.php @@ -0,0 +1,42 @@ +middleware('auth'); + $this->middleware('role:User'); + } + + /** + * Display the ESI scopes to choose from + * + * @return view + */ + public function displayScopes() { + $scopes = EsiScope::where([ + 'character_id' => Auth::user()->character_id, + ])->get(); + + return view('scopes.select')->with('scopes', $scopes); + } + + /** + * Redirect to the provider + * + * @return Socialite + */ + public function redirectToProvider(Request $request) { + return Socialite::driver('eveonline')->setScopes($request->scopes)->redirect(); + } + +} diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php new file mode 100644 index 0000000..991803a --- /dev/null +++ b/app/Http/Controllers/Auth/LoginController.php @@ -0,0 +1,132 @@ +middleware('guest')->except(['logout', + 'handleProviderCallback', + 'redirectToProvider']); + } + + /** + * Logout function + * + * @return void + */ + public function logout() { + Auth::logout(); + return redirect('/'); + } + + /** + * Redirect to the provider's website + * + * @return Socialite + * @return character_owner_hash + * @return character_name + * @return character_id + * @return token + * @return refreshToken + * @return expiresIn + * @return user (Holds jwt) + */ + public function redirectToProvider() { + //The default scope is public data for everyone due to OAuth2 Tokens + //Add esi-mail.send_mail.v1 to send mails more efficiently + $scopes = ['publicData', 'esi-mail.send_mail.v1']; + + //Collect any other scopes from the database. + //If we are logged in we are linking another character to this one. + //Attempt to use the same scopes for this character as the original. + if(Auth::check()) { + $extrascopes = EsiScope::where([ + 'character_id' => auth()->user()->getId(); + ])->get(['scope']); + + //Pop each scope onto the array of scopes + foreach($extraScopes as $extra) { + array_push($scopes, $extra->scope); + } + + /** + * Place the scopes in the session. + * Place the original character id in the session. + */ + session()->put('scopes', $scopes); + session()->put('orgCharacter', auth()->user()->getId()); + } + + return Socialite::driver('eveonline')->scopes($scopes)->redirect(); + } + + /** + * Get token from callback + * Redirect to the dashboard if logging in successfully. + * + * @return redirect() + */ + public function handleProviderCallback(Socialite $social) { + //Get the sso user from the socialite driver + $ssoUser = $social->driver('eveonline')->user(); + + $scpSession = session()->pull('scopes'); + + //If the user was already logged in, let's do some checks to see if we are adding + //additional scopes to the user's account + if(Auth::check()) { + //If we are logged in already and the session contains the original characters, then we are creating an alt + //for the original character + if(session()->has('orgCharacter')) { + $orgCharacter = session()->pull('orgCharacter'); + + if(LoginHelper::createAlt($ssoUser, $orgCharacter)) { + return redirect()->to('/profile')->with('success', 'Alt registered.'); + } else { + return redirect()->to('/profile')->with('error', 'Unable to register alt or it was previously registered.'); + } + } else { + if(sizeof($ssoUser->scopes) > 1) { + $tokenCount = EsiToken::where([ + 'character_id' => $ssoUser->id, + ])->count(); + if($tokenCount > 0) { + LoginHelper::UpdateEsiToken($ssoUser); + } else { + LoginHelper::SaveEsiToken($ssoUser); + } + LoginHelper::SetScopes($ssoUser->scopes, $ssoUser->id); + return redirect()->to('/dashboard')->with('success', 'Successfully updated ESI scopes.'); + } + } + } else { + //If the user wasn't logged in, then create a new user + $user = LoginHelper::createOrGetUser($ssoUser); + //Login in the new user + auth()->login($user, true); + //Redirect back to the dashboard + return redirect()->to('/dashboard')->with('success', 'Successfully Logged In.'); + } + } + + +} diff --git a/app/Http/Controllers/Contracts/SupplyChainController.php b/app/Http/Controllers/Contracts/SupplyChainController.php new file mode 100644 index 0000000..ff839c0 --- /dev/null +++ b/app/Http/Controllers/Contracts/SupplyChainController.php @@ -0,0 +1,11 @@ + auth()->user()->character_id, + ])->get(['role']); + + if($role[0]-> != "Admin") { + $perms = UserPermission::where(['character_id' => auth()->user()->character_id, 'permission' => $permission])->get(['permission']); + + abort_unless(auth()->check() && isset($perms[0]->permission), 403, "You don't have the correct permission to be in this area."); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/RequireRole.php b/app/Http/Middleware/RequireRole.php new file mode 100644 index 0000000..e947b1a --- /dev/null +++ b/app/Http/Middleware/RequireRole.php @@ -0,0 +1,39 @@ +role] = $r->rank; + } + + $check = UserRole::where('character_id', auth()->user()->character_id)->get(['role']); + + if(!isset($check[0]->role)) { + abort(403, "You don't have any roles."); + } + + if($ranking[$check[0]->role] < $ranking[$role]) { + abort(403, "You don't have the correct role to be in the area."); + } + + return $next($request); + } +} diff --git a/app/Library/Esi/Esi.php b/app/Library/Esi/Esi.php new file mode 100644 index 0000000..b332150 --- /dev/null +++ b/app/Library/Esi/Esi.php @@ -0,0 +1,191 @@ + $charId, 'scope' => $scope])->count(); + if($check == 0) { + //Compose a mail to send to the user if the scope is not found + $subject = 'W4RP Services - Incorrect ESI Scope'; + $body = "Please register on https://services.w4rp.space with the scope: " . $scope; + + SendEveMail::dispatch($body, (int)$charId, 'character', $subject, $config['primary'])->delay(Carbon::now()->addSeconds(5)); + return false; + } + + return true; + } + + public function DecodeDate($date) { + //Find the end of the date + $dateEnd = strpos($date, "T"); + //Split the string up into date and time + $dateArr = str_split($date, $dateEnd); + //Trim the T and Z from the end of the second item in the array + $dateArr[1] = ltrim($dateArr[1], "T"); + $dateArr[1] = rtrim($dateArr[1], "Z"); + //Combine the date + $realDate = $dateArr[0] . " " . $dateArr[1]; + + //Return the combined date in the correct format + return $realDate; + } + + public function TokenExpired($token) { + $currentTime = Carbon::now(); + + //Create the carbon time for expiration time + $expires = $token->inserted_at + $token->expires_in; + $tokenExpiration = Carbon::createFromTimeStamp($expires); + + if($currentTime->greaterThan($tokenExpiration->subSeconds(5))) { + return true; + } else { + return false; + } + } + + public function GetRefreshToken($charId) { + //Declare variables + $currentTime = Carbon::now(); + $scopes = null; + $i = 0; + $config = config('esi'); + + //If the program doesn't find an ESI Token, there is nothing to return + if(EsiToken::where(['character_id' => $charId])->count() == 0) { + return null; + } + + //Get the ESI Token from the database + $token = EsiToken::where([ + 'character_id' => $charId, + ])->first(); + + //Check the expiration of the token to see if the token has expired and needs to be refreshed using the refresh token + $expires = $token->inserted_at + $token->expires_in; + $tokenExpiration = Carbon::createFromTimestamp($expires); + //If the access token has expired, we need to do a request for a new access token + //We give ourselves around 5 seconds leeway in order to deal with an expired token + if($currentTime->greaterThan($tokenExpiration->subSeconds(5))) { + //Get the current scopes of the token + $scopesArr = EsiScope::where([ + 'character_id' => $token->character_id, + ])->get(['scope'])->toArray(); + + //Cycle through the scopes, and create the string for scopes to send with the token + foreach($scopesArr as $scp) { + $scopes .= $scp['scope']; + $i++; + if($i < sizeof($scopesArr)) { + $scopes .= '%20'; + } + } + + //Setup the guzzle client for the request to get a new token + $client = new Client(['base_uri' => 'https://login.eveonline.com']); + $response = $client->request('POST', '/v2/oauth/token', [ + 'headers' => [ + 'Content-Type' => 'application/x-www-form-urlencoded', + 'Host' => 'login.eveonline.com', + 'Authorization' => "Basic " . base64_encode($config['client_id'] . ":" . $config['secret']), + ], + 'form_params' => [ + 'grant_type' => 'refresh_token', + 'refresh_token' => $token->refresh_token, + ], + ]); + //Decode the body of the response which has the token information + $body = json_decode($response->getBody(), true); + //Update the old token, then send the new token back to the calling function + EsiToken::where([ + 'character_id' => $charId, + ])->update([ + 'access_token' => $body['access_token'], + 'refresh_token' => $body['refresh_token'], + 'expires_in' => $body['expires_in'], + 'inserted_at' => time(), + ]); + + $newToken = new EsiToken; + $newToken->character_id = $charId; + $newToken->access_token = $body['access_token']; + $newToken->refresh_token = $body['refresh_token']; + $newToken->inserted_at = time(); + $newToken->expires_in = $body['expires_in']; + + //Return the new token model + return $newToken; + } + + //If we had a good token which has not expired yet, return the data + return $token; + } + + public function SetupEsiAuthentication($token = null) { + //Declare some variables + $authentication = null; + $esi = null; + $config = config('esi'); + + if($token == null) { + $esi = new Eseye(); + } else { + $tokenExpires = $token->inserted_at + $token->expires_in; + + //Setup the esi authentication container + $authentication = new EsiAuthentication([ + 'client_id' => $config['client_id'], + 'secret' => $config['secret'], + 'refresh_token' => $token->refresh_token, + 'access_token' => $token->access_token, + 'token_expires' => $tokenExpires, + ]); + + //Setup the esi variable + $esi = new Eseye($authentication); + } + + //Return the created variable + return $esi; + } +} + +?> \ No newline at end of file diff --git a/app/Library/Helpers/AssetHelper.php b/app/Library/Helpers/AssetHelper.php new file mode 100644 index 0000000..443e2d3 --- /dev/null +++ b/app/Library/Helpers/AssetHelper.php @@ -0,0 +1,113 @@ +charId = $char; + $this->corpId = $corp; + } + + /** + * Get Assets By Page in order to store in the database + */ + public function GetAssetsByPage($page) { + //Declare the variable for the esi helper + $esiHelper = new Esi; + + //Setup the esi authentication container + $config = config('esi'); + + //Check for the scope needed + $hasScope = $esiHelper->HaveEsiScope($this->charId, 'esi-assets.read_corporation_assets.v1'); + if($hasScope == false) { + Log::critical('ESI Scope check has failed for esi-assets.read_corporation_assets.v1 for character id: ' . $this->charId); + return null; + } + + //Get the refresh token from the database + $token = $esiHelper->GetRefreshToken($this->charId); + //Setup the esi authentication container + $esi = $esiHelper->SetupEsiAuthentication($token); + + try { + $assets = $esi->page($this->page) + ->invoke('get', '/corporations/{corporation_id}/assets/', [ + 'corporation_id' => $this->corpId, + ]); + } catch(RequestFailedException $e) { + Log::critical("Failed to get page of assets from ESI."); + $assets = null; + } + + return $assets; + } + + /** + * Store a new asset record in the database + */ + public function StoreNewAsset($asset) { + Asset::updateOrCreate([ + 'item_id' => $asset->item_id, + ], [ + 'is_blueprint_copy' => $asset->is_blueprint_copy, + 'is_singleton' => $asset->is_singleton, + 'item_id' => $asset->item_id, + 'location_flag' => $asset->location_flag, + 'location_id' => $asset->location_id, + 'location_type' => $asset->location_type, + 'quantity' => $asset->quantity, + 'type_id' => $asset->type_id, + ]); + } + + /** + * Purge old data, so we don't run into data issues + */ + public function PurgeStaleData() { + Asset::where('updated_at', '<', Carbon::now()->subDay())->delete(); + } + + /** + * Get the liquid ozone asset + */ + public function GetAssetByType($type, $structureId) { + //See if the row is in the database table + $count = Asset::where([ + 'location_id' => $structureId, + 'type_id' => $type, + 'location_flag' => 'StructureFuel', + ])->count(); + //Get the row if it is in the table + $asset = Asset::where([ + 'location_id' => $structureId, + 'type_id' => $type, + 'location_flag' => 'StructureFuel', + ])->first(); + + if($count == 0) { + return 0; + } else { + return $asset['quantity']; + } + } +} + +?> \ No newline at end of file diff --git a/app/Library/Helpers/FinanceHelper.php b/app/Library/Helpers/FinanceHelper.php new file mode 100644 index 0000000..e464bb9 --- /dev/null +++ b/app/Library/Helpers/FinanceHelper.php @@ -0,0 +1,300 @@ +GetRefreshToken($charId); + $esi = $esiHelper->SetupEsiAuthentication($token); + + //Check the scope + if(!$esiHelper->HaveEsiScope($charId, 'esi-wallet.read_corporation_wallets.v1')) { + Log::critical('Scope check failed for esi-wallet.read_corporation_wallets.v1 for character id: ' . $charId); + return null; + } + + //Reference the character id to the corporation id + $char = $lookup->GetCharacterInfo($charId); + $corpId = $char->corporation_id; + + //Set the current page to 1 which is the page we start on + $currentPage = 1; + //Set the total pages to 1, but in the future we will set it to another number + $totalPages = 1; + //Setup a page failed variable + $pageFailed = false; + + do { + /** + * During the course of the operation, we want to ensure our token hasn't expired. + * If the token has expired, then resetup the authentication container, which will refresh the + * access token. + */ + if($esiHelper->TokenExpired($token)) { + $token = $esiHelper->GetRefreshToken($charId); + $esi = $esiHelper->SetupEsiAuthentication($token); + } + + /** + * Attempt to get the data from the esi api. If it fails, we skip the page, and go onto the next page, unless + * the failed page is the first page. + */ + try { + $journals = $esi->page($currentPage) + ->invoke('get', '/corporations/{corporation_id}/wallets/{division}/journal/', [ + 'corporation_id' => $corpId, + 'division' => $division, + ]); + } catch(RequestFailedException $e) { + Log::warning('Failed to get wallet journal page ' . $currentPage . ' for character id: ' . $charId); + Log::warning($e); + dd($e); + $pageFailed = true; + } + + /** + * If the current page is the first one and the page didn't fail, then update the total pages. + * If the first page failed, just return as we aren't going to be able to get the total amount of data needed. + */ + if($currentPage == 1 && $pageFailed == false) { + $totalPages = $journals->pages; + } else if($currentPage == 1 && $pageFailed == true) { + return null; + } + + /** + * If the page was successfully pulled, we need to decode the data, then cycle through the data, and save it + * where we can. + */ + if($pageFailed == false) { + //Decode the json data, and return it as an array + $wallet = json_decode($journals->raw, true); + + + //Foreach journal entry, add the journal entry to the table + foreach($wallet as $entry) { + //See if we find the entry id in the database already + $found = AllianceWalletJournal::where([ + 'id' => $entry['id'], + ])->count(); + + if($found == 0) { + $awj = new AllianceWalletJournal; + $awj->id = $entry['id']; + $awj->corporation_id = $corpId; + $awj->division = $division; + if(isset($entry['amount'])) { + $awj->amount = $entry['amount']; + } + if(isset($entry['balance'])) { + $awj->balance = $entry['balance']; + } + if(isset($entry['context_id'])) { + $awj->context_id = $entry['context_id']; + } + if(isset($entry['date'])) { + $awj->date = $esiHelper->DecodeDate($entry['date']); + } + if(isset($entry['description'])) { + $awj->description = $entry['description']; + } + if(isset($entry['first_party_id'])) { + $awj->first_party_id = $entry['first_party_id']; + } + if(isset($entry['reason'])) { + $awj->reason = $entry['reason']; + } + if(isset($entry['ref_type'])) { + $awj->ref_type = $entry['ref_type']; + } + if(isset($entry['tax'])) { + $awj->tax = $entry['tax']; + } + if(isset($entry['tax_receiver_id'])) { + $awj->tax_receiver_id = $entry['tax_receiver_id']; + } + $awj->save(); + + } + } + } else { + /** + * If the current page failed to get data from the esi, then reset the page failed data. + * Continue to try to pull the next page of data. We might be able to get the current failed page + * later in another pull if it is successful. + */ + $pageFailed = false; + } + + //Increment the current page counter + $currentPage++; + } while($currentPage <= $totalPages); + + return 0; + } + + /** + * Get the pages for the alliance wallet journal + */ + public function GetAllianceWalletJournalPages($division, $charId) { + $lookup = new LookupHelper; + $esiHelper = new Esi; + + //Setup the esi container. + $token = $esiHelper->GetRefreshToken($charId); + $esi = $esiHelper->SetupEsiAuthentication($token); + + //Check the scope + if(!$esiHelper->HaveEsiScope($charId, 'esi-wallet.read_corporation_wallets.v1')) { + Log::critical('Scope check failed for esi-wallet.read_corporation_wallets.v1 for character id: ' . $charId); + return null; + } + + //Reference the character id to the corporation id + $char = $lookup->GetCharacterInfo($charId); + $corpId = $char->corporation_id; + + /** + * Attempt to get the data from the esi api. If it fails, we skip the page, and go onto the next page, unless + * the failed page is the first page. + */ + try { + $journals = $esi->page(1) + ->invoke('get', '/corporations/{corporation_id}/wallets/{division}/journal/', [ + 'corporation_id' => $corpId, + 'division' => $division, + ]); + } catch(RequestFailedException $e) { + Log::warning('Failed to get wallet journal pages for character id: ' . $charId); + Log::warning($e); + return 0; + } + + //Return the total pages + return $journals->pages; + } + + private function GetPIMaterialsArray() { + //Setup array for PI items + $pi_items = [ + //R0 Materials + '2073', + '2667', + '2268', + '2270', + '2272', + '2286', + '2287', + '2288', + '2305', + '2306', + '2307', + '2308', + '2309', + '2310', + '2311', + //P1 Materials + '2389', + '2390', + '2392', + '2393', + '2395', + '2396', + '2397', + '2398', + '2399', + '2400', + '2401', + '3645', + '3683', + '3779', + '9828', + //P2 Materials + '44', + '2312', + '2317', + '2319', + '2321', + '2327', + '2328', + '2329', + '2463', + '3689', + '3691', + '3693', + '3695', + '3697', + '3725', + '3775', + '3828', + '9830', + '9832', + '9836', + '9838', + '9840', + '9842', + '15317', + //P3 Materials + '2344', + '2345', + '2346', + '2348', + '2349', + '2351', + '2352', + '2354', + '2358', + '2360', + '2361', + '2366', + '2367', + '9834', + '9846', + '9848', + '12836', + '17136', + '17392', + '17898', + '28974', + //P4 Materials + '2867', + '2868', + '2869', + '2870', + '2871', + '2872', + '2875', + '2876', + ]; + + return $pi_items; + } + +} + +?> \ No newline at end of file diff --git a/app/Library/Helpers/LookupHelper.php b/app/Library/Helpers/LookupHelper.php new file mode 100644 index 0000000..32c779b --- /dev/null +++ b/app/Library/Helpers/LookupHelper.php @@ -0,0 +1,1109 @@ +esi = $esiHelper->SetupEsiAuthentication(); + } + + public function StructureTypeIdToName($typeId) { + $structureTypes = [ + 35841 => 'Ansiblex Jump Gate', + 35840 => 'Pharolux Cyno Beacon', + 37534 => 'Tenebrex Cyno Jammer', + 35834 => 'Keepstar', + 35833 => 'Fortizar', + 35832 => 'Astrahus', + 35836 => 'Tatara', + 35835 => 'Athanor', + 35827 => 'Sotiyo', + 35826 => 'Azbel', + 35825 => 'Raitaru', + ]; + + return $structureTypes[$typeId]; + } + + public function StructureNameToTypeId($name) { + $structureTypes = [ + 'Ansiblex Jump Gate' => 35841, + 'Pharolux Cyno Beacon' => 35840, + 'Tenebrex Cyno Jammer' => 37534, + 'Keepstar' => 35834, + 'Fortizar' => 35833, + 'Astrahus' => 35832, + 'Tatara' => 35836, + 'Athanor' => 35835, + 'Sotiyo' => 35827, + 'Azbel' => 35826, + 'Raitaru' => 35825, + ]; + + return $structureTypes[$name]; + } + + public function ItemNameToId($itemName) { + $item = ItemLookup::where([ + 'name' => $itemName, + ])->first(); + + if($item != null) { + return $item->type_id; + } else { + try { + $response = $this->esi->setBody(array( + $itemName, + ))->invoke('post', '/universe/ids/'); + } catch(RequestFailedException $e) { + printf("Failed to get the item information"); + Log::warning('Failed to get item information from /universe/'); + return null; + } + + if(isset($response->inventory_types)) { + return $response->inventory_types[0]->id; + } else { + return null; + } + } + } + + public function ItemIdToName($itemId) { + //Check if the item is stored in our own database first + $item = $this->LookupItem($itemId); + + //If the item is found, return it, otherwise, do some esi to find it. + if($item != null) { + return $item->name; + } else { + try { + $response = $this->esi->invoke('get', '/universe/types/{type_id}/', [ + 'type_id' => $itemId, + ]); + } catch(RequestFailedException $e) { + printf("Failed to get the item name from the id.\r\n"); + var_dump($e); + printf("\r\n"); + Log::warning('Failed to get item information from /universe/types/{type_id}/ in LookupHelper.'); + return null; + } + + if(isset($response->description)) { + $this->StoreItem($response); + + return $response->name; + } else { + return null; + } + } + } + + private function LookupItem($itemId) { + $item = ItemLookup::where([ + 'type_id' => $itemId, + ])->first(); + + return $item; + } + + private function StoreItem($item) { + $newItem = new ItemLookup; + if(isset($item->capacity)) { + $newItem->capacity = $item->capacity; + } + $newItem->description = $item->description; + if(isset($item->graphic_id)) { + $newItem->graphic_id = $item->graphic_id; + } + $newItem->group_id = $item->group_id; + if(isset($item->icon_id)) { + $newItem->icon_id = $item->icon_id; + } + if(isset($item->market_group_id)) { + $newItem->market_group_id = $item->market_group_id; + } + if(isset($item->mass)) { + $newItem->mass = $item->mass; + } + $newItem->name = $item->name; + if(isset($item->packaged_volume)) { + $newItem->packaged_volume = $item->packaged_volume; + } + if(isset($item->portion_size)) { + $newItem->portion_size = $item->portion_size; + } + $newItem->published = $item->published; + if(isset($item->radius)) { + $newItem->radius = $item->radius; + } + $newItem->type_id = $item->type_id; + if(isset($item->volume)) { + $newItem->volume = $item->volume; + } + $newItem->save(); + } + + public function SystemIdToName($systemId) { + //Check if the solar system is stored in our database first + $solarSystem = $this->LookupSolarSystemId($systemId); + + if($solarSystem != null) { + return $solarSystem->name; + } else { + try { + $solar = $this->esi->invoke('get', '/universe/systems/{system_id}/', [ + 'system_id' => $systemId, + ]); + } catch(RequestFailedException $e) { + Log::warning('Failed to get system id from /universe/systems in Lookup Helper.'); + return null; + } + + $this->StoreSolarSystem($solar); + + return $solar->name; + } + } + + public function SystemNameToId($system) { + //Check if the solar system is stored in our own database first + $solarSystem = $this->LookupSolarSystem($system); + + if($solarSystem != null) { + return $solarSystem->solar_system_id; + } else { + try { + $response = $this->esi->setBody(array( + $system, + ))->invoke('post', '/universe/ids/'); + } catch(RequestFailedException $e) { + Log::warning('Failed to get system name from /universe/ids/ in lookup helper.'); + return null; + } + + if(isset($response->systems)) { + $this->StoreSolarSystem($response->systems[0]); + + return $response->systems[0]->id; + } else { + return null; + } + } + } + + private function LookupSolarSystemId($systemId) { + $solar = SolarSystem::where([ + 'solar_system_id' => $systemId, + ])->first(); + + return $solar; + } + + private function LookupSolarSystem($system) { + $solar = SolarSystem::where([ + 'name' => $system, + ])->first(); + + return $solar; + } + + private function StoreSolarSystem($system) { + if(isset($system->id)) { + SolarSystem::insertOrIgnore([ + 'name' => $system->name, + 'solar_system_id' => $system->id, + ]); + } else if(isset($system->system_id)) { + SolarSystem::insertOrIgnore([ + 'name' => $system->name, + 'solar_system_id' => $system->system_id, + ]); + } else { + $solar = new SolarSystem; + $solar->name = $system->name; + $solar->solar_system_id = $system->id; + $solar->save(); + } + } + + /** + * Get moon information from the database, or store it in the database if it's not found + */ + public function GetMoonInfo($moonId) { + //Check our own database first + $moon = $this->LookupMoonInfo($moonId); + + //If no data was found in the database, then save the data, and return what is found through esi + if( $moon == null) { + try { + $response = $this->esi->invoke('get', '/universe/moons/{moon_id}/', [ + 'moon_id' => $moonId, + ]); + } catch(RequestFailedException $e) { + Log::critical("Failed to get moon information in LookupHelper."); + return null; + } + + $this->SaveMoonInfo($response); + + return $response; + } else { + //Return the moon info + return $moon; + } + } + + /** + * Lookup moon info from the database + */ + private function LookupMoonInfo($moonId) { + $moon = MoonLookup::where([ + 'moon_id' => $moonId, + ])->first(); + + return $moon; + } + + /** + * Save moon info into the lookup database + */ + private function SaveMoonInfo($moon) { + $newMoon = new MoonLookup; + $newMoon->moon_id = $moon->moon_id; + $newMoon->name = $moon->name; + $newMoon->position_x = $moon->position->x; + $newMoon->position_y = $moon->position->y; + $newMoon->position_z = $moon->position->z; + $newMoon->system_id = $moon->system_id; + $newMoon->save(); + } + + public function GetCharacterInfo($charId) { + //Check our own database first + $char = $this->LookupCharacter($charId, null); + + //if the character was not found in the database, then get the information and store it in our database for later + if($char == null) { + try { + $response = $this->esi->invoke('get', '/characters/{character_id}/', [ + 'character_id' => $charId, + ]); + } catch(RequestFailedException $e) { + Log::warning('Failed to get character information in GetCharacterInfo in Lookup'); + dd($e); + return null; + } + + //Store the character in our database + $this->SaveCharacter($response, $charId); + + //Return the character details to the calling function + return $response; + } else { + //Return what was pulled from the database + return $char; + } + } + + public function GetCorporationInfo($corpId) { + //Check our own database first + $corp = $this->LookupCorporation($corpId, null); + + //If the corporation was not found in the database, then get the information and store it in our database for later + if($corp == null) { + try { + $response = $this->esi->invoke('get', '/corporations/{corporation_id}/', [ + 'corporation_id' => $corpId, + ]); + } catch(RequestFailedException $e) { + Log::warning('Failed to get corporation information in GetCorporationInfo in Lookup'); + return null; + } + + //Store the corporation in our database + $this->SaveCorporation($response, $corpId); + + //Return the corporation details to the calling function + return $response; + } else { + //Return what was pulled from the database + return $corp; + } + } + + public function GetAllianceInfo($allianceId) { + //Check our own database first + $ally = $this->LookupAlliance($allianceId, null); + + if($ally == null) { + try { + $response = $this->esi->invoke('get', '/alliances/{alliance_id}/', [ + 'alliance_id' => $allianceId, + ]); + } catch(RequestFailedException $e) { + Log::warning('Failed to get alliance information in GetAllianceInfo in Lookup'); + return null; + } + + //Store the alliance in our database + $this->SaveAlliance($response, $allianceId); + + return $response; + } else { + return $ally; + } + } + + public function CharacterIdToName($charId) { + //Check if the character is stored in our own database first + $char = $this->LookupCharacter($charId, null); + //If the char is null, then we did not find the character in our own database + if($char != null) { + return $char->name; + } else { + //Get the character id from esi + try { + $character = $this->esi->invoke('get', '/characters/{character_id}/', [ + 'character_id' => $charId, + ]); + } catch(RequestFailedException $e) { + Log::warning('Failed to get character name from /characters/{character_id}/ in lookup helper.'); + return null; + } + + if(isset($character->name)) { + //Store the character name for the lookup table + $this->StoreCharacterLookup(null, $character->name); + //Return the character name to the calling function + return $character->name; + } else { + //If we don't find any information return null + return null; + } + } + } + + public function CharacterNameToId($charName) { + //Check if the character is stored in our own database first + $char = $this->LookupCharacter(null, $charName); + + if($char != null) { + return $char->character_id; + } else { + try { + $response = $this->esi->setBody(array( + $charName, + ))->invoke('post', '/universe/ids/'); + } catch(RequestFailedException $e) { + Log::warning('Failed to get character name from /universe/ids/ in lookup helper.'); + return null; + } + + if(isset($response->characters[0]->id)) { + $this->StoreCharacterLookup($response->characters[0]->id, null); + + return $response->characters[0]->id; + } else { + return null; + } + } + } + + public function CorporationIdToName($corpId) { + //Check if the corporation is stored in our own database first + $corp = $this->LookupCorporation($corpId, null); + if($corp != null) { + return $corp->name; + } else { + //Try to get the corporation details from ESI + try { + $corporation = $this->esi->invoke('get', '/corporations/{corporation_id}/', [ + 'corporation_id' => $corpId, + ]); + } catch(RequestFailedException $e) { + //Log the issue + Log::warning('Failed to get corporation name from /corporations/{corporation_id}/ in lookup helper.'); + return null; + } + + if(isset($corporation->name)) { + //Store the corporation name for the lookup table + $this->StoreCorporationLookup(null, $corporation->name); + //Return the corporation name to the calling function + return $corporation->name; + } else { + //If nothing is found and ESI didn't work, return null to the calling function + return null; + } + } + } + + public function CorporationNameToId($corpName) { + //Check if the corporation is stored in our own database first + $corp = $this->LookupCorporation(null, $corpName); + + if($corp != null) { + return $corp->corporation_id; + } else { + //Try to get the corporation details from ESI + try { + $response = $this->esi->setBody(array( + $corpName, + ))->invoke('post', '/universe/ids/'); + } catch(RequestFailedException $e) { + Log::warning('Failed to get the corporation id from /universe/ids/ in lookup helper.'); + return null; + } + + if(isset($response->corporations[0]->id)) { + $this->StoreCorporationLookup($response->corporations[0]->id, null); + + return $response->corporations[0]->id; + } else { + return null; + } + } + } + + public function AllianceIdToName($allianceId) { + //Check if the alliance is stored in our own database first + $alliance = $this->LookupAlliance($allianceId, null); + if($alliance != null) { + return $alliance->alliance_id; + } else { + //Try to get the alliance details from ESI + try { + $alliance = $this->esi->invoke('get', '/alliances/{alliance_id}/', [ + 'alliance_id' => $allianceId, + ]); + } catch(RequestFailedException $e) { + Log::warning('Failed to get the alliance name from /alliances/{alliance_id}/ in lookup helper.'); + return null; + } + + if(isset($alliance->name)) { + $this->StoreAllianceLookup(null, $alliance->name); + + return $alliance->name; + } else { + return null; + } + } + } + + public function AllianceNameToId($allianceName) { + //Check if the alliance is stored in our own database first + $alliance = $this->LookupAlliance(null, $allianceName); + if($alliance != null) { + return $alliance->name; + } else { + //Try to get the alliance details from ESI + try { + $response = $this->esi->setBody(array( + $allianceName, + ))->invoke('post', '/universe/ids/'); + } catch(RequestFailedException $e) { + Log::warning('Failed to get the alliance id from /universe/ids/ in lookup helper.'); + return null; + } + + //If the data is pulled from ESI store the data, and send the data back to the calling function + if(isset($response->alliances[0]->id)) { + $this->StoreAllianceLookup($response->alliances[0]->id, null); + + return $response->alliances[0]->id; + } else { + return null; + } + } + } + + private function LookupCharacter($id = null, $name = null) { + //If both the id and name are null, then there is nothing to lookup + if($id == null & $name == null) { + return null; + } + + $character = null; + + //If the id is null attempt to lookup the character + if($id != null) { + $count = CharacterLookup::where(['character_id' => $id])->count(); + if($count > 0) { + $character = CharacterLookup::where(['character_id' => $id])->first(); + } else { + //If we didn't find it in the database, then return null + return null; + } + } else if($name != null) { + //If the name is not null then attemp to lookup the character + $count = CharacterLookup::where(['name' => $name])->count(); + if($count > 0) { + $character = CharacterLookup::where(['name' => $name])->first(); + } else { + //If we didn't find it in the database, then return null + return null; + } + } + + //Return the character details to the calling function + return $character; + } + + private function LookupCorporation($id = null, $name = null) { + if($id == null && $name == null) { + return null; + } + + $corporation = null; + + //If the id is not null attempt to lookup the character + if($id != null) { + $count = CorporationLookup::where(['corporation_id' => $id])->count(); + if($count > 0) { + $corporation = CorporationLookup::where(['corporation_id' => $id])->first(); + } else { + $corporation = null; + } + } else if($name != null) { + $count = CorporationLookup::where(['name' => $name])->count(); + if($count > 0) { + $corporation = CorporationLookup::where(['name' => $name])->first(); + } else { + $corporation = null; + } + } + + return $corporation; + } + + private function LookupAlliance($id = null, $name = null) { + if($id == null && $name == null) { + return null; + } + + $alliance = null; + + if($id != null) { + $count = AllianceLookup::where(['alliance_id' => $id])->count(); + if($count > 0) { + $alliance = AllianceLookup::where(['alliance_id' => $id])->first(); + } else { + $alliance = null; + } + } else if($name != null) { + $count = AllianceLookup::where(['name' => $name])->count(); + if($count > 0) { + $alliance = AllianceLookup::where(['name' => $name])->first(); + } else { + $alliance = null; + } + } + + return $alliance; + } + + private function StoreCharacterLookup($id = null, $name = null) { + //Declare the esi helper + $esiHelper = new Esi; + + //If the id and name are null, just return + if($id == null && $name == null) { + return; + } + + //If the id isn't null, then get the character information from the esi via the character id + if($id != null) { + //See if the character already exists in the lookup table + $count = CharacterLookup::where(['character_id' => $id])->count(); + if($count == 0) { + try { + $response = $this->esi->invoke('get', '/characters/{character_id}/', [ + 'character_id' => $id, + ]); + } catch(RequestFailedException $e) { + return; + } + + $corpId = $this->SaveCharacter($response, $id); + + if($corpId != null) { + //Do a recursive call for the corporation Lookup + $this->StoreCorporationLookup($corpId, null); + } + } else { + return; + } + } else { + return; + } + + //If the name is not null attempt to add the character to the table + if($name != null) { + $count = CharacterLookup::where(['name' => $name])->count(); + if($count == 0) { + try { + //Get the character id from the ESI API + $responseName = $this->esi->setBody(array( + $name, + ))->invoke('post', '/universe/ids/'); + } catch(RequestFailedException $e) { + return; + } + + try { + $response = $this->esi->invoke('get', '/characters/{character_id}/', [ + 'character_id' => $responseName->characters[0]->id, + ]); + } catch(RequestFailedException $e) { + return; + } + + $corpId = $this->SaveCharacter($response, $responseName->characters[0]->id); + if($corpId != null) { + //Do a recursive call for the corporation Lookup + $this->StoreCorporationLookup($corpId, null); + } + + } else { + return; + } + } else { + return; + } + } + + private function SaveCharacter($response, $charId) { + $esiHelper = new Esi; + + $char = new CharacterLookup; + + $char->character_id = $charId; + if(isset($response->alliance_id)) { + $char->alliance_id = $response->alliance_id; + } + if(isset($response->ancestry_id)) { + $char->ancestry_id = $response->ancestry_id; + } + $char->birthday = $esiHelper->DecodeDate($response->birthday); + $char->bloodline_id = $response->bloodline_id; + $char->corporation_id = $response->corporation_id; + if(isset($response->description)) { + $char->description = $response->description; + } + if(isset($response->faction_id)) { + $char->faction_id = $response->faction_id; + } + $char->gender = $response->gender; + $char->name = $response->name; + $char->race_id = $response->race_id; + if(isset($response->security_status)) { + $char->security_status = $response->security_status; + } + if(isset($response->title)) { + $char->title = $response->title; + } + $char->save(); + + return $response->corporation_id; + } + + public function UpdateCharacters() { + $all = CharacterLookup::all(); + + foreach($all as $entry) { + //Attempt to get the data from ESI + try { + $response = $this->esi->invoke('get', '/characters/{character_id}/', [ + 'character_id' => $entry->character_id, + ]); + } catch(RequestFailedException $e) { + + } + + //Update the data + if(isset($response->alliance_id)) { + if($response->alliance_id != $entry->alliance_id) { + CharacterLookup::where([ + 'character_id' => $entry->character_id, + ])->update([ + 'alliance_id' => $response->alliance_id, + ]); + } + } + if(isset($response->description)) { + if($response->description != $entry->description) { + CharacterLookup::where([ + 'character_id' => $entry->character_id, + ])->update([ + 'description' => $response->description, + ]); + } + } + if(isset($response->security_status)) { + if($response->security_status != $entry->security_status) { + CharacterLookup::where([ + 'character_id' => $entry->character_id, + ])->update([ + 'security_status' => $response->security_status, + ]); + } + } + if(isset($response->title)) { + if($response->title != $entry->title) { + CharacterLookup::where([ + 'character_id' => $entry->character_id, + ])->update([ + 'title' => $response->title, + ]); + } + } + if(isset($response->corporation_id)) { + if($response->corporation_id != $entry->corporation_id) { + CharacterLookup::where([ + 'character_id' => $entry->character_id, + ])->update([ + 'corporation_id' => $response->corporation_id, + ]); + } + } + } + } + + private function StoreCorporationLookup($id = null, $name = null) { + //Declare the esi helper + $esiHelper = new Esi; + + //If the id is null and the name is null, then return + if($id == null && $name == null) { + return; + } + + if($id != null) { + $count = CorporationLookup::where(['corporation_id' => $id])->count(); + if($count == 0) { + try { + $response = $this->esi->invoke('get', '/corporations/{corporation_id}/', [ + 'corporation_id' => $id, + ]); + } catch(RequestFailedException $e) { + return; + } + + $allianceId = $this->SaveCorporation($response, $id); + + if($allianceId != null) { + $this->StoreAllianceLookup($allianceId); + } + } else { + return; + } + } else { + return; + } + + if($name != null) { + $count = CorporationLookup::where(['name' => $name])->count(); + if($count == 0) { + try { + //Get the corporation id from the ESI API + $responseName = $this->esi->setBody(array( + $name, + ))->invoke('post', '/universe/ids/'); + } catch(RequestFailedException $e) { + return; + } + + try { + $response = $this->esi->invoke('get', '/corporations/{corporation_id}/', [ + 'corporation_id' => $responseName->corporations[0]->id, + ]); + } catch(ReqeustFailedException $e) { + return; + } + + $allianceId = $this->SaveCorporation($response, $responseName->corporations[0]->id); + if($allianceId != null) { + //Do a recursive call for the alliance lookup + $this->StoreAllianceLookup($allianceId, null); + } + } else { + return; + } + } else { + return; + } + } + + private function SaveCorporation($response, $corpId) { + $esiHelper = new Esi; + + $corp = new CorporationLookup; + $corp->corporation_id = $corpId; + if(isset($response->alliance_id)) { + $corp->alliance_id = $response->alliance_id; + } + $corp->ceo_id = $response->ceo_id; + $corp->creator_id = $response->creator_id; + if(isset($response->date_founded)) { + $corp->date_founded = $esiHelper->DecodeDate($response->date_founded); + } + if(isset($response->description)) { + $corp->description = $response->description; + } + if(isset($response->faction_id)) { + $corp->faction_id = $response->faction_id; + } + if(isset($response->home_station_id)) { + $corp->home_station_id = $response->home_station_id; + } + $corp->member_count = $response->member_count; + $corp->name = $response->name; + if(isset($response->shares)) { + $corp->shares = $response->shares; + } + $corp->tax_rate = $response->tax_rate; + $corp->ticker = $response->ticker; + if(isset($response->url)) { + $corp->url = $response->url; + } + if(isset($response->war_eligible)) { + $corp->war_eligible = $response->war_eligible; + } + $corp->save(); + + if(isset($response->alliance_id)) { + return $response->alliance_id; + } else { + return null; + } + + } + + public function UpdateCorporations() { + $all = CorporationLookup::all(); + + foreach($all as $entry) { + try { + $response = $this->esi->invoke('get', '/corporations/{corporation_id}/', [ + 'corporation_id' => $entry->corporation_id, + ]); + } catch(RequestFailedException $e) { + + } + + if(isset($response->alliance_id)) { + if($response->alliance_id != $entry->alliance_id) { + CorporationLookup::where([ + 'corporation_id' => $entry->corporation_id, + ])->update([ + 'alliance_id' => $response->alliance_id, + ]); + } + + if(isset($response->description)) { + if($response->description != $entry->description) { + CorporationLookup::where([ + 'corporation_id' => $entry->corporation_id, + ])->update([ + 'description' => $response->description, + ]); + } + } + + if(isset($response->faction_id)) { + if($response->faction_id != $entry->faction_id) { + CorporationLookup::where([ + 'corporation_id' => $entry->corporation_id, + ])->update([ + 'faction_id' => $response->faction_id, + ]); + } + } + + if(isset($response->home_station_id)) { + if($response->home_station_id != $entry->home_station_id) { + CorporationLookup::where([ + 'corporation_id' => $entry->corporation_id, + ])->update([ + 'home_station_id' => $response->home_station_id, + ]); + } + } + + if(isset($response->member_count)) { + if($response->member_count != $entry->member_count) { + CorporationLookup::where([ + 'corporation_id' => $entry->corporation_id, + ])->update([ + 'member_count' => $response->member_count, + ]); + } + } + + if(isset($response->tax_rate)) { + if($response->tax_rate != $entry->tax_rate) { + CorporationLookup::where([ + 'corporation_id' => $entry->corporation_id, + ])->update([ + 'tax_rate' => $response->tax_rate, + ]); + } + } + + if(isset($response->url)) { + if($response->url != $entry->url) { + CorporationLookup::where([ + 'corporation_id' => $entry->corporation_id, + ])->update([ + 'url' => $response->url, + ]); + } + } + + if(isset($response->war_eligible)) { + if($response->war_eligible != $entry->war_eligible) { + CorporationLookup::where([ + 'corporation_id' => $entry->corporation_id, + ])->update([ + 'war_eligible' => $response->war_eligible, + ]); + } + } + } + } + } + + private function StoreAllianceLookup($id = null, $name = null) { + //Declare the esi helper + $esiHelper = new Esi; + + //Check if the passed variables are null + if($id == null && $name == null) { + return; + } + + //If the id isn't null then attempt to populate the table + if($id != null) { + //See if the alliance already exists in the table + $count = AllianceLookup::where(['alliance_id' => $id])->count(); + if($count == 0) { + try { + $response = $this->esi->invoke('get', '/alliances/{alliance_id}/', [ + 'alliance_id' => $id, + ]); + } catch(RequestFailedException $e) { + return; + } + + $this->SaveAlliance($response, $id); + } + } + + //If the name isn't null then attempt to populate the table + if($name != null) { + $count = AllianceLookup::where(['name' => $name])->count(); + if($count == 0) { + try { + $responseName = $this->esi->setBody(array( + $name, + ))->invoke('post', '/universe/ids/'); + } catch(RequestFailedException $e) { + return; + } + + try { + $response = $this->esi->invoke('get', '/alliances/{alliance_id}/', [ + 'alliance_id' => $responseName->alliances[0]->id, + ]); + } catch(RequestFailedException $e) { + return; + } + + $this->SaveAlliance($response, $responseName->alliances[0]->id); + } + } + } + + private function SaveAlliance($response, $allianceId) { + $esiHelper = new Esi; + + $alliance = new AllianceLookup; + $alliance->alliance_id = $allianceId; + $alliance->creator_corporation_id = $response->creator_corporation_id; + $alliance->creator_id = $response->creator_id; + $alliance->date_founded = $esiHelper->DecodeDate($response->date_founded); + if(isset($response->executor_corporation_id)) { + $alliance->executor_corporation_id = $response->executor_corporation_id; + } + if(isset($response->faction_id)) { + $alliance->faction_id = $response->faction_id; + } + $alliance->name = $response->name; + $alliance->ticker = $response->ticker; + $alliance->save(); + } + + public function UpdateAlliances() { + $all = AllianceLookup::all(); + + foreach($all as $entry) { + try { + $response = $this->esi->invoke('get', '/alliances/{alliance_id}/', [ + 'alliance_id' => $entry->alliance_id, + ]); + } catch(RequestFailedException $e) { + + } + + if(isset($response->executor_corporation_id)) { + if($response->executor_corporation_id != $entry->executor_corporation_id) { + AllianceLookup::where([ + 'alliance_id' => $entry->alliance_id, + ])->update([ + 'executor_corporation_id' => $response->executor_corporation_id, + ]); + } + } + + if(isset($response->faction_id)) { + if($response->faction_id != $entry->faction_id) { + AllianceLookup::where([ + 'alliance_id' => $entry->alliance_id, + ])->update([ + 'faction_id' => $response->faction_id, + ]); + } + } + } + } +} + +?> \ No newline at end of file diff --git a/app/Library/Helpers/MiningLedgerHelper.php b/app/Library/Helpers/MiningLedgerHelper.php new file mode 100644 index 0000000..8599836 --- /dev/null +++ b/app/Library/Helpers/MiningLedgerHelper.php @@ -0,0 +1,189 @@ +charId = $charId; + $this->corpId = $corpID; + } + + /** + * Get the corporation's mining structures. + * These structures consist of Athanors and Tataras + * + * @return array + */ + public function GetCorpMiningStructures() { + //Declare variables + $esiHelper = new Esi; + + //Check if the character has the correct ESI Scope. If the character doesn't, then return false, but + //also send a notice eve mail to the user. The HaveEsiScope sends a mail for us. + if(!$esiHelper->HaveEsiScope($this->charId, 'esi-industry.read_corporation_mining.v1')) { + Log::warning('Character: ' . $this->charId . ' did not have the appropriate esi scope for the mining ledger.'); + return null; + } + + //Get the refresh token from the database and setup the esi authenticaiton container + $esi = $esiHelper->SetupEsiAuthentication($esiHelper->GetRefreshToken($this->charId)); + + //Get a list of the mining observers, which are structures + try { + $observers = $esi->invoke('get', '/corporation/{corporation_id}/mining/observers/', [ + 'corporation_id' => $this->corpId, + ]); + } catch(RequestFailedException $e) { + Log::warning('Could not find any mining observers for corporation: ' . $this->corpId); + return null; + } + + return $observers; + } + + /** + * Get the mining struture information + * + * @return array + */ + public function GetMiningStructureInfo($observerId) { + //Declare variables + $esiHelper = new Esi; + $lookup = new LookupHelper; + + //Check for ESI scopes + if(!$esiHelper->HaveEsiScope($this->charId, 'esi-universe.read_structures.v1')) { + return null; + } + + //Get the refresh token and setup the esi authentication container + $esi = $esiHelper->SetupEsiAuthentication($esiHelper->GetRefreshToken($this->charId)); + + //Try to get the structure information + try { + $info = $esi->invoke('get', '/universe/structures/{struture_id}/', [ + 'structure_id' => $observerId, + ]); + } catch(RequestFailedExcept $e) { + return null; + } + + $system = $lookup->SystemIdToName($info->solar_system_id); + + return [ + 'name' => $info->name, + 'system' => $system, + ]; + } + + /** + * Get the mining ledger for a particular structure + * + * @var observerId + * @return array + */ + public function GetMiningLedger($observerId) { + //Declare variables + $esiHelper = new Esi; + + //Check for ESI Scopes + if(!$esiHelper->HaveEsiScope($this->charId, 'esi-industry.read_corporation_mining.v1')) { + return null; + } + + //Get the refresh token and setup the esi authentication container + $esi = $esiHelper->SetupEsiAuthentication($esiHelper->GetRefreshToken($charId)); + + //Get the mining ledger + try { + $ledger = $esi->invoke('get', '/corporation/{corporation_id}/mining/observers/{observer_id}/', [ + 'corporation_id' => $corpId, + 'observer_id' => $observerId, + ]); + } catch(RequestFailedException $e) { + return null; + } + + return $ledger; + } + + /** + * Process the mining ledger into something more readable for humans + * + * @var array + * @return array + */ + public function ProcessMiningLedger($ledger, $date) { + //Declare some variables + $items = array(); + $notSorted = array(); + $final = array(); + $lookup = new LookupHelper; + + + //In the first iteration of the array get rid of the extra items we don't want + foreach($ledger as $ledg) { + if($ledg->last_updated == $date) { + array_push($items, $ledg); + } + } + + //Sort through the array and replace character id with name and item id with name + foreach($items as $item) { + $charName = $lookup->CharacterIdToName($item->character_id); + $typeName = $lookup->ItemIdToName($item->type_id); + $corpName = $lookup->CorporationIdToName($item->recorded_corporation_id); + + if(isset($final[$charName])) { + $final[$charName] = [ + 'ore' => $typeName, + 'quantity' => $item->quantity, + 'date' => $item->last_updated, + ]; + } else { + $temp = [ + 'ore' => $typeName, + 'quantity' => $item->quantity, + 'date' => $item->last_updated, + ]; + + array_push($final[$charName], $temp); + } + } + + return $final; + } +} + +?> \ No newline at end of file diff --git a/app/Library/Helpers/MiningTaxHelper.php b/app/Library/Helpers/MiningTaxHelper.php new file mode 100644 index 0000000..5908eca --- /dev/null +++ b/app/Library/Helpers/MiningTaxHelper.php @@ -0,0 +1,72 @@ + $charId, + 'invoiced' => 'No', + ])->count(); + + if($rowCount > 0) { + $rows = Ledger::where([ + 'character_id' => $charId, + 'invoiced' => 'No', + ])->get()->toArray(); + + foreach($rows as $row) { + $ledgers->push($row); + } + } + + return $ledgers; + } + + /** + * Create the invoice and mail it + * + * @var int $charId + * @var collection $ledgers + * @var int $mailDelay + * + */ + public function MailMiningInvoice(int $charId, collection $ledgers, int &$mailDelay) { + + } +} \ No newline at end of file diff --git a/app/Library/Helpers/SRPHelper.php b/app/Library/Helpers/SRPHelper.php new file mode 100644 index 0000000..ddc6e0f --- /dev/null +++ b/app/Library/Helpers/SRPHelper.php @@ -0,0 +1,102 @@ + 'Approved', + ])->whereBetween('created_at', [$start, $end]) + ->sum('paid_value'); + + return $actual; + } + + public function GetAllianceSRPLoss($start, $end) { + $loss = 0.00; + + $loss = SRPShip::where([ + 'approved' => 'Approved', + ])->whereBetween('created_at', [$start, $end]) + ->sum('loss_value'); + + return $loss; + } + + public function GetTimeFrame($months) { + $start = Carbon::now()->startOfMonth(); + $start->hour = 23; + $start->minute = 59; + $start->second = 59; + $end = Carbon::now()->subMonths($months); + $end->hour = 23; + $end->minute = 59; + $end->second = 59; + + $date = [ + 'start' => $start, + 'end' => $end, + ]; + + return $date; + } + + /** + * Returns a set of dates from now until the amount of months has passed + * + * @var integer + * @returns array + */ + public function GetTimeFrameInMonths($months) { + //Declare an array of dates + $dates = array(); + //Setup the start of the array as the basis of our start and end dates + $start = Carbon::now()->startOfMonth(); + $end = Carbon::now()->endOfMonth(); + $end->hour = 23; + $end->minute = 59; + $end->second = 59; + + if($months == 1) { + $dates = [ + 'start' => $start, + 'end' => $end, + ]; + + return $dates; + } + + //Create an array of dates + for($i = 0; $i < $months; $i++) { + if($i == 0) { + $dates[$i]['start'] = $start; + $dates[$i]['end'] = $end; + } + + $start = Carbon::now()->startOfMonth()->subMonths($i); + $end = Carbon::now()->endOfMonth()->subMonths($i); + $end->hour = 23; + $end->minute = 59; + $end->second = 59; + $dates[$i]['start'] = $start; + $dates[$i]['end'] = $end; + } + + //Return the dates back to the calling function + return $dates; + } +} + +?> \ No newline at end of file diff --git a/app/Library/Helpers/StructureHelper.php b/app/Library/Helpers/StructureHelper.php new file mode 100644 index 0000000..be2754a --- /dev/null +++ b/app/Library/Helpers/StructureHelper.php @@ -0,0 +1,340 @@ +charId = $char; + $this->corpId = $corp; + if($esi == null) { + $esiHelper = new Esi; + $token = $esiHelper->GetRefreshToken($char); + $this->esi = $esiHelper->SetupEsiAuthentication($token); + } else { + $this->esi = $esi; + } + } + + public function GetStructuresByPage($page) { + + //Try to get the ESI data + try { + $structures = $this->esi->page($page) + ->invoke('get', '/corporations/{corporation_id}/structures/', [ + 'corporation_id' => $this->corpId, + ]); + } catch (RequestFailedException $e) { + Log::critical("Failed to get structure list."); + return null; + } + + return $structures; + } + + public function ProcessStructure($structure) { + + //Get the structure information + $info = $this->GetStructureInfo($structure->structure_id); + + //Record the structure information into the database + //Find if the structure exists + if(Structure::where(['structure_id' => $structure->structure_id])->count() == 0) { + $this->SaveNewStructure($structure, $info); + } else { + $this->UpdateExistingStructure($structure, $info); + } + } + + public function GetStructureName($structureId) { + try { + $info = $this->esi->invoke('get', '/universe/structures/{structure_id}/', [ + 'structure_id' => $structureId, + ]); + } catch(RequestFailedException $e) { + Log::warning("Failed to get structure information for structure with id " . $structureId); + Log::warning($e->getCode()); + Log::warning($e->getMessage()); + Log::warning($e->getEsiResponse()); + $info = null; + } + + $structure = json_decode($info->raw, true); + + if(!isset($structure['name'])) { + return null; + } else { + return (string)$structure['name']; + } + } + + /** + * Search for a structure in our own database, otherwise pull it from esi. + */ + public function GetStructureInfo($structureId) { + $info = Structure::where([ + 'structure_id' => $structureId, + ])->first(); + + if($info != null) { + return $info; + } else { + try { + $info = $this->esi->invoke('get', '/universe/structures/{structure_id}/', [ + 'structure_id' => $structureId, + ]); + } catch(RequestFailedException $e) { + Log::warning("Failed to get structure information for structure with id " . $structureId); + Log::warning($e->getCode()); + Log::warning($e->getMessage()); + Log::warning($e->getEsiResponse()); + return null; + } + + return $info; + } + } + + private function UpdateExistingStructure($structure, $info) { + $esi = new Esi; + + //Update the structure id and name + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'structure_id' => $structure->structure_id, + 'structure_name' => $info->name, + ]); + + //Update the services + if(isset($structure->services)) { + $services = true; + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'services' => $services, + ]); + } else { + $services = false; + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'services' => $services, + ]); + } + + //Update the structure state + if(isset($structure->state)) { + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'state' => $structure->state, + ]); + } else { + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'state' => 'None', + ]); + } + + //Update the state timer start + if(isset($structure->state_timer_start)) { + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'state_timer_start' => $esi->DecodeDate($structure->state_timer_start), + ]); + } + + //Update the state timer end + if(isset($structure->state_timer_end)) { + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'state_timer_end' => $esi->DecodeDate($structure->state_timer_end), + ]); + } + + //Update the fuel expires + if(isset($structure->fuel_expires)) { + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'fuel_expires' => $esi->DecodeDate($structure->fuel_expires), + ]); + } + + //Update the profile id, and positions + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'profile_id' => $structure->profile_id, + 'position_x' => $info->position->x, + 'position_y' => $info->position->y, + 'position_z' => $info->position->z, + ]); + + //Update the next reinforce apply + if(isset($structure->next_reinforce_apply)) { + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'next_reinforce_apply' => $esi->DecodeDate($structure->next_reinforce_apply), + ]); + } + + //update the next reinforce hour + if(isset($structure->next_reinforce_hour)) { + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'next_reinforce_hour' => $structure->next_reinforce_hour, + ]); + } + + //Update next reinforce weekday + if(isset($structure->next_reinforce_weekday)) { + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'next_reinforce_weekday' => $structure->next_reinforce_weekday, + ]); + } + + //Update reinforce hour + if(isset($structure->reinforce_hour)) { + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'reinforce_hour' => $structure->reinforce_hour, + ]); + } + + //Update reinforce weekday + if(isset($structure->reinforce_weekday)) { + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'reinforce_weekday' => $structure->reinforce_weekday, + ]); + } + + //Update the unanchors at field + if(isset($structure->unanchors_at)) { + //Decode the date / time + $daTi = $esi->DecodeDate($structure->unanchors_at); + + Structure::where(['structure_id' => $structure->structure_id])->update([ + 'unanchors_at' => $daTi, + ]); + } + + //Update the services for the structure as well + if($services == true) { + //Delete the existing services, then add the new services + if(Service::where(['structure_id' => $structure->structure_id])->count() > 0) { + Service::where(['structure_id' => $structure->structure_id])->delete(); + } + + + foreach($structure->services as $service) { + $serv = new Service; + $serv->structure_id = $structure->structure_id; + $serv->name = $service->name; + $serv->state = $service->state; + $serv->save(); + } + } + } + + private function SaveNewStructure($structure, $info) { + //Declare helper variable needed + $lookup = new LookupHelper; + $esi = new Esi; + + if(isset($info->solar_system_id)) { + $solarName = $lookup->SolarSystemIdToName($info->solar_system_id); + } else { + Log::critical("Couldn't get solar system name for structure " . $structure->structure_id . " in SaveNewStructure in StructureHelper.php"); + $solarName = null; + } + + $st = new Structure; + $st->structure_id = $structure->structure_id; + $st->structure_name = $info->name; + $st->corporation_id = $info->owner_id; + $st->solar_system_id = $info->solar_system_id; + $st->solar_system_name = $solarName; + if(isset($info->type_id)) { + $st->type_id = $info->type_id; + } + $st->corporation_id = $structure->corporation_id; + if(isset($structure->services)) { + $st->services = true; + } else { + $st->services = false; + } + if(isset($structure->state)) { + $st->state = $structure->state; + } else { + $st->state = 'None'; + } + if(isset($structure->state_timer_start)) { + $st->state_timer_start = $esi->DecodeDate($structure->state_timer_start); + } + if(isset($structure->state_timer_end)) { + $st->state_timer_end = $esi->DecodeDate($structure->state_timer_end); + } + if(isset($structure->fuel_expires)) { + $st->fuel_expires = $esi->DecodeDate($structure->fuel_expires); + } + $st->profile_id = $structure->profile_id; + $st->position_x = $info->position->x; + $st->position_y = $info->position->y; + $st->position_z = $info->position->z; + if(isset($structure->next_reinforce_apply)) { + $st->next_reinforce_apply = $esi->DecodeDate($structure->next_reinforce_apply); + } + if(isset($structure->next_reinforce_hour)) { + $st->next_reinforce_hour = $structure->next_reinforce_hour; + } + if(isset($structure->next_reinforce_weekday)) { + $st->next_reinforce_weekday = $structure->next_reinforce_weekday; + } + $st->reinforce_hour = $structure->reinforce_hour; + if(isset($structure->reinforce_weekday)) { + $st->reinforce_weekday = $structure->reinforce_weekday; + } + if(isset($structure->unanchors_at)) { + $daTi = $esi->DecodeDate($structure->unanchors_at); + $st->unanchors_at = $daTi; + } + + //Save the database record + $st->save(); + + if($st->services == true) { + foreach($structure->services as $service) { + $serv = new Service; + $serv->structure_id = $structure->structure_id; + $serv->name = $service->name; + $serv->state = $service->state; + } + } + } + + public function GetStructuresByType($type) { + //Declare variable + $lookup = new LookupHelper; + + $sType = $lookup->StructureNameToTypeId($type); + + $structures = Structure::where([ + 'type_id' => $sType, + ])->get(); + + return $structures; + } +} + +?> \ No newline at end of file diff --git a/app/Library/Helpers/TaxesHelper.php b/app/Library/Helpers/TaxesHelper.php new file mode 100644 index 0000000..9ec81da --- /dev/null +++ b/app/Library/Helpers/TaxesHelper.php @@ -0,0 +1,182 @@ +corpId = $corp; + $this->refType = $ref; + $this->start = $st; + $this->end = $en; + } + + public function GetMoonRentalTaxesGross($start, $end) { + $revenue = 0.00; + + $revenue = AllianceMoonRental::whereBetween('rental_start', [$start, $end]) + ->sum('rental_amount'); + + return $revenue; + } + + public function GetMoonMiningTaxesGross($start, $end) { + $revenue = 0.00; + + $revenue = Invoice::where([ + 'status' => 'Paid', + ])->whereBetween('date_issued', [$start, $end]) + ->sum('invoice_amount'); + + return $revenue; + } + + public function GetMoonMiningTaxesLateGross($start, $end) { + $revenue = 0.00; + + $revenue = Invoice::where([ + 'status' => 'Paid Late', + ])->whereBetween('date_issued', [$start, $end])->sum('invoice_amount'); + + return $revenue; + } + + public function GetAllianceMarketGross($start, $end) { + $revenue = 0.00; + + $revenue = AllianceWalletJournal::where([ + 'ref_type' => 'brokers_fee', + ])->whereBetween('date', [$start, $end]) + ->sum('amount'); + + return $revenue; + } + + public function GetJumpGateGross($start, $end) { + $revenue = 0.00; + + $revenue = AllianceWalletJournal::where([ + 'ref_type' => 'structure_gate_jump', + ])->whereBetween('date', [$start, $end]) + ->sum('amount'); + + return $revenue; + } + + public function GetIndustryGross($start, $end) { + $revenue = 0.00; + + $revenue = AllianceWalletJournal::where([ + 'ref_type' => 'industry_job_tax', + ])->whereBetween('date', [$start, $end]) + ->sum('amount'); + + return $revenue; + } + + public function GetReprocessingGross($start, $end) { + $revenue = 0.00; + + $revenue = AllianceWalletJournal::where([ + 'ref_type' => 'reprocessing_tax', + ])->whereBetween('date', [$start, $end]) + ->sum('amount'); + + return $revenue; + } + + public function GetPIGross($start, $end) { + $revenueImport = 0.00; + $revenueExport = 0.00; + + //Get the import revenue from the database + $revenueImport = AllianceWalletJournal::where([ + 'ref_type' => 'planetary_import_tax', + ])->whereBetween('date', [$start, $end]) + ->sum('amount'); + + //Get the export revenue from the database + $revenueExport = AllianceWalletJournal::where([ + 'ref_type' => 'planetary_export_tax', + ])->whereBetween('date', [$start, $end]) + ->sum('amount'); + + //Total up the two values + $finalRevenue = $revenueImport + $revenueExport; + + //Return the values + return $finalRevenue; + } + + public function GetOfficeGross($start, $end) { + $revenue = 0.00; + + $revenue = AllianceWalletJournal::where([ + 'ref_type' => 'office_rental_fee', + ])->whereBetween('date', [$start, $end]) + ->sum('amount'); + + return $revenue; + } + + /** + * Returns a set of dates from now until the amount of months has passed + * + * @var integer + * @returns array + */ + public function GetTimeFrameInMonths($months) { + //Declare an array of dates + $dates = array(); + //Setup the start of the array as the basis of our start and end dates + $start = Carbon::now()->startOfMonth(); + $end = Carbon::now()->endOfMonth(); + $end->hour = 23; + $end->minute = 59; + $end->second = 59; + + if($months == 1) { + $dates = [ + 'start' => $start, + 'end' => $end, + ]; + + return $dates; + } + + //Create an array of dates + for($i = 0; $i < $months; $i++) { + if($i == 0) { + $dates[$i]['start'] = $start; + $dates[$i]['end'] = $end; + } + + $start = Carbon::now()->startOfMonth()->subMonths($i); + $end = Carbon::now()->endOfMonth()->subMonths($i); + $end->hour = 23; + $end->minute = 59; + $end->second = 59; + $dates[$i]['start'] = $start; + $dates[$i]['end'] = $end; + } + + //Return the dates back to the calling function + return $dates; + } +} \ No newline at end of file diff --git a/app/Library/Login/LoginHelper.php b/app/Library/Login/LoginHelper.php new file mode 100644 index 0000000..599f57b --- /dev/null +++ b/app/Library/Login/LoginHelper.php @@ -0,0 +1,330 @@ + $user->id])->count(); + + //Check to see if the new character being added is already a main character + $mainCount = User::where(['character_id' => $user->id])->count(); + + //If not already in the database, then add the new character + if($altCount == 0 && $mainCount == 0) { + //Create the new alt in the table + $newAlt = new UserAlt; + $newAlt->name = $user->getName(); + $newAlt->main_id = $orgCharacter; + $newAlt->character_id = $user->id; + $newAlt->avatar = $user->avatar; + $newAlt->access_token = $user->token; + $newAlt->owner_hash = $user->owner_hash; + $newAlt->inserted_at = time(); + $newAlt->expires_in = $user->expiresIn; + $newAlt->save(); + + //Create the entry into the EsiToken table + if(EsiToken::where(['character_id' => $user->id])->count() == 0) { + $this->SaveEsiToken($user); + } else { + $this->UpdateEsiToken($user); + } + + //Create the entry into the EsiScopes table + if(sizeof($user->scopes) > 1) { + $this->SetScopes($user->scopes, $user->id); + } + //Return the successfull conclusion of the function + return 1; + } else { + //Return the unsuccessfull conclusion of the function + return 0; + } + } + + /** + * Check if a user exists in the database and return the user object. + * + * @param \Laravel\Socialite\User $user + */ + private function createOrGetUser($eveUser) { + $authUser = null; + + //Search to see if we have a matching user in the database. + //At this point we don't care about the information + $userCount = User::where([ + 'character_id' => $eveUser->id, + ])->count(); + + //If the user is found, do more checks to see what type of login we are doing + if($userCount > 0) { + //Search for user in the database + $authUser = User::where([ + 'character_id' => $eveUser->id, + ])->first(); + + //Check to see if the owner has changed + //If the owner has changed, then update their roles and permissions + if($this->OwnerHasChanged($authUser->owner_hash, $eveUser->owner_hash)) { + //Get the right role for the user + $role = $this->GetRole(null, $eveUser->id); + //Set the role for the user + $this->SetRole($role, $eveUser->id); + + //Update the user information never the less. + $this->UpdateUser($eveUser, $role); + + //Update the user's roles and permission + $this->UpdatePermission($eveUser, $role); + } + + //Return the user to the calling auth function + return $authUser; + } else { + //Get the role for the character to be stored in the database + $role = $this->GetRole(null, $eveUser->id); + + //Create the user account + $user = $this->CreateNewUser($eveUser); + + //Set the role for the user + $this->SetRole($role, $eveUser->id); + + //Create a user account + return $user; + } + } + + /** + * Update the ESI Token + * + * @return null + */ + private function UpdateEsiToken($eveUser) { + EsiToken::where('character_id', $eveUser->id->update([ + 'character_id' => $eveUser->getId(), + 'access_token' => $eveUser->token, + 'refresh_token' => $eveUser->refreshToken, + 'inserted_at' => time(), + 'expires_in' => $eveuser->expiresIn, + ])); + } + + /** + * Create a new ESI Token in the database + * + * @return null + */ + private function SaveEsiToken($eveUser) { + $token = new EsiToken; + $token->character_id = $eveUser->id; + $token->access_token = $eveUser->token; + $token->refresh_token = $eveUser->refreshToken; + $token->inserted_at = time(); + $token->expires_in = $eveUser->expiresIn; + $token->save(); + } + + /** + * Update avatar + */ + private function UpdateAvatar($eveUser) { + User::where('character_id', $eveUser->id)->update([ + 'avatar' => $eveUser->avatar, + ]); + } + + /** + * Update user permission + */ + private function UpdatePermission($eveUser, $role) { + UserPermission::where(['character_id' => $eveUser->id])->delete(); + $perm = new UserPermission(); + $perm->character_id = $eveUser->id; + $perm->permission = $role; + $perm->save(); + } + + /** + * Update the user + */ + private function UpdateUser($eveUser, $role) { + User::where('character_id', $eveUser->id)->update([ + 'avatar' => $eveUser->avatar, + 'owner_hash' => $eveUser->owner_hash, + 'role' => $role, + ]); + } + + /** + * Create a new user account + */ + private function CreateNewUser($eveUser) { + $user = User::create([ + 'name' => $eveUser->getName(), + 'avatar' => $eveUser->avatar, + 'owner_hash' => $eveUser->owner_hash, + 'character_id' => $eveUser->getId(), + 'inserted_at' => time(), + 'expires_in' => $eveUser->expiresIn, + 'user_type' => $this->GetAccountType(null, $eveUser->id), + ]); + + //Look for an existing token for the characters + $tokenFound = EsiToken::where([ + 'character_id' => $eveUser->id, + ])->count(); + + if($tokenFound == 0) { + $token = new EsiToken; + $token->character_id = $eveUser->id; + $token->access_token = $eveUser->token; + $token->refresh_token = $eveUser->refreshToken; + $token->inserted_at = time(); + $token->expires_in = $eveUser->expiresIn; + $token->save(); + } else { + EsiToken::where([ + 'character_id' => $eveUser->id, + ])->update([ + 'character_id' => $eveUser->id, + 'access_token' => $eveUser->token, + 'refresh_token' => $eveUser->refreshToken, + 'inserted_at' => time(), + 'expires_in' => $eveUser->expiresIn, + ]); + } + + return $user; + } + + /** + * Set the user role in the database + * + * @param role + * @param charId + */ + private function SetRole($role, $charId) { + $permission = new UserRole; + $permission->character_id = $charId; + $permission->role = $role; + $permission->save(); + } + + /** + * Set the user scopes in the database + * + * @param scopes + * @param charId + */ + private function SetScopes($scopes, $charId) { + //Delete the current scopes, so we can add new scopes into the database + EsiScope::where('character_id', $charId)->delete(); + foreach($scopes as $scope) { + $data = new EsiScope; + $data->character_id = $charId; + $data->scope = $scope; + $data->save(); + } + } + + /** + * Get the current owner hash, and compare it with the new owner hash + * + * @param hash + * @param charId + */ + private function OwnerHasChanged($hash, $newHash) { + if($hash === $newHash) { + return false; + } else { + return true; + } + } + + /** + * Get the account type and returns it + * + * @param refreshToken + * @param character_id + */ + private function GetRole($refreshToken, $charId) { + $accountType = $this->GetAccountType($refreshToken, $charId); + if($accountType == 'Guest') { + $role = 'Guest'; + } else if($accountType == 'Legacy'){ + $role = 'User'; + } else if($accountType == 'W4RP') { + $role = 'User'; + } elseif($accountType == 'Renter') { + $role = 'Renter'; + } else { + $role = 'None'; + } + + return $role; + } + + /** + * Gets the appropriate account type the user should be assigned through ESI API + * + * @param refreshToken + * @param charId + * + * @return text + */ + private function GetAccountType($refreshToken, $charId) { + //Declare some variables + $esiHelper = new Esi; + $lookup = new LookupHelper; + + //Instantiate a new ESI isntance + $esi = $esiHelper->SetupEsiAuthentication(); + + //Set caching to null + $configuration = Configuration::getInstance(); + $configuration->cache = NullCache::class; + + //Get the character information + $character_info = $lookup->GetCharacterInfo($charId); + + //Get the corporation information + $corp_info = $lookup->GetCorporationInfo($character_info->corporation_id); + + if($character_info == null || $corp_info == null) { + return redirect('/')->with('error', 'Could not create user at this time.'); + } + + $legacy = AllowedLogin::where(['login_type' => 'Legacy'])->pluck('entity_id')->toArray(); + $renter = AllowedLogin::where(['login_type' => 'Renter'])->pluck('entity_id')->toArray(); + + //Send back the appropriate group + if(isset($corp_info->alliance_id)) { + if($corp_info->alliance_id == '99004116') { + return 'W4RP'; + } else if(in_array($corp_info->alliance_id, $legacy)) { + return 'Legacy'; + } else if(in_array($corp_info->alliance_id, $renter)) { + return 'Renter'; + } else { + return 'Guest'; + } + } else { + return 'None'; + } + } +} + +?> \ No newline at end of file diff --git a/app/Library/Moons/MoonCalc.php b/app/Library/Moons/MoonCalc.php new file mode 100644 index 0000000..92bac0f --- /dev/null +++ b/app/Library/Moons/MoonCalc.php @@ -0,0 +1,626 @@ + $ore, + ])->first(); + + return $composition; + } + + /** + * Calculate the total worth of a moon + */ + public function MoonTotalWorth($firstOre = null, $firstQuan = 0.00, $secondOre = null, $secondQuan = 0.00, $thirdOre = null, $thirdQuan = 0.00, $fourthOre = null, $fourthQuan = 0.00) { + //Declare variables + $total = 0.00; + + //Convert the quantities into numbers we want to utilize + $this->ConvertPercentages($firstQuan, $secondQuan, $thirdQuan, $fourthQuan); + + //Calculate the prices from the ores + if($firstOre != null) { + $total += $this->CalcMoonPrice($firstOre, $firstQuan); + } + if($secondOre != null) { + $total += $this->CalcMoonPrice($secondOre, $secondQuan); + } + if($thirdOre != null) { + $total += $this->CalcMoonPrice($thirdOre, $thirdQuan); + } + if($fourthOre != null) { + $total += $this->CalcMoonPrice($fourthOre, $fourthQuan); + } + + //Return the rental price to the caller + return $total; + } + + /** + * Fetch new prices for items from the market + */ + public function FetchNewPrices() { + //Create the item id array which we will pull data for from Fuzzwork market api + $ItemIDs = array( + "Tritanium" => 34, + "Pyerite" => 35, + "Mexallon" => 36, + "Isogen" => 37, + "Nocxium" => 38, + "Zydrine" => 39, + "Megacyte" => 40, + "Morphite" => 11399, + "HeliumIsotopes" => 16274, + "NitrogenIsotopes" => 17888, + "OxygenIsotopes" => 17887, + "HydrogenIsotopes" => 17889, + "LiquidOzone" => 16273, + "HeavyWater" => 16272, + "StrontiumClathrates" => 16275, + "AtmosphericGases" => 16634, + "EvaporiteDeposits" => 16635, + "Hydrocarbons" => 16633, + "Silicates" => 16636, + "Cobalt" => 16640, + "Scandium" => 16639, + "Titanium" => 16638, + "Tungsten" => 16637, + "Cadmium" => 16643, + "Platinum" => 16644, + "Vanadium" => 16642, + "Chromium" => 16641, + "Technetium" => 16649, + "Hafnium" => 16648, + "Caesium" => 16647, + "Mercury" => 16646, + "Dysprosium" => 16650, + "Neodymium" => 16651, + "Promethium" => 16652, + "Thulium" => 16653, + ); + + //Create the time variable + $time = Carbon::now(); + + //Get the json data for each ItemId from https://market.fuzzwork.co.uk/api/ + //Base url is https://market.fuzzwork.co.uk/aggregates/?region=10000002&types=34 + //Going to use curl for these requests + foreach($ItemIDs as $key => $value) { + //Declare a new array each time we cycle through the for loop for the item + $item = array(); + + //Setup the guzzle client fetch object + $client = new Client(['base_uri' => 'https://market.fuzzwork.co.uk/aggregates/']); + //Setup the uri for the guzzle client + $uri = '?region=10000002&types=' . $value; + //Get the result from the guzzle client request + $result = $client->request('GET', $uri); + //Decode the request into an array from the json body return + $item = json_decode($result->getBody(), true); + + //Save the entry into the database + $price = new MineralPrice; + $price->Name = $key; + $price->ItemId = $value; + $price->Price = $item[$value]['sell']['median']; + $price->Time = $time; + $price->save(); + } + + //Run the update for the item pricing + $this->UpdateItemPricing(); + } + + /** + * Calculate the ore units + */ + public function CalcOreUnits($ore, $percentage) { + //Specify the total pull amount + $totalPull = 5.55 * (3600.00 * 24.00 *30.00); + + //Find the size of the asteroid from the database + $item = ItemComposition::where([ + 'Name' => $ore, + ])->first(); + + //Get the m3 size from the item composition + $m3Size = $item->m3Size; + + //Calculate the actual m3 from the total pull amount in m3 using the percentage of the ingredient + $actualm3 = floor($totalPull * $percentage); + + //Calculate the units from the m3 pulled from the moon + $units = floor($actualm3 / $m3Size); + + //Return the calculated data + return $units; + } + + /** + * Calculate the per item price of a unit of ore + */ + public function CalculateOrePrice($oreId) { + //Declare variables + $lookupHelper = new LookupHelper; + $finalName = null; + + $pastTime = Carbon::now()->subDays(30); + + //Get the price of the moongoo + $tritaniumPrice = MineralPrice::where(['ItemId' => 34])->where('Time', '>', $pastTime)->avg('Price'); + $pyeritePrice = MineralPrice::where(['ItemId' => 35])->where('Time', '>', $pastTime)->avg('Price'); + $mexallonPrice = MineralPrice::where(['ItemId' => 36])->where('Time', '>', $pastTime)->avg('Price'); + $isogenPrice = MineralPrice::where(['ItemId' => 37])->where('Time', '>', $pastTime)->avg('Price'); + $nocxiumPrice = MineralPrice::where(['ItemId' => 38])->where('Time', '>', $pastTime)->avg('Price'); + $zydrinePrice = MineralPrice::where(['ItemId' => 39])->where('Time', '>', $pastTime)->avg('Price'); + $megacytePrice = MineralPrice::where(['ItemId' => 40])->where('Time', '>', $pastTime)->avg('Price'); + $atmosphericGasesPrice = MineralPrice::where(['ItemId' => 16634])->where('Time', '>', $pastTime)->avg('Price'); + $evaporiteDepositsPirce = MineralPrice::where(['ItemId' => 16635])->where('Time', '>', $pastTime)->avg('Price'); + $hydrocarbonsPrice = MineralPrice::where(['ItemId' => 16633])->where('Time', '>', $pastTime)->avg('Price'); + $silicatesPrice = MineralPrice::where(['ItemId' => 16636])->where('Time', '>', $pastTime)->avg('Price'); + $cobaltPrice = MineralPrice::where(['ItemId' => 16640])->where('Time', '>', $pastTime)->avg('Price'); + $scandiumPrice = MineralPrice::where(['ItemId' => 16639])->where('Time', '>', $pastTime)->avg('Price'); + $titaniumPrice = MineralPrice::where(['ItemId' => 16638])->where('Time', '>', $pastTime)->avg('Price'); + $tungstenPrice = MineralPrice::where(['ItemId' => 16637])->where('Time', '>', $pastTime)->avg('Price'); + $cadmiumPrice = MineralPrice::where(['ItemId' => 16643])->where('Time', '>', $pastTime)->avg('Price'); + $platinumPrice = MineralPrice::where(['ItemId' => 16644])->where('Time', '>', $pastTime)->avg('Price'); + $vanadiumPrice = MineralPrice::where(['ItemId' => 16642])->where('Time', '>', $pastTime)->avg('Price'); + $chromiumPrice = MineralPrice::where(['ItemId' => 16641])->where('Time', '>', $pastTime)->avg('Price'); + $technetiumPrice = MineralPrice::where(['ItemId' => 16649])->where('Time', '>', $pastTime)->avg('Price'); + $hafniumPrice = MineralPrice::where(['ItemId' => 16648])->where('Time', '>', $pastTime)->avg('Price'); + $caesiumPrice = MineralPrice::where(['ItemId' => 16647])->where('Time', '>', $pastTime)->avg('Price'); + $mercuryPrice = MineralPrice::where(['ItemId' => 16646])->where('Time', '>', $pastTime)->avg('Price'); + $dysprosiumPrice = MineralPrice::where(['ItemId' => 16650])->where('Time', '>', $pastTime)->avg('Price'); + $neodymiumPrice = MineralPrice::where(['ItemId' => 16651])->where('Time', '>', $pastTime)->avg('Price'); + $promethiumPrice = MineralPrice::where(['ItemId' => 16652])->where('Time', '>', $pastTime)->avg('Price'); + $thuliumPrice = MineralPrice::where(['ItemId' => 16653])->where('Time', '>', $pastTime)->avg('Price'); + + //Get the name through the lookup table + $oreName = $lookupHelper->ItemIdToName($oreId); + + //Strip the prefix from the ore name if it has one. + //Then change the ore id if necessary + $tempName = explode(' ', $oreName); + + if(sizeof($tempName) == 1) { + $finalName = $tempName[0]; + } else { + $finalName = $tempName[sizeof($tempName) - 1]; + $oreId = $lookupHelper->ItemNameToId($finalName); + } + + //Get the item composition for the ore + $composition = ItemComposition::where('ItemId', $oreId)->first(); + + //Calculate the Batch Price + $batchPrice = ( ($composition->Tritanium * $tritaniumPrice) + + ($composition->Pyerite * $pyeritePrice) + + ($composition->Mexallon * $mexallonPrice) + + ($composition->Isogen * $isogenPrice) + + ($composition->Nocxium * $nocxiumPrice) + + ($composition->Zydrine * $zydrinePrice) + + ($composition->Megacyte * $megacytePrice) + + ($composition->AtmosphericGases * $atmosphericGasesPrice) + + ($composition->EvaporiteDeposits * $evaporiteDepositsPirce) + + ($composition->Hydrocarbons * $hydrocarbonsPrice) + + ($composition->Silicates * $silicatesPrice) + + ($composition->Cobalt * $cobaltPrice) + + ($composition->Scandium * $scandiumPrice) + + ($composition->Titanium * $titaniumPrice) + + ($composition->Tungsten * $tungstenPrice) + + ($composition->Cadmium * $cadmiumPrice) + + ($composition->Platinum * $platinumPrice) + + ($composition->Vanadium * $vanadiumPrice) + + ($composition->Chromium * $chromiumPrice)+ + ($composition->Technetium * $technetiumPrice) + + ($composition->Hafnium * $hafniumPrice) + + ($composition->Caesium * $caesiumPrice) + + ($composition->Mercury * $mercuryPrice) + + ($composition->Dysprosium * $dysprosiumPrice) + + ($composition->Neodymium * $neodymiumPrice) + + ($composition->Promethium * $promethiumPrice) + + ($composition->Thulium * $thuliumPrice)); + + //Take the batch price, and divide by batch size to get unit price + $price = $batchPrice / $composition->BatchSize; + + //Return the price to the calling function + return $price; + } + + /** + * Update item pricing after new prices were pulled + */ + private function UpdateItemPricing() { + //Get the configuration from the config table + $config = DB::table('Config')->first(); + + //Calculate refine rate + $refineRate = $config->RefineRate / 100.00; + + //Calculate the current time + $time = Carbon::now(); + //Calcualate the current time minus 30 days + $pastTime = Carbon::now()->subDays(30); + + //Get the price of the basic minerals + $tritaniumPrice = MineralPrice::where(['ItemId' => 34])->where('Time', '>', $pastTime)->avg('Price'); + $pyeritePrice = MineralPrice::where(['ItemId' => 35])->where('Time', '>', $pastTime)->avg('Price'); + $mexallonPrice = MineralPrice::where(['ItemId' => 36])->where('Time', '>', $pastTime)->avg('Price'); + $isogenPrice = MineralPrice::where(['ItemId' => 37])->where('Time', '>', $pastTime)->avg('Price'); + $nocxiumPrice = MineralPrice::where(['ItemId' => 38])->where('Time', '>', $pastTime)->avg('Price'); + $zydrinePrice = MineralPrice::where(['ItemId' => 39])->where('Time', '>', $pastTime)->avg('Price'); + $megacytePrice = MineralPrice::where(['ItemId' => 40])->where('Time', '>', $pastTime)->avg('Price'); + $morphitePrice = MineralPrice::where(['ItemId' => 11399])->where('Time', '>', $pastTime)->avg('Price'); + $heliumIsotopesPrice = MineralPrice::where(['ItemId' => 16274])->where('Time', '>', $pastTime)->avg('Price'); + $nitrogenIsotopesPrice = MineralPrice::where(['ItemId' => 17888])->where('Time', '>', $pastTime)->avg('Price'); + $oxygenIsotopesPrice = MineralPrice::where(['ItemId' => 17887])->where('Time', '>', $pastTime)->avg('Price'); + $hydrogenIsotopesPrice = MineralPrice::where(['ItemId' => 17889])->where('Time', '>', $pastTime)->avg('Price'); + $liquidOzonePrice = MineralPrice::where(['ItemId' => 16273])->where('Time', '>', $pastTime)->avg('Price'); + $heavyWaterPrice = MineralPrice::where(['ItemId' => 16272])->where('Time', '>', $pastTime)->avg('Price'); + $strontiumClathratesPrice = MineralPrice::where(['ItemId' => 16275])->where('Time', '>', $pastTime)->avg('Price'); + //Get the price of the moongoo + $atmosphericGasesPrice = MineralPrice::where(['ItemId' => 16634])->where('Time', '>', $pastTime)->avg('Price'); + $evaporiteDepositsPirce = MineralPrice::where(['ItemId' => 16635])->where('Time', '>', $pastTime)->avg('Price'); + $hydrocarbonsPrice = MineralPrice::where(['ItemId' => 16633])->where('Time', '>', $pastTime)->avg('Price'); + $silicatesPrice = MineralPrice::where(['ItemId' => 16636])->where('Time', '>', $pastTime)->avg('Price'); + $cobaltPrice = MineralPrice::where(['ItemId' => 16640])->where('Time', '>', $pastTime)->avg('Price'); + $scandiumPrice = MineralPrice::where(['ItemId' => 16639])->where('Time', '>', $pastTime)->avg('Price'); + $titaniumPrice = MineralPrice::where(['ItemId' => 16638])->where('Time', '>', $pastTime)->avg('Price'); + $tungstenPrice = MineralPrice::where(['ItemId' => 16637])->where('Time', '>', $pastTime)->avg('Price'); + $cadmiumPrice = MineralPrice::where(['ItemId' => 16643])->where('Time', '>', $pastTime)->avg('Price'); + $platinumPrice = MineralPrice::where(['ItemId' => 16644])->where('Time', '>', $pastTime)->avg('Price'); + $vanadiumPrice = MineralPrice::where(['ItemId' => 16642])->where('Time', '>', $pastTime)->avg('Price'); + $chromiumPrice = MineralPrice::where(['ItemId' => 16641])->where('Time', '>', $pastTime)->avg('Price'); + $technetiumPrice = MineralPrice::where(['ItemId' => 16649])->where('Time', '>', $pastTime)->avg('Price'); + $hafniumPrice = MineralPrice::where(['ItemId' => 16648])->where('Time', '>', $pastTime)->avg('Price'); + $caesiumPrice = MineralPrice::where(['ItemId' => 16647])->where('Time', '>', $pastTime)->avg('Price'); + $mercuryPrice = MineralPrice::where(['ItemId' => 16646])->where('Time', '>', $pastTime)->avg('Price'); + $dysprosiumPrice = MineralPrice::where(['ItemId' => 16650])->where('Time', '>', $pastTime)->avg('Price'); + $neodymiumPrice = MineralPrice::where(['ItemId' => 16651])->where('Time', '>', $pastTime)->avg('Price'); + $promethiumPrice = MineralPrice::where(['ItemId' => 16652])->where('Time', '>', $pastTime)->avg('Price'); + $thuliumPrice = MineralPrice::where(['ItemId' => 16653])->where('Time', '>', $pastTime)->avg('Price'); + + //Get the item compositions + $items = DB::select('SELECT Name,ItemId FROM ItemComposition'); + //Go through each of the items and update the price + foreach($items as $item) { + //Get the item composition + $composition = ItemComposition::where('ItemId', $item->ItemId)->first(); + + //Calculate the Batch Price + $batchPrice = ( ($composition->Tritanium * $tritaniumPrice) + + ($composition->Pyerite * $pyeritePrice) + + ($composition->Mexallon * $mexallonPrice) + + ($composition->Isogen * $isogenPrice) + + ($composition->Nocxium * $nocxiumPrice) + + ($composition->Zydrine * $zydrinePrice) + + ($composition->Megacyte * $megacytePrice) + + ($composition->Morphite * $morphitePrice) + + ($composition->HeavyWater * $heavyWaterPrice) + + ($composition->LiquidOzone * $liquidOzonePrice) + + ($composition->NitrogenIsotopes * $nitrogenIsotopesPrice) + + ($composition->HeliumIsotopes * $heliumIsotopesPrice) + + ($composition->HydrogenIsotopes * $hydrogenIsotopesPrice) + + ($composition->OxygenIsotopes * $oxygenIsotopesPrice) + + ($composition->StrontiumClathrates * $strontiumClathratesPrice) + + ($composition->AtmosphericGases * $atmosphericGasesPrice) + + ($composition->EvaporiteDeposits * $evaporiteDepositsPirce) + + ($composition->Hydrocarbons * $hydrocarbonsPrice) + + ($composition->Silicates * $silicatesPrice) + + ($composition->Cobalt * $cobaltPrice) + + ($composition->Scandium * $scandiumPrice) + + ($composition->Titanium * $titaniumPrice) + + ($composition->Tungsten * $tungstenPrice) + + ($composition->Cadmium * $cadmiumPrice) + + ($composition->Platinum * $platinumPrice) + + ($composition->Vanadium * $vanadiumPrice) + + ($composition->Chromium * $chromiumPrice)+ + ($composition->Technetium * $technetiumPrice) + + ($composition->Hafnium * $hafniumPrice) + + ($composition->Caesium * $caesiumPrice) + + ($composition->Mercury * $mercuryPrice) + + ($composition->Dysprosium * $dysprosiumPrice) + + ($composition->Neodymium * $neodymiumPrice) + + ($composition->Promethium * $promethiumPrice) + + ($composition->Thulium * $thuliumPrice)); + //Calculate the batch price with the refine rate included + //Batch Price is base price for everything + $batchPrice = $batchPrice * $refineRate; + //Calculate the unit price + $price = $batchPrice / $composition->BatchSize; + //Calculate the m3 price + $m3Price = $price / $composition->m3Size; + + //Check if an item is in the table + $count = OrePrice::where('Name', $composition->Name)->count(); + if($count == 0) { + //If the ore wasn't found, then add a new entry + $ore = new OrePrice; + $ore->Name = $composition->Name; + $ore->ItemId = $composition->ItemId; + $ore->BatchPrice = $batchPrice; + $ore->UnitPrice = $price; + $ore->m3Price = $m3Price; + $ore->Time = $time; + $ore->save(); + } else { + //Update the prices in the Prices table + OrePrice::where('Name', $composition->Name)->update([ + 'Name' => $composition->Name, + 'ItemId' => $composition->ItemId, + 'BatchPrice' => $batchPrice, + 'UnitPrice' => $price, + 'm3Price' => $m3Price, + 'Time' => $time, + ]); + } + } + } + + /** + * Calculate the total amount pulled from a moon + */ + private function CalculateTotalMoonPull() { + //Always assume a 1 month pull which equates to 5.55m3 per second or 2,592,000 seconds + //Total pull size is 14,385,600 m3 + $totalPull = 5.55 * 3600.00 * 24.00 *30.00; + + //Return the total pull + return $totalPull; + } + + /** + * Calculate the rental price of a moon ore from the moon + */ + private function CalcRentalPrice($ore, $percentage) { + //Specify the total pull amount + $totalPull = $this->CalculateTotalMoonPull(); + + //Setup the total value at 0.00 + $totalPrice = 0.00; + + //Check to see what type of moon goo the moon is + $gasMoonOre = $this->IsGasMoonGoo($ore); + + //Find the size of the asteroid from the database + $m3Size = DB::table('ItemComposition')->where('Name', $ore)->value('m3Size'); + + //Calculate the actual m3 from the total pull amount in m3 using the percentage of the ingredient + $actualm3 = floor($percentage * $totalPull); + + //Calculate the units once we have the size and actual m3 value + $units = floor($actualm3 / $m3Size); + + //Look up the unit price from the database + $unitPrice = DB::table('ore_prices')->where('Name', $ore)->value('UnitPrice'); + + //If the ore is a gas ore, then take only 50% of the price. + if($gasMoonOre == true) { + $totalPrice = $units * ($unitPrice / 2.00); + Log::warning('Found gas ore: ' . $totalPrice); + } else { + $totalPrice = $units * $unitPrice; + } + + //Return the total + return $totalPrice; + } + + /** + * Calculate the moon's total price + */ + public function CalcMoonPrice($ore, $percentage) { + //Specify the total pull amount + $totalPull = $this->CalculateTotalMoonPull(); + + //Setup the total value at 0.00 + $totalPrice = 0.00; + + //Find the size of the asteroid from the database + $m3Size = DB::table('ItemComposition')->where('Name', $ore)->value('m3Size'); + + //Calculate the actual m3 from the total pull amount in m3 using the percentage of the ingredient + $actualm3 = floor($percentage * $totalPull); + + //Calculate the units once we have the size and actual m3 value + $units = floor($actualm3 / $m3Size); + + //Look up the unit price from the database + $unitPrice = DB::table('ore_prices')->where('Name', $ore)->value('UnitPrice'); + + //Calculate the total amount from the units and the unit price. + $totalPrice = $units * $unitPrice; + + //Return the value + return $totalPrice; + } + + /** + * Convert a number to a percentage + */ + private function ConvertToPercentage($quantity) { + //Perform the calculation and return the data + return $quantity / 100.00; + } + + /** + * Return if a type of ore is a gas moon goo + */ + private function IsGasMoonGoo($ore) { + $ores = [ + 'Zeolites' => 'Gas', + 'Sylvite' => 'Gas', + 'Bitumens' => 'Gas', + 'Coesite' => 'Gas', + ]; + + foreach($ores as $key => $value) { + if(strtolower($key) == strtolower($ore)) { + return $value; + } + } + + return false; + } + + /** + * Return the type of ore a particular moon ore is. + */ + public function IsRMoonGoo($ore) { + $ores = [ + 'Zeolites' => 'R4', + 'Sylvite' => 'R4', + 'Bitumens' => 'R4', + 'Coesite' => 'R4', + 'Cobaltite' => 'R8', + 'Euxenite' => 'R8', + 'Titanite' => 'R8', + 'Scheelite' => 'R8', + 'Otavite' => 'R16', + 'Sperrylite' => 'R16', + 'Vanadinite' => 'R16', + 'Chromite' => 'R16', + 'Carnotite' => 'R32', + 'Zircon' => 'R32', + 'Pollucite' => 'R32', + 'Cinnabar' => 'R32', + 'Xenotime' => 'R64', + 'Monazite' => 'R64', + 'Loparite' => 'R64', + 'Ytterbite' => 'R64', + ]; + + foreach($ores as $key => $value) { + if(strtolower($key) == strtolower($ore)) { + return $value; + } + } + + //Return false if the ore is not found in an array + return false; + } + + /** + * Return true if a moon ore is a moon ore, and false + * if the ore is not a moon ore. + */ + public function IsRMoonOre($ore) { + $ores = [ + 'Zeolites' => 'R4', + 'Sylvite' => 'R4', + 'Bitumens' => 'R4', + 'Coesite' => 'R4', + 'Cobaltite' => 'R8', + 'Euxenite' => 'R8', + 'Titanite' => 'R8', + 'Scheelite' => 'R8', + 'Otavite' => 'R16', + 'Sperrylite' => 'R16', + 'Vanadinite' => 'R16', + 'Chromite' => 'R16', + 'Carnotite' => 'R32', + 'Zircon' => 'R32', + 'Pollucite' => 'R32', + 'Cinnabar' => 'R32', + 'Xenotime' => 'R64', + 'Monazite' => 'R64', + 'Loparite' => 'R64', + 'Ytterbite' => 'R64', + ]; + + foreach($ores as $key => $value) { + + if(strtolower($key) == strtolower($ore)) { + return true; + } + } + + return false; + } + + /** + * Convert percentages from quantities into a normalized percentage + */ + public function ConvertPercentages(&$firstPerc, &$secondPerc, &$thirdPerc, &$fourthPerc) { + //Convert the quantities into numbers we want to utilize + if($firstPerc >= 1.00) { + $firstPerc = $this->ConvertToPercentage($firstPerc); + } + + if($secondPerc >= 1.00) { + $secondPerc = $this->ConvertToPercentage($secondPerc); + } + + if($thirdPerc >= 1.00) { + $thirdPerc = $this->ConvertToPercentage($thirdPerc); + } + + if($fourthPerc >= 1.00) { + $fourthPerc = $this->ConvertToPercentage($fourthPerc); + } + + + //Add up all the percentages + $totalPerc = $firstPerc + $secondPerc + $thirdPerc + $fourthPerc; + + //If it is less than 1.00, then we need to normalize the decimal to be 100.0%. + if($totalPerc < 1.00) { + if($firstPerc > 0.00) { + $firstPerc = $firstPerc / $totalPerc; + } else { + $firstPerc = 0.00; + } + + if($secondPerc > 0.00) { + $secondPerc = $secondPerc / $totalPerc; + } else { + $secondPerc = 0.00; + } + + if($thirdPerc > 0.00) { + $thirdPerc = $thirdPerc / $totalPerc; + } else { + $thirdPerc = 0.00; + } + + if($fourthPerc > 0.00) { + $fourthPerc = $fourthPerc / $totalPerc; + } else { + $fourthPerc = 0.00; + } + } + } +} \ No newline at end of file diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 452e6b6..a6912c8 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -12,6 +12,14 @@ class AppServiceProvider extends ServiceProvider public function register(): void { // + /** + * Eve Online Socialite Provider registration + * + * Event::listen(function (\SocialiteProviders\Manager\SocialiteWasCalled $event) { + * $event->extendSocialite('eveonline', \SocialiteProviders\Eveonline\Provider::class); + * }); + */ + } /** diff --git a/composer.json b/composer.json index 52a3a8a..92e7897 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,9 @@ "require": { "php": "^8.2", "laravel/framework": "^12.0", - "laravel/tinker": "^2.10.1" + "laravel/horizon": "^5.44", + "laravel/tinker": "^2.10.1", + "socialiteproviders/eveonline": "^4.4" }, "require-dev": { "fakerphp/faker": "^1.23", diff --git a/composer.lock b/composer.lock index dd1ef44..d5a5661 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "c514d8f7b9fc5970bdd94287905ef584", + "content-hash": "9abf5d0f046d00e112328cc59a6ee96c", "packages": [ { "name": "brick/math", @@ -508,6 +508,69 @@ ], "time": "2025-03-06T22:45:56+00:00" }, + { + "name": "firebase/php-jwt", + "version": "v7.0.2", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/5645b43af647b6947daac1d0f659dd1fbe8d3b65", + "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.4", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", + "psr/cache": "^2.0||^3.0", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0" + }, + "suggest": { + "ext-sodium": "Support EdDSA (Ed25519) signatures", + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v7.0.2" + }, + "time": "2025-12-16T22:17:28+00:00" + }, { "name": "fruitcake/php-cors", "version": "v1.4.0", @@ -1274,6 +1337,85 @@ }, "time": "2026-02-17T17:07:04+00:00" }, + { + "name": "laravel/horizon", + "version": "v5.44.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/horizon.git", + "reference": "00c21e4e768112cce3f4fe576d75956dfc423de2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/horizon/zipball/00c21e4e768112cce3f4fe576d75956dfc423de2", + "reference": "00c21e4e768112cce3f4fe576d75956dfc423de2", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcntl": "*", + "ext-posix": "*", + "illuminate/contracts": "^9.21|^10.0|^11.0|^12.0|^13.0", + "illuminate/queue": "^9.21|^10.0|^11.0|^12.0|^13.0", + "illuminate/support": "^9.21|^10.0|^11.0|^12.0|^13.0", + "nesbot/carbon": "^2.17|^3.0", + "php": "^8.0", + "ramsey/uuid": "^4.0", + "symfony/console": "^6.0|^7.0|^8.0", + "symfony/error-handler": "^6.0|^7.0|^8.0", + "symfony/polyfill-php83": "^1.28", + "symfony/process": "^6.0|^7.0|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^7.55|^8.36|^9.15|^10.8|^11.0", + "phpstan/phpstan": "^1.10|^2.0", + "predis/predis": "^1.1|^2.0|^3.0" + }, + "suggest": { + "ext-redis": "Required to use the Redis PHP driver.", + "predis/predis": "Required when not using the Redis PHP driver (^1.1|^2.0|^3.0)." + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Horizon": "Laravel\\Horizon\\Horizon" + }, + "providers": [ + "Laravel\\Horizon\\HorizonServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\Horizon\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Dashboard and code-driven configuration for Laravel queues.", + "keywords": [ + "laravel", + "queue" + ], + "support": { + "issues": "https://github.com/laravel/horizon/issues", + "source": "https://github.com/laravel/horizon/tree/v5.44.0" + }, + "time": "2026-02-10T18:18:08+00:00" + }, { "name": "laravel/prompts", "version": "v0.3.13", @@ -1394,6 +1536,78 @@ }, "time": "2026-02-03T06:55:34+00:00" }, + { + "name": "laravel/socialite", + "version": "v5.24.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/socialite.git", + "reference": "5cea2eebf11ca4bc6c2f20495c82a70a9b3d1613" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/socialite/zipball/5cea2eebf11ca4bc6c2f20495c82a70a9b3d1613", + "reference": "5cea2eebf11ca4bc6c2f20495c82a70a9b3d1613", + "shasum": "" + }, + "require": { + "ext-json": "*", + "firebase/php-jwt": "^6.4|^7.0", + "guzzlehttp/guzzle": "^6.0|^7.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/http": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "league/oauth1-client": "^1.11", + "php": "^7.2|^8.0", + "phpseclib/phpseclib": "^3.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^4.18|^5.20|^6.47|^7.55|^8.36|^9.15|^10.8", + "phpstan/phpstan": "^1.12.23", + "phpunit/phpunit": "^8.0|^9.3|^10.4|^11.5|^12.0" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "Socialite": "Laravel\\Socialite\\Facades\\Socialite" + }, + "providers": [ + "Laravel\\Socialite\\SocialiteServiceProvider" + ] + }, + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\Socialite\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.", + "homepage": "https://laravel.com", + "keywords": [ + "laravel", + "oauth" + ], + "support": { + "issues": "https://github.com/laravel/socialite/issues", + "source": "https://github.com/laravel/socialite" + }, + "time": "2026-01-10T16:07:28+00:00" + }, { "name": "laravel/tinker", "version": "v2.11.1", @@ -1837,6 +2051,82 @@ ], "time": "2024-09-21T08:32:55+00:00" }, + { + "name": "league/oauth1-client", + "version": "v1.11.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth1-client.git", + "reference": "f9c94b088837eb1aae1ad7c4f23eb65cc6993055" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/f9c94b088837eb1aae1ad7c4f23eb65cc6993055", + "reference": "f9c94b088837eb1aae1ad7c4f23eb65cc6993055", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "guzzlehttp/psr7": "^1.7|^2.0", + "php": ">=7.1||>=8.0" + }, + "require-dev": { + "ext-simplexml": "*", + "friendsofphp/php-cs-fixer": "^2.17", + "mockery/mockery": "^1.3.3", + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5||9.5" + }, + "suggest": { + "ext-simplexml": "For decoding XML-based responses." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev", + "dev-develop": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "League\\OAuth1\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Corlett", + "email": "bencorlett@me.com", + "homepage": "http://www.webcomm.com.au", + "role": "Developer" + } + ], + "description": "OAuth 1.0 Client Library", + "keywords": [ + "Authentication", + "SSO", + "authorization", + "bitbucket", + "identity", + "idp", + "oauth", + "oauth1", + "single sign on", + "trello", + "tumblr", + "twitter" + ], + "support": { + "issues": "https://github.com/thephpleague/oauth1-client/issues", + "source": "https://github.com/thephpleague/oauth1-client/tree/v1.11.0" + }, + "time": "2024-12-10T19:59:05+00:00" + }, { "name": "league/uri", "version": "7.8.0", @@ -2528,6 +2818,125 @@ ], "time": "2026-02-16T23:10:27+00:00" }, + { + "name": "paragonie/constant_time_encoding", + "version": "v3.1.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", + "shasum": "" + }, + "require": { + "php": "^8" + }, + "require-dev": { + "infection/infection": "^0", + "nikic/php-fuzzer": "^0", + "phpunit/phpunit": "^9|^10|^11", + "vimeo/psalm": "^4|^5|^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2025-09-24T15:06:41+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, { "name": "phpoption/phpoption", "version": "1.9.5", @@ -2603,6 +3012,116 @@ ], "time": "2025-12-27T19:41:33+00:00" }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.49", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "6233a1e12584754e6b5daa69fe1289b47775c1b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/6233a1e12584754e6b5daa69fe1289b47775c1b9", + "reference": "6233a1e12584754e6b5daa69fe1289b47775c1b9", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2|^3", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.49" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2026-01-27T09:17:28+00:00" + }, { "name": "psr/clock", "version": "1.0.0", @@ -3292,6 +3811,131 @@ }, "time": "2025-12-14T04:43:48+00:00" }, + { + "name": "socialiteproviders/eveonline", + "version": "4.4.0", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/Eveonline.git", + "reference": "5472f8701385e9aa50da1bc24504c6aa0081d5bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/Eveonline/zipball/5472f8701385e9aa50da1bc24504c6aa0081d5bd", + "reference": "5472f8701385e9aa50da1bc24504c6aa0081d5bd", + "shasum": "" + }, + "require": { + "ext-json": "*", + "firebase/php-jwt": "^7.0", + "php": "^8.0", + "socialiteproviders/manager": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "SocialiteProviders\\Eveonline\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Gerstenberg", + "email": "grasume0@gmail.com" + } + ], + "description": "Eveonline OAuth2 Provider for Laravel Socialite", + "keywords": [ + "eveonline", + "laravel", + "oauth", + "provider", + "socialite" + ], + "support": { + "docs": "https://socialiteproviders.com/eveonline", + "issues": "https://github.com/socialiteproviders/providers/issues", + "source": "https://github.com/socialiteproviders/providers" + }, + "time": "2026-02-18T14:40:47+00:00" + }, + { + "name": "socialiteproviders/manager", + "version": "v4.8.1", + "source": { + "type": "git", + "url": "https://github.com/SocialiteProviders/Manager.git", + "reference": "8180ec14bef230ec2351cff993d5d2d7ca470ef4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/8180ec14bef230ec2351cff993d5d2d7ca470ef4", + "reference": "8180ec14bef230ec2351cff993d5d2d7ca470ef4", + "shasum": "" + }, + "require": { + "illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0 || ^12.0", + "laravel/socialite": "^5.5", + "php": "^8.1" + }, + "require-dev": { + "mockery/mockery": "^1.2", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "SocialiteProviders\\Manager\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "SocialiteProviders\\Manager\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andy Wendt", + "email": "andy@awendt.com" + }, + { + "name": "Anton Komarev", + "email": "a.komarev@cybercog.su" + }, + { + "name": "Miguel Piedrafita", + "email": "soy@miguelpiedrafita.com" + }, + { + "name": "atymic", + "email": "atymicq@gmail.com", + "homepage": "https://atymic.dev" + } + ], + "description": "Easily add new or override built-in providers in Laravel Socialite.", + "homepage": "https://socialiteproviders.com", + "keywords": [ + "laravel", + "manager", + "oauth", + "providers", + "socialite" + ], + "support": { + "issues": "https://github.com/socialiteproviders/manager/issues", + "source": "https://github.com/socialiteproviders/manager" + }, + "time": "2025-02-24T19:33:30+00:00" + }, { "name": "symfony/clock", "version": "v7.4.0", diff --git a/config/services.php b/config/services.php index 6a90eb8..bfa78c5 100644 --- a/config/services.php +++ b/config/services.php @@ -35,4 +35,10 @@ return [ ], ], + 'eveonline' => [ + 'client_id' => env('EVEONLINE_CLIENT_ID'), + 'client_secret' => env('EVEONLINE_SECRET_KEY'), + 'redirect' => env('EVEONLINE_REDIRECT_URL'), + ], + ];