/** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @param Guard $guard * @param SpotService $spotService * @return Response */ public function store(Request $request, Guard $guard, SpotService $spotService) { $response = new \stdClass(); $code = 200; if ($spot = $spotService->create($guard->getUser()->id, $request->input('msw_spot_id'), $request->input('name'), $request->input('public'))) { $response = $spot; } else { $response->errors = $spotService->getErrors(); $code = 400; } return (new Response(json_encode($response), $code))->header('Content-Type', 'application/json'); }
/** * Find a preference by it's key * or return a new instance. * * @param $key * @return PreferenceInterface */ public function findByKeyOrNew($key) { /* @var UserInterface $user */ if (!($user = $this->auth->getUser())) { throw new \Exception('The user could not be determined.'); } if (!($preference = $this->model->where('key', $key)->where('user_id', $user->getId())->first())) { $preference = $this->model->newInstance(); $preference->setKey($key); $preference->setUser($user); } return $preference; }
/** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param Guard $guard * @param UserService $userService * @param int $id * @return Response */ public function update(Request $request, Guard $guard, UserService $userService, $id) { if ($id == $guard->getUser()->id) { $response = new \stdClass(); $code = 200; if ($user = $userService->update($id, $request->all())) { $response = $user; } else { $response->errors = $userService->getErrors(); $code = 400; } return (new Response(json_encode($response), $code))->header('Content-Type', 'application/json'); } else { return response('Unauthorized', 403); } }
/** * Return the currently cached user. * * @return \App\User|null * @static */ public static function getUser() { return \Illuminate\Auth\Guard::getUser(); }
public function find($region, $localDate, Guard $guard) { $spots = $this->spotService->getVisibleSpotsByRegion($region, $guard->getUser() ? $guard->getUser()->id : 0); $spots->map(function ($spot) use($localDate) { $spot->msw_forecasts = $spot->mswSpot->mswForecast()->where('localTimestamp', '>=', $localDate)->where('localTimestamp', '<=', strtotime('+5 days', $localDate))->get(); $spot->msw_forecasts->map(function ($forecast) use($spot) { //TODO, bring these variations in from user selections $defaultsVariations = array('swell_size' => 1, 'swell_period' => 2, 'swell_direction' => 10, 'wind_speed' => 6, 'wind_direction' => 10); $variations = array_merge($defaultsVariations, array()); //todo, create forecast -> surf relationship and query via orm $forecast->matches = $this->surfModel->select('surfs.*', 'msw_forecasts.id AS forecast_id', 'msw_forecasts.swell_components_primary_height AS forecast_swell_height', 'msw_forecasts.swell_components_primary_direction AS forecast_swell_direction', 'msw_forecasts.swell_components_primary_period AS forecast_swell_period', 'msw_forecasts.wind_speed AS forecast_wind_speed', 'msw_forecasts.wind_direction AS forecast_wind_direction')->leftJoin('msw_forecasts', 'surfs.msw_forecast_id', '=', 'msw_forecasts.id')->where('surfs.spot_id', '=', $spot->id)->where(function ($query) use($forecast, $variations) { $swell_size_min = floor($forecast->swell_components_primary_height - $variations['swell_size']); $swell_size_min = $swell_size_min > 0 ? $swell_size_min : 0; $query->where('msw_forecasts.swell_components_primary_height', '>=', $swell_size_min)->where('msw_forecasts.swell_components_primary_height', '<=', ceil($forecast->swell_components_primary_height + $variations['swell_size'])); })->where(function ($query) use($forecast, $variations) { $swell_period_min = floor($forecast->swell_components_primary_period - $variations['swell_period']); $swell_period_min = $swell_period_min > 0 ? $swell_period_min : 0; $query->where('msw_forecasts.swell_components_primary_period', '>=', $swell_period_min)->where('msw_forecasts.swell_components_primary_period', '<=', ceil($forecast->swell_components_primary_period + $variations['swell_period'])); })->where(function ($query) use($forecast, $variations) { $swellDirAndOr = 'AND'; $swellDirMin = $forecast->swell_components_primary_direction - $variations['swell_direction']; if ($swellDirMin < 0) { $swellDirMin += 360; $swellDirAndOr = 'OR'; } $swellDirMax = $forecast->swell_components_primary_direction + $variations['swell_direction']; if ($swellDirMax > 360) { $swellDirMax -= 360; $swellDirAndOr = 'OR'; } if ($swellDirAndOr == 'AND') { $query->where('msw_forecasts.swell_components_primary_direction', '>=', $swellDirMin)->where('msw_forecasts.swell_components_primary_direction', '<=', $swellDirMax); } else { $query->where('msw_forecasts.swell_components_primary_direction', '>=', $swellDirMin)->orWhere('msw_forecasts.swell_components_primary_direction', '<=', $swellDirMax); } })->where(function ($query) use($forecast, $variations) { $wind_speed_min = floor($forecast->wind_speed - $variations['wind_speed']); $wind_speed_min = $wind_speed_min > 0 ? $wind_speed_min : 0; $query->where('msw_forecasts.wind_speed', '>=', $wind_speed_min)->where('msw_forecasts.wind_speed', '<=', ceil($forecast->wind_speed + $variations['wind_speed'])); })->where(function ($query) use($forecast, $variations) { $windDirAndOr = 'AND'; $windDirMin = $forecast->wind_direction - $variations['wind_direction']; if ($windDirMin < 0) { $windDirMin += 360; $windDirAndOr = 'OR'; } $windDirMax = $forecast->wind_direction + $variations['wind_direction']; if ($windDirMax > 360) { $windDirMax -= 360; $windDirAndOr = 'OR'; } if ($windDirAndOr == 'AND') { $query->where('msw_forecasts.wind_direction', '>=', $windDirMin)->where('msw_forecasts.wind_direction', '<=', $windDirMax); } else { $query->where('msw_forecasts.wind_direction', '>=', $windDirMin)->orWhere('msw_forecasts.wind_direction', '<=', $windDirMax); } })->get()->load('user', 'spot'); }); return $spot; }); return $spots; }
protected function executeSend(APIControllerHelper $helper, Request $request, PaymentAddressRepository $payment_address_respository, SendRepository $send_respository, PaymentAddressSender $address_sender, Guard $auth, APICallRepository $api_call_repository, $id) { $user = $auth->getUser(); if (!$user) { throw new Exception("User not found", 1); } // get the address $payment_address = $payment_address_respository->findByUuid($id); if (!$payment_address) { return new JsonResponse(['message' => 'address not found'], 404); } // make sure this address belongs to this user if ($payment_address['user_id'] != $user['id']) { return new JsonResponse(['message' => 'Not authorized to send from this address'], 403); } // attributes $request_attributes = $request->only(array_keys($request->rules())); // determine if this is a multisend $is_multisend = (isset($request_attributes['destinations']) and $request_attributes['destinations']); $is_regular_send = !$is_multisend; // normalize destinations $destinations = $is_multisend ? $this->normalizeDestinations($request_attributes['destinations']) : ''; $destination = $is_regular_send ? $request_attributes['destination'] : ''; // determine variables $quantity_sat = CurrencyUtil::valueToSatoshis($is_multisend ? $this->sumMultisendQuantity($destinations) : $request_attributes['quantity']); $asset = $is_regular_send ? $request_attributes['asset'] : 'BTC'; $is_sweep = isset($request_attributes['sweep']) ? !!$request_attributes['sweep'] : false; $float_fee = isset($request_attributes['fee']) ? $request_attributes['fee'] : PaymentAddressSender::DEFAULT_FEE; $dust_size = isset($request_attributes['dust_size']) ? $request_attributes['dust_size'] : PaymentAddressSender::DEFAULT_REGULAR_DUST_SIZE; $request_id = isset($request_attributes['requestId']) ? $request_attributes['requestId'] : Uuid::uuid4()->toString(); // create attibutes $create_attributes = []; $create_attributes['user_id'] = $user['id']; $create_attributes['payment_address_id'] = $payment_address['id']; $create_attributes['destination'] = $destination; $create_attributes['quantity_sat'] = $quantity_sat; $create_attributes['asset'] = $asset; $create_attributes['is_sweep'] = $is_sweep; $create_attributes['fee'] = $float_fee; $create_attributes['dust_size'] = $dust_size; // for multisends $create_attributes['destinations'] = $destinations; // the transaction must be committed before the lock is release and not after // therefore we must release the lock after this closure completes $lock_must_be_released = false; $lock_must_be_released_with_delay = false; // create a send and lock it immediately $send_result = $send_respository->executeWithNewLockedSendByRequestID($request_id, $create_attributes, function ($locked_send) use($request_attributes, $create_attributes, $payment_address, $user, $helper, $send_respository, $address_sender, $api_call_repository, $request_id, $is_multisend, $is_regular_send, $quantity_sat, $asset, $destination, $destinations, $is_sweep, $float_fee, $dust_size, &$lock_must_be_released, &$lock_must_be_released_with_delay) { $api_call = $api_call_repository->create(['user_id' => $user['id'], 'details' => ['method' => 'api/v1/sends/' . $payment_address['uuid'], 'args' => $request_attributes]]); // if a send already exists by this request_id, just return it if (isset($locked_send['txid']) && strlen($locked_send['txid'])) { EventLog::log('send.alreadyFound', $locked_send); return $helper->transformResourceForOutput($locked_send); } $float_quantity = CurrencyUtil::satoshisToValue($quantity_sat); // send EventLog::log('send.requested', array_merge($request_attributes, $create_attributes)); if ($is_sweep) { try { // get lock $lock_acquired = AccountHandler::acquirePaymentAddressLock($payment_address); if ($lock_acquired) { $lock_must_be_released = true; } list($txid, $float_balance_sent) = $address_sender->sweepAllAssets($payment_address, $request_attributes['destination'], $float_fee); $quantity_sat_sent = CurrencyUtil::valueToSatoshis($float_balance_sent); // clear all balances from all accounts AccountHandler::zeroAllBalances($payment_address, $api_call); // release the account lock with a slight delay if ($lock_acquired) { $lock_must_be_released_with_delay = true; } } catch (PaymentException $e) { EventLog::logError('error.sweep', $e); return new JsonResponse(['message' => $e->getMessage()], 500); } catch (Exception $e) { EventLog::logError('error.sweep', $e); return new JsonResponse(['message' => 'Unable to complete this request'], 500); } } else { try { // get the account $account_name = (isset($request_attributes['account']) and strlen($request_attributes['account'])) ? $request_attributes['account'] : 'default'; $account = AccountHandler::getAccount($payment_address, $account_name); if (!$account) { EventLog::logError('error.send.accountMissing', ['address_id' => $payment_address['id'], 'account' => $account_name]); return new JsonResponse(['message' => "This account did not exist."], 404); } // Log::debug("\$account=".json_encode($account, 192)); // get lock $lock_acquired = AccountHandler::acquirePaymentAddressLock($payment_address); if ($lock_acquired) { $lock_must_be_released = true; } // whether to spend unconfirmed balances $allow_unconfirmed = isset($request_attributes['unconfirmed']) ? $request_attributes['unconfirmed'] : false; // Log::debug("\$allow_unconfirmed=".json_encode($allow_unconfirmed, 192)); // validate that the funds are available if ($allow_unconfirmed) { $has_enough_funds = AccountHandler::accountHasSufficientFunds($account, $float_quantity, $asset, $float_fee, $dust_size); } else { $has_enough_funds = AccountHandler::accountHasSufficientConfirmedFunds($account, $float_quantity, $asset, $float_fee, $dust_size); } if (!$has_enough_funds) { EventLog::logError('error.send.insufficient', ['address_id' => $payment_address['id'], 'account' => $account_name, 'quantity' => $float_quantity, 'asset' => $asset]); return new JsonResponse(['message' => "This account does not have sufficient" . ($allow_unconfirmed ? '' : ' confirmed') . " funds available."], 400); } // send the funds EventLog::log('send.begin', ['request_id' => $request_id, 'address_id' => $payment_address['id'], 'account' => $account_name, 'quantity' => $float_quantity, 'asset' => $asset, 'destination' => $is_multisend ? $destinations : $destination]); $txid = $address_sender->sendByRequestID($request_id, $payment_address, $is_multisend ? $destinations : $destination, $float_quantity, $asset, $float_fee, $dust_size); EventLog::log('send.complete', ['txid' => $txid, 'request_id' => $request_id, 'address_id' => $payment_address['id'], 'account' => $account_name, 'quantity' => $float_quantity, 'asset' => $asset, 'destination' => $is_multisend ? $destinations : $destination]); // tag funds as sent with the txid if ($allow_unconfirmed) { AccountHandler::markAccountFundsAsSending($account, $float_quantity, $asset, $float_fee, $dust_size, $txid); } else { AccountHandler::markConfirmedAccountFundsAsSending($account, $float_quantity, $asset, $float_fee, $dust_size, $txid); // Log::debug("After marking confirmed funds as sent, all accounts for ${account['name']}: ".json_encode(app('App\Repositories\LedgerEntryRepository')->accountBalancesByAsset($account, null), 192)); // Log::debug("After marking confirmed funds as sent, all accounts for default: ".json_encode(app('App\Repositories\LedgerEntryRepository')->accountBalancesByAsset(AccountHandler::getAccount($payment_address), null), 192)); } // release the account lock if ($lock_acquired) { $lock_must_be_released_with_delay = true; } } catch (AccountException $e) { EventLog::logError('error.pay', $e); return new JsonResponse(['message' => $e->getMessage(), 'errorName' => $e->getErrorName()], $e->getStatusCode()); } catch (PaymentException $e) { EventLog::logError('error.pay', $e); return new JsonResponse(['message' => $e->getMessage()], 500); } catch (Exception $e) { EventLog::logError('error.pay', $e); return new JsonResponse(['message' => 'Unable to complete this request'], 500); } } $attributes = []; $attributes['sent'] = time(); $attributes['txid'] = $txid; EventLog::log('send.complete', $attributes); // update and send response $send_respository->update($locked_send, $attributes); return $helper->buildJSONResponse($locked_send->serializeForAPI()); }, self::SEND_LOCK_TIMEOUT); // make sure to release the lock if ($lock_must_be_released_with_delay) { $this->releasePaymentAddressLockWithDelay($payment_address); } else { if ($lock_must_be_released) { AccountHandler::releasePaymentAddressLock($payment_address); } } return $send_result; }