I'm running into an issue with Google Calendar API.
I can login with google via authCallback but after one hour it gives me a Invalid Credentials error
App\Http\Controllers\gCalendarController.php
<?php
namespace App\Http\Controllers;
use Carbon\Carbon;
use Google_Client;
use Google_Service_Calendar;
use Google_Service_Calendar_Event;
use Google_Service_Calendar_EventDateTime;
use Illuminate\Http\Request;
class gCalendarController extends Controller
{
protected $client;
public function __construct()
{
$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google_Service_Calendar::CALENDAR);
$guzzleClient = new \GuzzleHttp\Client(array('curl' => array(CURLOPT_SSL_VERIFYPEER => false)));
$client->setHttpClient($guzzleClient);
$this->client = $client;
}
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
session_start();
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$this->client->setAccessToken($_SESSION['access_token']);
$service = new Google_Service_Calendar($this->client);
$calendarId = 'primary';
$results = $service->events->listEvents($calendarId);
$test = $_SESSION['access_token'];
return view('calendar.tyfuscalender', compact('result', 'test'));
} else {
return redirect()->route('oauthCallback');
}
}
public function oauth()
{
session_start();
$rurl = action('gCalendarController#oauth');
$this->client->setRedirectUri($rurl);
if (!isset($_GET['code'])) {
$auth_url = $this->client->createAuthUrl();
$filtered_url = filter_var($auth_url, FILTER_SANITIZE_URL);
return redirect($filtered_url);
} else {
$this->client->authenticate($_GET['code']);
$_SESSION['access_token'] = $this->client->getAccessToken();
return redirect()->route('cal.index');
}
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
return view('calendar.createEvent');
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
session_start();
$startDateTime = $request->start_date;
$endDateTime = $request->end_date;
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$this->client->setAccessToken($_SESSION['access_token']);
$service = new Google_Service_Calendar($this->client);
$calendarId = 'primary';
$event = new Google_Service_Calendar_Event([
'summary' => $request->title,
'description' => $request->description,
'start' => ['dateTime' => $startDateTime],
'end' => ['dateTime' => $endDateTime],
'reminders' => ['useDefault' => true],
]);
$results = $service->events->insert($calendarId, $event);
if (!$results) {
return response()->json(['status' => 'error', 'message' => 'Something went wrong']);
}
return response()->json(['status' => 'success', 'message' => 'Event Created']);
} else {
return redirect()->route('oauthCallback');
}
}
/**
* Display the specified resource.
*
* #param $eventId
* #return \Illuminate\Http\Response
* #internal param int $id
*/
public function show($eventId)
{
session_start();
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$this->client->setAccessToken($_SESSION['access_token']);
$service = new Google_Service_Calendar($this->client);
$event = $service->events->get('primary', $eventId);
if (!$event) {
return response()->json(['status' => 'error', 'message' => 'Something went wrong']);
}
return response()->json(['status' => 'success', 'data' => $event]);
} else {
return redirect()->route('oauthCallback');
}
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param $eventId
* #return \Illuminate\Http\Response
* #internal param int $id
*/
public function update(Request $request, $eventId)
{
session_start();
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$this->client->setAccessToken($_SESSION['access_token']);
$service = new Google_Service_Calendar($this->client);
$startDateTime = Carbon::parse($request->start_date)->toRfc3339String();
$eventDuration = 30; //minutes
if ($request->has('end_date')) {
$endDateTime = Carbon::parse($request->end_date)->toRfc3339String();
} else {
$endDateTime = Carbon::parse($request->start_date)->addMinutes($eventDuration)->toRfc3339String();
}
// retrieve the event from the API.
$event = $service->events->get('primary', $eventId);
$event->setSummary($request->title);
$event->setDescription($request->description);
//start time
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime($startDateTime);
$event->setStart($start);
//end time
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime($endDateTime);
$event->setEnd($end);
$updatedEvent = $service->events->update('primary', $event->getId(), $event);
if (!$updatedEvent) {
return response()->json(['status' => 'error', 'message' => 'Something went wrong']);
}
return response()->json(['status' => 'success', 'data' => $updatedEvent]);
} else {
return redirect()->route('oauthCallback');
}
}
/**
* Remove the specified resource from storage.
*
* #param $eventId
* #return \Illuminate\Http\Response
* #internal param int $id
*/
public function destroy($eventId)
{
session_start();
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$this->client->setAccessToken($_SESSION['access_token']);
$service = new Google_Service_Calendar($this->client);
$service->events->delete('primary', $eventId);
} else {
return redirect()->route('oauthCallback');
}
}
}
This is the error message
Google_Service_Exception in REST.php line 118:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
}
I'm thinking it's something with the token that expires, but i have no idea on how to solve it.
Thanks.
I figured out that if i go back to the '/oauth' route, it prompts me to allow google use my google account again.. Instead of refreshing my accesstoken.. Is there a way to make it refresh? without going back to '/oauth'..
Thanks
Related
Description: I have implemented the laravel socialite stateless, because I am using Laravel as a backend app with REST APIs and my frontend is in Angular. I get the correct redirect URL, however, when I enter my Facebook credentials and agree to proceed with the application I get redirected to my site with the following issue:
Client error: `POST https://graph.facebook.com/v3.3/oauth/access_token` resulted in a `400 Bad Request` response: {"error":{"message":"This authorization code has been used.","type":"OAuthException","code":100,"error_subcode":36009,"f (truncated...)
Here are the routes in my api.php
Route::get('/auth/redirect/{provider}', [AuthController::class, 'redirectToProvider'])
->where('provider', '[A-Za-z]+');
Route::get('/auth/{provider}/callback', [AuthController::class, 'handleProviderCallback'])
->where('provider', '[A-Za-z]+');
And the following functions in my controller AuthController.php
/**
* #param $provider
* #return JsonResponse
*/
public function redirectToProvider($provider): JsonResponse
{
$response = $this->authService->redirectToProvider($provider);
return response()->json($response);
}
/**
* #param $provider
* #param Request $request
* #return JsonResponse
* #throws \App\Exceptions\Custom\CustomValidationException
*/
public function handleProviderCallback($provider, Request $request): JsonResponse
{
ValidationUtils::validate($request->all(), [
'code' => 'required',
]);
$response = $this->authService->handleProviderCallback($provider);
return response()->json($response);
}
And this is where it resolves in the AuthServiceImpl.php
/**
* #param $provider
* #return array[]
*/
public function redirectToProvider($provider): array
{
if (!in_array($provider, self::PROVIDERS)) {
throw new CustomNotFoundException(trans('errors.not_found.provider'));
}
$success['provider_redirect'] = Socialite::driver($provider)->stateless()->redirect()->getTargetUrl();
return [
'data' => $success
];
}
/**
* #param $provider
* #return array[]|void
*/
public function handleProviderCallback($provider)
{
if (!in_array($provider, self::PROVIDERS)) {
throw new CustomNotFoundException(trans('errors.not_found.provider'));
}
try {
$providerUser = Socialite::driver($provider)->stateless()->user();
if ($providerUser) {
$user = $this->socialAccountsService->findOrCreate($providerUser, $provider);
$user->markEmailAsVerified();
$token = $user->createToken(env('API_AUTH_TOKEN_PASSPORT_SOCIAL'))->accessToken;
return [
'data' => [
'tokens' => [
'token_type' => 'Bearer',
'expires_in' => 5400,
'access_token' => $token
],
'user' => new UserResource($user)
],
'message' => trans('auth.login')
];
}
} catch (\Exception $e) {
throw new CustomUnauthorizedException($e->getMessage());
}
}
You can try it yourself by logging in with Facebook on the following link: https://afillix.common.mk/login
I am doing unit testing / functional testing, but my code gives me an error. Kindly have a look on my code and suggest a solution.
Codes On Controller
<?php
namespace App\Controller;
use App\Entity\Organization;
use App\Entity\User;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Psr\Log\LoggerInterface;
use Swift_Mailer;
use Swift_Message;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
class RegisterController extends AbstractController
{
protected $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* Validate the data
* Encodes the password
* Creates new organization if evaplyId does not exists
* Create user and send verification email.
* return status
*
* #param Request $request
* #param UserPasswordEncoderInterface $userPasswordEncoder
* #param ValidatorInterface $validator
* #param Swift_Mailer $mailer
* #return Response
*/
public function register(Request $request, UserPasswordEncoderInterface $userPasswordEncoder, ValidatorInterface $validator, Swift_Mailer $mailer)
{
try {
$form = $request->getContent();
$form = json_decode($form);
$entityManager = $this->getDoctrine()->getManager(); //doctrine manager for entity managing
$user = new User();
$user->setEmail($form->email);
if (!$this->checkEmail($form->email)) {
return new JsonResponse(['status' => false, 'message' => 'Email already exists']);
}
$user->setFirstName($form->first_name);
$user->setLastName($form->last_name);
$user->setPassword($form->plain_password);
if (!$form->evaply_id) {
if(!$form->organization_name)
return new JsonResponse(['status' => false, 'message' => 'Missing field Organization']);
$organization = new Organization();
$organization->setName($form->organization_name);
$startGuideStatus['status'] = false;
$startGuideStatus['add_company'] = false;
$startGuideStatus['first_connection'] = false;
$startGuideStatus['first_scorecard'] = false;
$startGuideStatus['first_order'] = false;
$organization->setStartGuideStatus(($startGuideStatus));
$organization->setCustOrSupplier($form->cust_or_supplier);
$evaply_id = $this->generateEvaplyId($form->organization_name);
$organization->setEvaplyId($evaply_id);
$entityManager->persist($organization);
$entityManager->flush();
} else {
$organization = $this->getDoctrine()->getRepository(Organization::class)->findOneBy(array('evaplyId' => $form->evaply_id));
if (!$organization) {
return new JsonResponse(['status' => false, 'message' => 'Invalid Evaply ID']);
}
}
$user->setOrganization($organization);
$user->setUuid($this->generateUUID());
$user->setRoles(['Admin']);
$error = $validator->validate($user);
if (count($error) > 0) {
return new JsonResponse(['status' => false, 'message' => 'Validation error']);
}
if ($form->plain_password != $form->confirm_password) {
return new JsonResponse(['status' => false, 'message' => 'Password miss match']);
}
$user->setPassword(
$userPasswordEncoder->encodePassword(
$user,
$form->plain_password
)
);
$token = $this->generateVerificationToken($user);
$this->logger->info($token);
$verificationUrl = $this->getParameter('app_url') . "account/verify/" . $token;
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
$this->sendUserRegisteredMail($user, $verificationUrl, $mailer);
return new JsonResponse(['status' => true, 'message' => "Successfully registered"]);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
return new Response($e->getMessage());
}
}
/**
* Check email duplication in database
*
* #param $email
* #return bool
*/
public function checkEmail($email)
{
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy(array('email' => $email));
if ($user)
return false;
else
return true;
}
/**
* Generate a unique id using organization name and timestamp
*
* #param $orgName
* #return string
*/
public function generateEvaplyId($orgName)
{
$org = strtoupper(substr($orgName, 0, 3));
$dateTime = time();
$evaply_id = $org . $dateTime;
return $evaply_id;
}
/**
* Generate unique uuid for user
* Recursive function
*
* #return int
*/
public function generateUUID()
{
$uuid = rand(1000000000, 9999999999);
$user = $this->getDoctrine()->getRepository(User::class)->findOneBy(array('uuid' => $uuid));
if ($user) {
return $this->generateUUID();
} else {
return $uuid;
}
}
/**
* Send email to user after a successfull registartion.
*
* #param User $user
* #param Swift_Mailer $mailer
* #return int
*/
public function sendUserRegisteredMail(User $user, $verificationUrl, Swift_Mailer $mailer)
{
$message = (new Swift_Message("Successfully Registered"))
->setFrom('admin#evaply.com')
->setTo($user->getEmail())
->setBody(
$this->renderView(
'emails/registration.html.twig',
array('firstName' => $user->getFirstName(), 'lastName' => $user->getLastName(), 'verificationUrl' => $verificationUrl)
),
'text/html'
);
return $mailer->send($message);
}
/**
* Generates a verification token using aes-128-gcm encryption
* encrypts email and uuid
* encode ciphertext with base64 encoder
*
* #param User $user
* #return string
*/
public function generateVerificationToken(User $user)
{
$data = array();
$data['email'] = $user->getEmail();
$data['uuid'] = $user->getUuid();
$plaintext = json_encode($data);
$cipher = $this->getParameter('cipher');
if (in_array($cipher, openssl_get_cipher_methods())) {
$this->logger->info("inside cipher");
//$ivlen = openssl_cipher_iv_length($cipher);
$iv = $this->getParameter('secretIV');
$key = $this->getParameter('cipher_key');
//$tag = $this->getParameter('tagg');
$ciphertext = openssl_encrypt($plaintext, $cipher, $key, $options = 0, $iv);
$original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, $options = 0, $iv);
return $token = base64_encode($ciphertext);
}
}
}
Codes On Tests/Controller Folder
<?php
/**
* Created by PhpStorm.
* User: xavier-phases
* Date: 22/1/19
* Time: 5:09 PM
*/
namespace App\Tests\Controller;
use App\Controller\RegisterController;
use PHPUnit\Framework\TestCase;
class EvaplyTest extends TestCase
{
public function testGenerate_evaply_clid(LoggerInterface $logger)
{
$id= new RegisterController();
$org_name=$id->generateEvaplyId('Tset');
$org = strtoupper(substr($org_name, 0, 3));
$dateTime = time();
$evaply_id = $org . $dateTime;
return $evaply_id;
}
}`
I am calling the generateEvaplyId() method from the register controller. I have installed all test packages. It gives me the following error:
"ArgumentCountError: Too few arguments to function App\Tests\Controller\EvaplyTest::testGenerate_evaply_clid(), 0 passed and exactly 1 expected". KIndly have a look and suggest me a solution.
<?php
namespace App\Tests\Controller;
use App\Controller\RegisterController;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
class EvaplyTest extends TestCase
{
/** #var LoggerInterface|MockObject */
protected $logger;
/** #var RegisterController **/
protected $controller;
/**
* {#inheritdoc}
*/
protected function setUp()
{
$this->logger = $this->createMock(LoggerInterface::class);
$this->controller = new RegisterController(
$this->logger,
);
parent::setUp();
}
public function testGenerate_evaply_clid()
{
$result = $this->controller->generateEvaplyId('Test');
$this->assertEquals( 'TEST1548303737',$result);
}
}
Here is how it should be. Initiate controller instance and all it's dependencies in setUp method, then, in all the tests you can reference them. By default, PHPUnit does not expect any dependencies for tests suite, what you tried to do is called data provider (check for data providers docs), it does require additional annotation and used for completely different purpose.
And for the last, I do NOT recommend you to store any part of logic in controllers. Move everything to service layer. Controllers are only to catch request, pass it to manager and return response.
I have a Question about calling a other script.
I want to make an api whit ExactOnline... But i need to call an other script for that I used "require DIR ." That works fine but my code still doesn't get the script. Can someone explane to me why this is not working?
(My script that need to call is in "C:\xampp\htdocs\CM\EO\exactphpclientmaster\vendor\picqer\exactphpclient\src\Picqer\Financials\Exact\Connection.php")
=ERROR=
Fatal error: Class 'vendor\picqer\exactphpclient\src\Picqer\Financials\Exact\Connection' not found in C:\xampp\htdocs\CM\EO\exactphpclientmaster\ConntectEO.php on line 3
=SCRIPT That is calling connection.php=
<?php
require __DIR__ . '\vendor\picqer\exactphpclient\src\Picqer\Financials\Exact\Connection.php';
$connection = new \vendor\picqer\exactphpclient\src\Picqer\Financials\Exact\Connection.php();
$connection->setRedirectUrl('**************************'); // Same as entered online in the App Center
$connection->setExactClientId('****************************************');
$connection->setExactClientSecret('************************');
if (getValue('authorizationcode')) // Retrieves authorizationcode from database
$connection->setAuthorizationCode(getValue('authorizationcode'));
if (getValue('accesstoken')) // Retrieves accesstoken from database
$connection->setAccessToken(unserialize(getValue('accesstoken')));
if (getValue('refreshtoken')) // Retrieves refreshtoken from database
$connection->setRefreshToken(getValue('refreshtoken'));
if (getValue('expires_in')) // Retrieves expires timestamp from database
$connection->setTokenExpires(getValue('expires_in'));
// Make the client connect and exchange tokens
try {
$connection->connect();
} catch (\Exception $e)
{
throw new Exception('Could not connect to Exact: ' . $e->getMessage());
}
// Save the new tokens for next connections
setValue('accesstoken', serialize($connection->getAccessToken()));
setValue('refreshtoken', $connection->getRefreshToken());
// Optionally, save the expiry-timestamp. This prevents exchanging valid tokens (ie. saves you some requests)
setValue('expires_in', $connection->getTokenExpires());
=SCRIPT Connection.php=
<?php namespace Picqer\Financials\Exact;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7;
/**
* Class Connection
*
* #package Picqer\Financials\Exact
*
*/
class Connection
{
/**
* #var string
*/
private $baseUrl = 'https://start.exactonline.nl';
/**
* #var string
*/
private $apiUrl = '/api/v1';
/**
* #var string
*/
private $authUrl = '/api/oauth2/auth';
/**
* #var string
*/
private $tokenUrl = '/api/oauth2/token';
/**
* #var
*/
private $exactClientId;
/**
* #var
*/
private $exactClientSecret;
/**
* #var
*/
private $authorizationCode;
/**
* #var
*/
private $accessToken;
/**
* #var
*/
private $tokenExpires;
/**
* #var
*/
private $refreshToken;
/**
* #var
*/
private $redirectUrl;
/**
* #var
*/
private $division;
/**
* #var Client
*/
private $client;
/**
* #var callable(Connection)
*/
private $tokenUpdateCallback;
/**
*
*/
protected $middleWares = [];
/**
* #var
*/
public $nextUrl = null;
/**
* #return Client
*/
private function client()
{
if ($this->client) {
return $this->client;
}
$handlerStack = HandlerStack::create();
foreach ($this->middleWares as $middleWare) {
$handlerStack->push($middleWare);
}
$this->client = new Client([
'http_errors' => true,
'handler' => $handlerStack,
'expect' => false,
]);
return $this->client;
}
public function insertMiddleWare($middleWare)
{
$this->middleWares[] = $middleWare;
}
public function connect()
{
// Redirect for authorization if needed (no access token or refresh token given)
if ($this->needsAuthentication()) {
$this->redirectForAuthorization();
}
// If access token is not set or token has expired, acquire new token
if (empty($this->accessToken) || $this->tokenHasExpired()) {
$this->acquireAccessToken();
}
$client = $this->client();
return $client;
}
/**
* #param string $method
* #param $endpoint
* #param null $body
* #param array $params
* #param array $headers
* #return Request
*/
private function createRequest($method = 'GET', $endpoint, $body = null, array $params = [], array $headers = [])
{
// Add default json headers to the request
$headers = array_merge($headers, [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Prefer' => 'return=representation'
]);
// If access token is not set or token has expired, acquire new token
if (empty($this->accessToken) || $this->tokenHasExpired()) {
$this->acquireAccessToken();
}
// If we have a token, sign the request
if (!$this->needsAuthentication() && !empty($this->accessToken)) {
$headers['Authorization'] = 'Bearer ' . $this->accessToken;
}
// Create param string
if (!empty($params)) {
$endpoint .= '?' . http_build_query($params);
}
// Create the request
$request = new Request($method, $endpoint, $headers, $body);
return $request;
}
/**
* #param $url
* #param array $params
* #return mixed
* #throws ApiException
*/
public function get($url, array $params = [])
{
$url = $this->formatUrl($url, $url !== 'current/Me', $url == $this->nextUrl);
try {
$request = $this->createRequest('GET', $url, null, $params);
$response = $this->client()->send($request);
return $this->parseResponse($response, $url != $this->nextUrl);
} catch (Exception $e) {
$this->parseExceptionForErrorMessages($e);
}
}
/**
* #param $url
* #param $body
* #return mixed
* #throws ApiException
*/
public function post($url, $body)
{
$url = $this->formatUrl($url);
try {
$request = $this->createRequest('POST', $url, $body);
$response = $this->client()->send($request);
return $this->parseResponse($response);
} catch (Exception $e) {
$this->parseExceptionForErrorMessages($e);
}
}
/**
* #param $url
* #param $body
* #return mixed
* #throws ApiException
*/
public function put($url, $body)
{
$url = $this->formatUrl($url);
try {
$request = $this->createRequest('PUT', $url, $body);
$response = $this->client()->send($request);
return $this->parseResponse($response);
} catch (Exception $e) {
$this->parseExceptionForErrorMessages($e);
}
}
/**
* #param $url
* #return mixed
* #throws ApiException
*/
public function delete($url)
{
$url = $this->formatUrl($url);
try {
$request = $this->createRequest('DELETE', $url);
$response = $this->client()->send($request);
return $this->parseResponse($response);
} catch (Exception $e) {
$this->parseExceptionForErrorMessages($e);
}
}
/**
* #return string
*/
public function getAuthUrl()
{
return $this->baseUrl . $this->authUrl . '?' . http_build_query(array(
'client_id' => $this->exactClientId,
'redirect_uri' => $this->redirectUrl,
'response_type' => 'code'
));
}
/**
* #param mixed $exactClientId
*/
public function setExactClientId($exactClientId)
{
$this->exactClientId = $exactClientId;
}
/**
* #param mixed $exactClientSecret
*/
public function setExactClientSecret($exactClientSecret)
{
$this->exactClientSecret = $exactClientSecret;
}
/**
* #param mixed $authorizationCode
*/
public function setAuthorizationCode($authorizationCode)
{
$this->authorizationCode = $authorizationCode;
}
/**
* #param mixed $accessToken
*/
public function setAccessToken($accessToken)
{
$this->accessToken = $accessToken;
}
/**
* #param mixed $refreshToken
*/
public function setRefreshToken($refreshToken)
{
$this->refreshToken = $refreshToken;
}
/**
*
*/
public function redirectForAuthorization()
{
$authUrl = $this->getAuthUrl();
header('Location: ' . $authUrl);
exit;
}
/**
* #param mixed $redirectUrl
*/
public function setRedirectUrl($redirectUrl)
{
$this->redirectUrl = $redirectUrl;
}
/**
* #return bool
*/
public function needsAuthentication()
{
return empty($this->refreshToken) && empty($this->authorizationCode);
}
/**
* #param Response $response
* #param bool $returnSingleIfPossible
* #return mixed
* #throws ApiException
*/
private function parseResponse(Response $response, $returnSingleIfPossible = true)
{
try {
if ($response->getStatusCode() === 204) {
return [];
}
Psr7\rewind_body($response);
$json = json_decode($response->getBody()->getContents(), true);
if (array_key_exists('d', $json)) {
if (array_key_exists('__next', $json['d'])) {
$this->nextUrl = $json['d']['__next'];
}
else {
$this->nextUrl = null;
}
if (array_key_exists('results', $json['d'])) {
if ($returnSingleIfPossible && count($json['d']['results']) == 1) {
return $json['d']['results'][0];
}
return $json['d']['results'];
}
return $json['d'];
}
return $json;
} catch (\RuntimeException $e) {
throw new ApiException($e->getMessage());
}
}
/**
* #return mixed
*/
private function getCurrentDivisionNumber()
{
if (empty($this->division)) {
$me = new Me($this);
$this->division = $me->find()->CurrentDivision;
}
return $this->division;
}
/**
* #return mixed
*/
public function getRefreshToken()
{
return $this->refreshToken;
}
/**
* #return mixed
*/
public function getAccessToken()
{
return $this->accessToken;
}
private function acquireAccessToken()
{
// If refresh token not yet acquired, do token request
if (empty($this->refreshToken)) {
$body = [
'form_params' => [
'redirect_uri' => $this->redirectUrl,
'grant_type' => 'authorization_code',
'client_id' => $this->exactClientId,
'client_secret' => $this->exactClientSecret,
'code' => $this->authorizationCode
]
];
} else { // else do refresh token request
$body = [
'form_params' => [
'refresh_token' => $this->refreshToken,
'grant_type' => 'refresh_token',
'client_id' => $this->exactClientId,
'client_secret' => $this->exactClientSecret,
]
];
}
$response = $this->client()->post($this->getTokenUrl(), $body);
if ($response->getStatusCode() == 200) {
Psr7\rewind_body($response);
$body = json_decode($response->getBody()->getContents(), true);
if (json_last_error() === JSON_ERROR_NONE) {
$this->accessToken = $body['access_token'];
$this->refreshToken = $body['refresh_token'];
$this->tokenExpires = $this->getDateTimeFromExpires($body['expires_in']);
if (is_callable($this->tokenUpdateCallback)) {
call_user_func($this->tokenUpdateCallback, $this);
}
} else {
throw new ApiException('Could not acquire tokens, json decode failed. Got response: ' . $response->getBody()->getContents());
}
} else {
throw new ApiException('Could not acquire or refresh tokens');
}
}
private function getDateTimeFromExpires($expires)
{
if (!is_numeric($expires)) {
throw new \InvalidArgumentException('Function requires a numeric expires value');
}
return time() + 600;
}
/**
* #return mixed
*/
public function getTokenExpires()
{
return $this->tokenExpires;
}
/**
* #param mixed $tokenExpires
*/
public function setTokenExpires($tokenExpires)
{
$this->tokenExpires = $tokenExpires;
}
private function tokenHasExpired()
{
if (empty($this->tokenExpires)) {
return true;
}
return $this->tokenExpires <= time() + 10;
}
private function formatUrl($endPoint, $includeDivision = true, $formatNextUrl = false)
{
if ($formatNextUrl) {
return $endPoint;
}
if ($includeDivision) {
return implode('/', [
$this->getApiUrl(),
$this->getCurrentDivisionNumber(),
$endPoint
]);
}
return implode('/', [
$this->getApiUrl(),
$endPoint
]);
}
/**
* #return mixed
*/
public function getDivision()
{
return $this->division;
}
/**
* #param mixed $division
*/
public function setDivision($division)
{
$this->division = $division;
}
/**
* #param callable $callback
*/
public function setTokenUpdateCallback($callback) {
$this->tokenUpdateCallback = $callback;
}
/**
* Parse the reponse in the Exception to return the Exact error messages
* #param Exception $e
* #throws ApiException
*/
private function parseExceptionForErrorMessages(Exception $e)
{
if (! $e instanceof BadResponseException) {
throw new ApiException($e->getMessage());
}
$response = $e->getResponse();
Psr7\rewind_body($response);
$responseBody = $response->getBody()->getContents();
$decodedResponseBody = json_decode($responseBody, true);
if (! is_null($decodedResponseBody) && isset($decodedResponseBody['error']['message']['value'])) {
$errorMessage = $decodedResponseBody['error']['message']['value'];
} else {
$errorMessage = $responseBody;
}
throw new ApiException('Error ' . $response->getStatusCode() .': ' . $errorMessage);
}
/**
* #return string
*/
protected function getBaseUrl()
{
return $this->baseUrl;
}
/**
* #return string
*/
private function getApiUrl()
{
return $this->baseUrl . $this->apiUrl;
}
/**
* #return string
*/
private function getTokenUrl()
{
return $this->baseUrl . $this->tokenUrl;
}
/**
* Set base URL for different countries according to
* https://developers.exactonline.com/#Exact%20Online%20sites.html
*
* #param string $baseUrl
*/
public function setBaseUrl($baseUrl)
{
$this->baseUrl = $baseUrl;
}
/**
* #param string $apiUrl
*/
public function setApiUrl($apiUrl)
{
$this->apiUrl = $apiUrl;
}
/**
* #param string $authUrl
*/
public function setAuthUrl($authUrl)
{
$this->authUrl = $authUrl;
}
/**
* #param string $tokenUrl
*/
public function setTokenUrl($tokenUrl)
{
$this->tokenUrl = $tokenUrl;
}
}
The error itself is pretty self-explanatory. You are trying to include a file and it cannot be found with the path you provided.
Try printing what the magic constant __DIR__ contains in order to see the full path you are trying to include.
You can use var_dump(__DIR__);exit; at the start of your script.
As an additional note, you should consider using composer's autoload.
As you mention your trying to load Connection class as below
require __DIR__ . '\vendor\picqer\exactphpclient\src\Picqer\Financials\Exact\Connection.php';
When we using composer, instead of loading individual class files try to use composer auto load, its automatically loads the name spaces of the required class.
If you implement auto load in your code, the code may look like this.
require __DIR__ . '/vendor/autoload.php';
use Picqer\Financials\Exact\Connection;
$connection = new Connection();
just now I get this issues that is bothering me.
the error in code after validator::make in update function.
BadMethodCallException in Controller.php line 107: Method [all] does
not exist.
This is the full code from BooksController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Redirect;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\book;
class BooksController extends Controller
{
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
$book = BooksController::all();
return view('book.index')->with('book', $book);
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
return view('book.create');
}
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
$rules = array(
'judul' => 'required',
'author' => 'required',
'penerbit' => 'required'
);
$validator = Validator::make(Input::all(), $rules);
// process the login
if ($validator->fails()) {
return Redirect::to('book/create')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
// store
$book = new book;
$book ->judul = Input::get('judul');
$book ->author = Input::get('author');
$book ->penerbit = Input::get('penerbit');
$book ->save();
// redirect
Session:flash('message', 'Berhasil membuat buku!');
return Redirect::to('book');
}
}
/**
* Display the specified resource.
*
* #param int $idate
* #return Response
*/
public function show($id)
{
$book = books::find($id);
return view('book.show')
->with('book', $book);
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return Response
*/
public function edit($id)
{
$book = books::find($id);
return view('book.edit')
->with('book', $book);
}
/**
* Update the specified resource in storage.
*
* #param int $id
* #return Response
*/
public function update($id)
{
$rules = array(
'judul' => 'required',
'author' => 'required',
'penerbit' => 'required'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('book/' . $id . '/edit')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
// simpan
$book = books::find($id);
$book->judul = Input::get('judul');
$book->author = Input::get('author');
$book->penerbit = Input::get('penerbit');
$book->save();
// redirect
Session::flash('message', 'Berhasil mengganti info buku!');
return Redirect::to('book');
}
}
/**
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
$book = books::find($id);
$book ->delete();
//redirect
Session::flash('message', 'Berhasil menghapus buku!');
return Redirect::to('book');
}
}
try this use Validator; instead of
use Illuminate\Support\Facades\Validator;
convert user Input::all() to input()->all() or request()->all()
I'm trying to use the Auth Client Extension in Yii2 (http://www.yiiframework.com/doc-2.0/ext-authclient-index.html). I've copied the Twitter Auth Client class that came with YiiFramework and made my own Tumblr version. Twitter works fine, but when I use my Tumblr version, I get an error on the screen after the "Is it alright for this application to access some of your data and make posts to your account? You are logged in as *********." (Tumblr oauth page)
There error is: Request failed with code: 401, message: oauth_signature does not match expected value
Here is my Tumblr auth client code:
namespace yii\authclient\clients;
use yii\authclient\OAuth1;
/**
*
* Example application configuration:
*
* ~~~
* 'components' => [
* 'authClientCollection' => [
* 'class' => 'yii\authclient\Collection',
* 'clients' => [
* 'tumblr' => [
* 'class' => 'yii\authclient\clients\Tumblr',
* 'consumerKey' => 'tumblr_consumer_key',
* 'consumerSecret' => 'tumblr_consumer_secret',
* ],
* ],
* ]
* ...
* ]
* ~~~
*
*/
class Tumblr extends OAuth1
{
/**
* #inheritdoc
*/
public $authUrl = 'https://www.tumblr.com/oauth/authorize';
/**
* #inheritdoc
*/
public $requestTokenUrl = 'https://www.tumblr.com/oauth/request_token';
/**
* #inheritdoc
*/
public $requestTokenMethod = 'POST';
/**
* #inheritdoc
*/
public $accessTokenUrl = 'https://www.tumblr.com/oauth/access_token';
/**
* #inheritdoc
*/
public $accessTokenMethod = 'GET';
/**
* #inheritdoc
*/
public $apiBaseUrl = 'http://api.tumblr.com/v2';
/**
* #inheritdoc
*/
protected function initUserAttributes()
{
return $this->api('/user/info', 'GET');
}
/**
* #inheritdoc
*/
protected function defaultName()
{
return 'tumblr';
}
/**
* #inheritdoc
*/
protected function defaultTitle()
{
return 'Tumblr';
}
}
You might want to try out Hybridauth's version. I have used the Google and Facebook version in Yii2 and it works fine.
For the current version of yii - you have to extend yii Oauth1 class using the following code to be able to use your class.
<?php
namespace your_vendor\authclient;
use yii\authclient\OAuthToken;
use yii\base\Exception;
use Yii;
class OAuth1 extends \yii\authclient\OAuth1
{
public function fetchAccessToken(OAuthToken $requestToken = null, $oauthVerifier = null, array $params = [])
{
if (!is_object($requestToken)) {
$requestToken = $this->getState('requestToken');
if (!is_object($requestToken)) {
throw new Exception('Request token is required to fetch access token!');
}
}
$defaultParams = [
'oauth_consumer_key' => $this->consumerKey,
'oauth_token' => $requestToken->getToken()
];
if ($oauthVerifier === null) {
if (isset($_REQUEST['oauth_verifier'])) {
$oauthVerifier = $_REQUEST['oauth_verifier'];
}
}
if (!empty($oauthVerifier)) {
$defaultParams['oauth_verifier'] = $oauthVerifier;
}
$response = $this->sendSignedRequest($this->accessTokenMethod, $this->accessTokenUrl, array_merge($defaultParams, $params));
$this->removeState('requestToken');
$token = $this->createToken([
'params' => $response
]);
$this->setAccessToken($token);
return $token;
}
protected function composeSignatureKey() {
$signatureKeyParts = [
$this->consumerSecret
];
if (is_null($accessToken = $this->getState('requestToken'))) {
$accessToken = $this->getAccessToken();
}
if (is_object($accessToken)) {
$signatureKeyParts[] = $accessToken->getTokenSecret();
} else {
$signatureKeyParts[] = '';
}
$signatureKeyParts = array_map('rawurlencode', $signatureKeyParts);
return implode('&', $signatureKeyParts);
}
}