diff --git a/app/Console/Commands/SendRenewalInvoices.php b/app/Console/Commands/SendRenewalInvoices.php
index cf9a968d56ba..658784a30311 100644
--- a/app/Console/Commands/SendRenewalInvoices.php
+++ b/app/Console/Commands/SendRenewalInvoices.php
@@ -29,13 +29,20 @@ class SendRenewalInvoices extends Command
$this->info(date('Y-m-d').' Running SendRenewalInvoices...');
$today = new DateTime();
+ // get all accounts with pro plans expiring in 10 days
$accounts = Account::whereRaw('datediff(curdate(), pro_plan_paid) = 355')->get();
$this->info(count($accounts).' accounts found');
foreach ($accounts as $account) {
$client = $this->accountRepo->getNinjaClient($account);
$invitation = $this->accountRepo->createNinjaInvoice($client);
- $this->mailer->sendInvoice($invitation->invoice);
+
+ // set the due date to 10 days from now
+ $invoice = $invitation->invoice;
+ $invoice->due_date = date('Y-m-d', strtotime('+ 10 days'));
+ $invoice->save();
+
+ $this->mailer->sendInvoice($invoice);
}
$this->info('Done');
diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php
index f6990e28450e..1eb38bcbdc8a 100644
--- a/app/Http/Controllers/AccountController.php
+++ b/app/Http/Controllers/AccountController.php
@@ -43,6 +43,7 @@ use App\Ninja\Mailers\ContactMailer;
use App\Events\UserSignedUp;
use App\Events\UserLoggedIn;
use App\Events\UserSettingsChanged;
+use App\Services\AuthService;
class AccountController extends BaseController
{
@@ -110,7 +111,6 @@ class AccountController extends BaseController
}
Auth::login($user, true);
- event(new UserSignedUp());
event(new UserLoggedIn());
$redirectTo = Input::get('redirect_to') ?: 'invoices/create';
@@ -121,13 +121,6 @@ class AccountController extends BaseController
{
$invitation = $this->accountRepo->enableProPlan();
- /*
- if ($invoice)
- {
- $this->contactMailer->sendInvoice($invoice);
- }
- */
-
return $invitation->invitation_key;
}
@@ -153,7 +146,12 @@ class AccountController extends BaseController
public function showSection($section = ACCOUNT_DETAILS, $subSection = false)
{
if ($section == ACCOUNT_DETAILS) {
- $primaryUser = Auth::user()->account->users()->orderBy('id')->first();
+
+ $oauthLoginUrls = [];
+ foreach (AuthService::$providers as $provider) {
+ $oauthLoginUrls[] = ['label' => $provider, 'url' => '/auth/' . strtolower($provider)];
+ }
+
$data = [
'account' => Account::with('users')->findOrFail(Auth::user()->account_id),
'countries' => Cache::get('countries'),
@@ -164,9 +162,10 @@ class AccountController extends BaseController
'datetimeFormats' => Cache::get('datetimeFormats'),
'currencies' => Cache::get('currencies'),
'languages' => Cache::get('languages'),
- 'showUser' => Auth::user()->id === $primaryUser->id,
'title' => trans('texts.company_details'),
- 'primaryUser' => $primaryUser,
+ 'user' => Auth::user(),
+ 'oauthProviderName' => AuthService::getProviderName(Auth::user()->oauth_provider_id),
+ 'oauthLoginUrls' => $oauthLoginUrls,
];
return View::make('accounts.details', $data);
@@ -402,6 +401,8 @@ class AccountController extends BaseController
$account->custom_invoice_label2 = trim(Input::get('custom_invoice_label2'));
$account->custom_invoice_taxes1 = Input::get('custom_invoice_taxes1') ? true : false;
$account->custom_invoice_taxes2 = Input::get('custom_invoice_taxes2') ? true : false;
+ $account->custom_invoice_text_label1 = trim(Input::get('custom_invoice_text_label1'));
+ $account->custom_invoice_text_label2 = trim(Input::get('custom_invoice_text_label2'));
$account->invoice_number_prefix = Input::get('invoice_number_prefix');
$account->invoice_number_counter = Input::get('invoice_number_counter');
@@ -722,23 +723,21 @@ class AccountController extends BaseController
$account->military_time = Input::get('military_time') ? true : false;
$account->save();
- if (Auth::user()->id === $user->id) {
- $user = Auth::user();
- $user->first_name = trim(Input::get('first_name'));
- $user->last_name = trim(Input::get('last_name'));
- $user->username = trim(Input::get('email'));
- $user->email = trim(strtolower(Input::get('email')));
- $user->phone = trim(Input::get('phone'));
- if (Utils::isNinja()) {
- if (Input::get('referral_code')) {
- $user->referral_code = $this->accountRepo->getReferralCode();
- }
+ $user = Auth::user();
+ $user->first_name = trim(Input::get('first_name'));
+ $user->last_name = trim(Input::get('last_name'));
+ $user->username = trim(Input::get('email'));
+ $user->email = trim(strtolower(Input::get('email')));
+ $user->phone = trim(Input::get('phone'));
+ if (Utils::isNinja()) {
+ if (Input::get('referral_code') && !$user->referral_code) {
+ $user->referral_code = $this->accountRepo->getReferralCode();
}
- if (Utils::isNinjaDev()) {
- $user->dark_mode = Input::get('dark_mode') ? true : false;
- }
- $user->save();
}
+ if (Utils::isNinjaDev()) {
+ $user->dark_mode = Input::get('dark_mode') ? true : false;
+ }
+ $user->save();
/* Logo image file */
if ($file = Input::file('logo')) {
@@ -816,24 +815,14 @@ class AccountController extends BaseController
$user->username = $user->email;
$user->password = bcrypt(trim(Input::get('new_password')));
$user->registered = true;
- $user->save();
-
- if (Utils::isNinjaProd()) {
- $this->userMailer->sendConfirmation($user);
- }
-
- $activities = Activity::scope()->get();
- foreach ($activities as $activity) {
- $activity->message = str_replace('Guest', $user->getFullName(), $activity->message);
- $activity->save();
- }
+ $user->save();
if (Input::get('go_pro') == 'true') {
Session::set(REQUESTED_PRO_PLAN, true);
}
- Session::set(SESSION_COUNTER, -1);
-
+ event(new UserSignedUp());
+
return "{$user->first_name} {$user->last_name}";
}
diff --git a/app/Http/Controllers/AppController.php b/app/Http/Controllers/AppController.php
index 21becbc7e067..5ced7948658e 100644
--- a/app/Http/Controllers/AppController.php
+++ b/app/Http/Controllers/AppController.php
@@ -20,18 +20,21 @@ use App\Models\Industry;
use App\Ninja\Mailers\Mailer;
use App\Ninja\Repositories\AccountRepository;
use App\Events\UserSettingsChanged;
+use App\Services\EmailService;
class AppController extends BaseController
{
protected $accountRepo;
protected $mailer;
+ protected $emailService;
- public function __construct(AccountRepository $accountRepo, Mailer $mailer)
+ public function __construct(AccountRepository $accountRepo, Mailer $mailer, EmailService $emailService)
{
parent::__construct();
$this->accountRepo = $accountRepo;
$this->mailer = $mailer;
+ $this->emailService = $emailService;
}
public function showSetup()
@@ -195,4 +198,19 @@ class AppController extends BaseController
return Redirect::to('/');
}
+
+ public function emailBounced()
+ {
+ $messageId = Input::get('MessageID');
+ $error = Input::get('Name') . ': ' . Input::get('Description');
+ return $this->emailService->markBounced($messageId, $error) ? RESULT_SUCCESS : RESULT_FAILURE;
+ }
+
+ public function emailOpened()
+ {
+ $messageId = Input::get('MessageID');
+ return $this->emailService->markOpened($messageId) ? RESULT_SUCCESS : RESULT_FAILURE;
+
+ return RESULT_SUCCESS;
+ }
}
diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php
index a5897ac6879d..58891afe9763 100644
--- a/app/Http/Controllers/Auth/AuthController.php
+++ b/app/Http/Controllers/Auth/AuthController.php
@@ -9,6 +9,7 @@ use App\Models\User;
use App\Events\UserLoggedIn;
use App\Http\Controllers\Controller;
use App\Ninja\Repositories\AccountRepository;
+use App\Services\AuthService;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\Registrar;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
@@ -30,6 +31,7 @@ class AuthController extends Controller {
protected $loginPath = '/login';
protected $redirectTo = '/dashboard';
+ protected $authService;
protected $accountRepo;
/**
@@ -39,15 +41,29 @@ class AuthController extends Controller {
* @param \Illuminate\Contracts\Auth\Registrar $registrar
* @return void
*/
- public function __construct(Guard $auth, Registrar $registrar, AccountRepository $repo)
+ public function __construct(Guard $auth, Registrar $registrar, AccountRepository $repo, AuthService $authService)
{
$this->auth = $auth;
$this->registrar = $registrar;
$this->accountRepo = $repo;
+ $this->authService = $authService;
//$this->middleware('guest', ['except' => 'getLogout']);
}
+ public function authLogin($provider, Request $request)
+ {
+ return $this->authService->execute($provider, $request->has('code'));
+ }
+
+ public function authUnlink()
+ {
+ $this->accountRepo->unlinkUserFromOauth(Auth::user());
+
+ Session::flash('message', trans('texts.updated_settings'));
+ return redirect()->to('/company/details');
+ }
+
public function getLoginWrapper()
{
if (!Utils::isNinja() && !User::count()) {
@@ -63,7 +79,7 @@ class AuthController extends Controller {
$user = User::where('email', '=', $request->input('email'))->first();
if ($user && $user->failed_logins >= 3) {
- Session::flash('error', 'These credentials do not match our records.');
+ Session::flash('error', trans('texts.invalid_credentials'));
return redirect()->to('login');
}
diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php
index 60c1e7578cd0..948a21532f0e 100644
--- a/app/Http/Controllers/InvoiceController.php
+++ b/app/Http/Controllers/InvoiceController.php
@@ -358,20 +358,26 @@ class InvoiceController extends BaseController
$data['formIsChanged'] = true;
}
- // Set the invitation link on the client's contacts
+ // Set the invitation data on the client's contacts
if (!$clone) {
$clients = $data['clients'];
foreach ($clients as $client) {
- if ($client->id == $invoice->client->id) {
- foreach ($invoice->invitations as $invitation) {
- foreach ($client->contacts as $contact) {
- if ($invitation->contact_id == $contact->id) {
- $contact->invitation_link = $invitation->getLink();
- }
+ if ($client->id != $invoice->client->id) {
+ continue;
+ }
+
+ foreach ($invoice->invitations as $invitation) {
+ foreach ($client->contacts as $contact) {
+ if ($invitation->contact_id == $contact->id) {
+ $contact->email_error = $invitation->email_error;
+ $contact->invitation_link = $invitation->getLink();
+ $contact->invitation_viewed = $invitation->viewed_date;
+ $contact->invitation_status = $contact->email_error ? false : $invitation->getStatus();
}
}
- break;
}
+
+ break;
}
}
diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php
index 33f62d417d81..903d6f028aab 100644
--- a/app/Http/Middleware/VerifyCsrfToken.php
+++ b/app/Http/Middleware/VerifyCsrfToken.php
@@ -14,6 +14,8 @@ class VerifyCsrfToken extends BaseVerifier {
'api/v1/tasks',
'api/v1/email_invoice',
'api/v1/hooks',
+ 'hook/email_opened',
+ 'hook/email_bounced',
];
/**
diff --git a/app/Http/routes.php b/app/Http/routes.php
index 9f1e569fb768..2ec246b7ce42 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -63,6 +63,10 @@ Route::post('signup/validate', 'AccountController@checkEmail');
Route::post('signup/submit', 'AccountController@submitSignup');
Route::get('auth/{provider}', 'Auth\AuthController@authLogin');
+Route::get('auth_unlink', 'Auth\AuthController@authUnlink');
+
+Route::post('hook/email_bounced', 'AppController@emailBounced');
+Route::post('hook/email_opened', 'AppController@emailOpened');
// Laravel auth routes
@@ -436,7 +440,7 @@ if (!defined('CONTACT_EMAIL')) {
define('SOCIAL_GOOGLE', 'Google');
define('SOCIAL_FACEBOOK', 'Facebook');
- define('SOCIAL_GITHUB', 'Github');
+ define('SOCIAL_GITHUB', 'GitHub');
define('SOCIAL_LINKEDIN', 'LinkedIn');
diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php
index 60548af6ca7c..4c50b1059955 100644
--- a/app/Libraries/Utils.php
+++ b/app/Libraries/Utils.php
@@ -672,31 +672,6 @@ class Utils
fwrite($output, "\n");
}
- public static function stringToObjectResolution($baseObject, $rawPath)
- {
- $val = '';
-
- if (!is_object($baseObject)) {
- return $val;
- }
-
- $path = preg_split('/->/', $rawPath);
- $node = $baseObject;
-
- while (($prop = array_shift($path)) !== null) {
- if (property_exists($node, $prop)) {
- $val = $node->$prop;
- $node = $node->$prop;
- } else if (is_object($node) && isset($node->$prop)) {
- $node = $node->{$prop};
- } else if ( method_exists($node, $prop)) {
- $val = call_user_func(array($node, $prop));
- }
- }
-
- return $val;
- }
-
public static function getFirst($values) {
if (is_array($values)) {
return count($values) ? $values[0] : false;
@@ -753,4 +728,12 @@ class Utils
}
return $domain;
}
+
+ public static function splitName($name) {
+ $name = trim($name);
+ $lastName = (strpos($name, ' ') === false) ? '' : preg_replace('#.*\s([\w-]*)$#', '$1', $name);
+ $firstName = trim( preg_replace('#'.$lastName.'#', '', $name ) );
+ return array($firstName, $lastName);
+ }
+
}
diff --git a/app/Listeners/HandleUserSignedUp.php b/app/Listeners/HandleUserSignedUp.php
index 8d45d3e5a62a..5bc4eab28d97 100644
--- a/app/Listeners/HandleUserSignedUp.php
+++ b/app/Listeners/HandleUserSignedUp.php
@@ -1,37 +1,52 @@
-accountRepo = $accountRepo;
+ $this->userMailer = $userMailer;
}
- /**
- * Handle the event.
- *
- * @param UserSignedUp $event
- * @return void
- */
- public function handle(UserSignedUp $event)
- {
- if (!Utils::isNinjaProd()) {
- $this->accountRepo->registerUser(Auth::user());
- }
- }
+ /**
+ * Handle the event.
+ *
+ * @param UserSignedUp $event
+ * @return void
+ */
+ public function handle(UserSignedUp $event)
+ {
+ $user = Auth::user();
+ if (Utils::isNinjaProd()) {
+ $this->userMailer->sendConfirmation($user);
+ } elseif (Utils::isNinjaDev()) {
+ // do nothing
+ } else {
+ $this->accountRepo->registerNinjaUser($user);
+ }
+
+ $activities = Activity::scope()->get();
+ foreach ($activities as $activity) {
+ $activity->message = str_replace('Guest', $user->getFullName(), $activity->message);
+ $activity->save();
+ }
+
+ session([SESSION_COUNTER => -1]);
+ }
}
diff --git a/app/Models/Activity.php b/app/Models/Activity.php
index b910cac6a350..edb20a7c96e0 100644
--- a/app/Models/Activity.php
+++ b/app/Models/Activity.php
@@ -149,8 +149,13 @@ class Activity extends Eloquent
public static function emailInvoice($invitation)
{
- $adjustment = 0;
- $client = $invitation->invoice->client;
+ $invoice = $invitation->invoice;
+ $client = $invoice->client;
+
+ if (!$invoice->isSent()) {
+ $invoice->invoice_status_id = INVOICE_STATUS_SENT;
+ $invoice->save();
+ }
$activity = Activity::getBlank($invitation);
$activity->client_id = $invitation->invoice->client_id;
diff --git a/app/Models/Invitation.php b/app/Models/Invitation.php
index 8e6f58c94c15..b42bcfbaa80b 100644
--- a/app/Models/Invitation.php
+++ b/app/Models/Invitation.php
@@ -39,15 +39,35 @@ class Invitation extends EntityModel
if ($iframe_url) {
return "{$iframe_url}/?{$this->invitation_key}";
- } else if ($this->account->subdomain) {
+ } elseif ($this->account->subdomain) {
$url = Utils::replaceSubdomain($url, $this->account->subdomain);
}
return "{$url}/view/{$this->invitation_key}";
}
+ public function getStatus()
+ {
+ $hasValue = false;
+ $parts = [];
+ $statuses = $this->message_id ? ['sent', 'opened', 'viewed'] : ['sent', 'viewed'];
+
+ foreach ($statuses as $status) {
+ $field = "{$status}_date";
+ $date = '';
+ if ($this->$field) {
+ $date = Utils::dateToString($this->$field);
+ $hasValue = true;
+ }
+ $parts[] = trans('texts.invitation_status.' . $status) . ': ' . $date;
+ }
+
+ return $hasValue ? implode($parts, '
') : false;
+ }
+
public function getName()
{
return $this->invitation_key;
}
+
}
diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php
index 417a227db84f..9233d3da2188 100644
--- a/app/Models/Invoice.php
+++ b/app/Models/Invoice.php
@@ -140,6 +140,8 @@ class Invoice extends EntityModel
'custom_taxes2',
'partial',
'has_tasks',
+ 'custom_text_value1',
+ 'custom_text_value2',
]);
$this->client->setVisible([
@@ -187,6 +189,8 @@ class Invoice extends EntityModel
'custom_invoice_label2',
'pdf_email_attachment',
'show_item_taxes',
+ 'custom_invoice_text_label1',
+ 'custom_invoice_text_label2',
]);
foreach ($this->invoice_items as $invoiceItem) {
@@ -283,7 +287,7 @@ class Invoice extends EntityModel
public function updateCachedPDF($encodedString = false)
{
- if (!$encodedString) {
+ if (!$encodedString && env('PHANTOMJS_CLOUD_KEY')) {
$invitation = $this->invitations[0];
$link = $invitation->getLink();
diff --git a/app/Ninja/Mailers/ContactMailer.php b/app/Ninja/Mailers/ContactMailer.php
index e269f91fedea..e7200609c529 100644
--- a/app/Ninja/Mailers/ContactMailer.php
+++ b/app/Ninja/Mailers/ContactMailer.php
@@ -31,70 +31,71 @@ class ContactMailer extends Mailer
$invoice->updateCachedPDF();
}
- $view = 'invoice';
- $accountName = $invoice->account->getDisplayName();
- $emailTemplate = $invoice->account->getEmailTemplate($reminder ?: $entityType);
- $emailSubject = $invoice->account->getEmailSubject($reminder ?: $entityType);
+ $emailTemplate = $account->getEmailTemplate($reminder ?: $entityType);
+ $emailSubject = $account->getEmailSubject($reminder ?: $entityType);
- $this->initClosure($invoice);
- $response = false;
$sent = false;
foreach ($invoice->invitations as $invitation) {
- if (Auth::check()) {
- $user = Auth::user();
- } else {
- $user = $invitation->user;
- if ($invitation->user->trashed()) {
- $user = $account->users()->orderBy('id')->first();
- }
- }
-
- if (!$user->email || !$user->confirmed) {
- continue;
- }
-
- if (!$invitation->contact->email
- || $invitation->contact->trashed()) {
- continue;
- }
-
- $invitation->sent_date = \Carbon::now()->toDateTimeString();
- $invitation->save();
-
- $variables = [
- 'account' => $account,
- 'client' => $client,
- 'invitation' => $invitation,
- 'amount' => $invoice->getRequestedAmount()
- ];
-
- $data['body'] = $this->processVariables($emailTemplate, $variables);
- $data['link'] = $invitation->getLink();
- $data['entityType'] = $entityType;
- $data['invoice_id'] = $invoice->id;
-
- $subject = $this->processVariables($emailSubject, $variables);
- $fromEmail = $user->email;
- $response = $this->sendTo($invitation->contact->email, $fromEmail, $accountName, $subject, $view, $data);
-
- if ($response === true) {
+ if ($this->sendInvitation($invitation, $invoice, $emailTemplate, $emailSubject)) {
$sent = true;
- Activity::emailInvoice($invitation);
}
}
+ $account->loadLocalizationSettings();
+
if ($sent === true) {
- if (!$invoice->isSent()) {
- $invoice->invoice_status_id = INVOICE_STATUS_SENT;
- $invoice->save();
- }
-
- $account->loadLocalizationSettings();
Event::fire(new InvoiceSent($invoice));
}
- return $response ?: trans('texts.email_error');
+ return $sent ?: trans('texts.email_error');
+ }
+
+ private function sendInvitation($invitation, $invoice, $body, $subject)
+ {
+ $client = $invoice->client;
+ $account = $invoice->account;
+
+ if (Auth::check()) {
+ $user = Auth::user();
+ } else {
+ $user = $invitation->user;
+ if ($invitation->user->trashed()) {
+ $user = $account->users()->orderBy('id')->first();
+ }
+ }
+
+ if (!$user->email || !$user->confirmed) {
+ return false;
+ }
+
+ if (!$invitation->contact->email || $invitation->contact->trashed()) {
+ return false;
+ }
+
+ $variables = [
+ 'account' => $account,
+ 'client' => $client,
+ 'invitation' => $invitation,
+ 'amount' => $invoice->getRequestedAmount()
+ ];
+
+ $data['body'] = $this->processVariables($body, $variables);
+ $data['link'] = $invitation->getLink();
+ $data['entityType'] = $invoice->getEntityType();
+ $data['invoiceId'] = $invoice->id;
+ $data['invitation'] = $invitation;
+
+ $subject = $this->processVariables($subject, $variables);
+ $fromEmail = $user->email;
+ $response = $this->sendTo($invitation->contact->email, $fromEmail, $account->getDisplayName(), $subject, ENTITY_INVOICE, $data);
+
+ if ($response === true) {
+ Activity::emailInvoice($invitation);
+ return true;
+ } else {
+ return false;
+ }
}
public function sendPaymentConfirmation(Payment $payment)
@@ -110,8 +111,6 @@ class ContactMailer extends Mailer
$emailTemplate = $account->getEmailTemplate(ENTITY_PAYMENT);
$emailSubject = $invoice->account->getEmailSubject(ENTITY_PAYMENT);
- $this->initClosure($invoice);
-
if ($payment->invitation) {
$user = $payment->invitation->user;
$contact = $payment->contact;
@@ -190,26 +189,7 @@ class ContactMailer extends Mailer
}
$str = str_replace(array_keys($variables), array_values($variables), $template);
- $str = preg_replace_callback('/\{\{\$?(.*)\}\}/', $this->advancedTemplateHandler, $str);
return $str;
}
-
- private function initClosure($object)
- {
- $this->advancedTemplateHandler = function($match) use ($object) {
- for ($i = 1; $i < count($match); $i++) {
- $blobConversion = $match[$i];
-
- if (isset($$blobConversion)) {
- return $$blobConversion;
- } else if (preg_match('/trans\(([\w\.]+)\)/', $blobConversion, $regexTranslation)) {
- return trans($regexTranslation[1]);
- } else if (strpos($blobConversion, '->') !== false) {
- return Utils::stringToObjectResolution($object, $blobConversion);
- }
-
- }
- };
- }
}
diff --git a/app/Ninja/Mailers/Mailer.php b/app/Ninja/Mailers/Mailer.php
index 6162f3bd4323..dfe44015d24a 100644
--- a/app/Ninja/Mailers/Mailer.php
+++ b/app/Ninja/Mailers/Mailer.php
@@ -9,8 +9,7 @@ class Mailer
{
public function sendTo($toEmail, $fromEmail, $fromName, $subject, $view, $data = [])
{
- // https://github.com/wildbit/laravel-postmark-provider/issues/2
- if (isset($data['invoice_id']) && isset($_ENV['POSTMARK_API_TOKEN'])) {
+ if (isset($_ENV['POSTMARK_API_TOKEN'])) {
$views = 'emails.'.$view.'_html';
} else {
$views = [
@@ -20,7 +19,7 @@ class Mailer
}
try {
- Mail::send($views, $data, function ($message) use ($toEmail, $fromEmail, $fromName, $subject, $data) {
+ $response = Mail::send($views, $data, function ($message) use ($toEmail, $fromEmail, $fromName, $subject, $data) {
$toEmail = strtolower($toEmail);
$replyEmail = $fromEmail;
@@ -31,8 +30,9 @@ class Mailer
->replyTo($replyEmail, $fromName)
->subject($subject);
- if (isset($data['invoice_id'])) {
- $invoice = Invoice::with('account')->where('id', '=', $data['invoice_id'])->first();
+ // Attach the PDF to the email
+ if (isset($data['invoiceId'])) {
+ $invoice = Invoice::with('account')->where('id', '=', $data['invoiceId'])->first();
if ($invoice->account->pdf_email_attachment && file_exists($invoice->getPDFPath())) {
$message->attach(
$invoice->getPDFPath(),
@@ -41,17 +41,50 @@ class Mailer
}
}
});
-
- return true;
+
+ return $this->handleSuccess($response, $data);
} catch (Exception $exception) {
- Utils::logError('Email Error: ' . $exception->getMessage());
- if (isset($_ENV['POSTMARK_API_TOKEN'])) {
- $response = $exception->getResponse()->getBody()->getContents();
- $response = json_decode($response);
- return nl2br($response->Message);
- } else {
- return $exception->getMessage();
- }
+ return $this->handleFailure($exception);
}
}
+
+ private function handleSuccess($response, $data)
+ {
+ if (isset($data['invitation'])) {
+ $invitation = $data['invitation'];
+
+ // Track the Postmark message id
+ if (isset($_ENV['POSTMARK_API_TOKEN'])) {
+ $json = $response->json();
+ $invitation->message_id = $json['MessageID'];
+ }
+
+ $invitation->email_error = null;
+ $invitation->sent_date = \Carbon::now()->toDateTimeString();
+ $invitation->save();
+ }
+
+ return true;
+ }
+
+ private function handleFailure($exception)
+ {
+ if (isset($_ENV['POSTMARK_API_TOKEN'])) {
+ $response = $exception->getResponse()->getBody()->getContents();
+ $response = json_decode($response);
+ $emailError = nl2br($response->Message);
+ } else {
+ $emailError = $exception->getMessage();
+ }
+
+ Utils::logError("Email Error: $emailError");
+
+ if (isset($data['invitation'])) {
+ $invitation = $data['invitation'];
+ $invitation->email_error = $emailError;
+ $invitation->save();
+ }
+
+ return $emailError;
+ }
}
diff --git a/app/Ninja/Mailers/UserMailer.php b/app/Ninja/Mailers/UserMailer.php
index 3f2b4290a7eb..6ca98609b639 100644
--- a/app/Ninja/Mailers/UserMailer.php
+++ b/app/Ninja/Mailers/UserMailer.php
@@ -2,6 +2,7 @@
use Utils;
+use App\Models\Invitation;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\User;
@@ -60,4 +61,27 @@ class UserMailer extends Mailer
$this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data);
}
+
+ public function sendEmailBounced(Invitation $invitation)
+ {
+ $user = $invitation->user;
+ $invoice = $invitation->invoice;
+ $entityType = $invoice->getEntityType();
+
+ if (!$user->email) {
+ return;
+ }
+
+ $subject = trans("texts.notification_{$entityType}_bounced_subject", ['invoice' => $invoice->invoice_number]);
+ $view = 'email_bounced';
+ $data = [
+ 'userName' => $user->getDisplayName(),
+ 'emailError' => $invitation->email_error,
+ 'entityType' => $entityType,
+ 'contactName' => $invitation->contact->getDisplayName(),
+ 'invoiceNumber' => $invoice->invoice_number,
+ ];
+
+ $this->sendTo($user->email, CONTACT_EMAIL, CONTACT_NAME, $subject, $view, $data);
+ }
}
diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php
index d2e4af8b8702..d1bf2cadbced 100644
--- a/app/Ninja/Repositories/AccountRepository.php
+++ b/app/Ninja/Repositories/AccountRepository.php
@@ -6,6 +6,7 @@ use Session;
use Utils;
use DB;
use stdClass;
+use Validator;
use Schema;
use App\Models\AccountGateway;
use App\Models\Invitation;
@@ -49,6 +50,9 @@ class AccountRepository
$user->first_name = $firstName;
$user->last_name = $lastName;
$user->email = $user->username = $email;
+ if (!$password) {
+ $password = str_random(RANDOM_KEY_LENGTH);
+ }
$user->password = bcrypt($password);
}
@@ -231,7 +235,37 @@ class AccountRepository
return $client;
}
- public function registerUser($user)
+ public function unlinkUserFromOauth($user)
+ {
+ $user->oauth_provider_id = null;
+ $user->oauth_user_id = null;
+ $user->save();
+ }
+
+ public function updateUserFromOauth($user, $firstName, $lastName, $email, $providerId, $oauthUserId)
+ {
+ if (!$user->registered) {
+ $rules = ['email' => 'email|required|unique:users,email,'.$user->id.',id'];
+ $validator = Validator::make(['email' => $email], $rules);
+ if ($validator->fails()) {
+ $messages = $validator->messages();
+ return $messages->first('email');
+ }
+
+ $user->email = $email;
+ $user->first_name = $firstName;
+ $user->last_name = $lastName;
+ $user->registered = true;
+ }
+
+ $user->oauth_provider_id = $providerId;
+ $user->oauth_user_id = $oauthUserId;
+ $user->save();
+
+ return true;
+ }
+
+ public function registerNinjaUser($user)
{
if ($user->email == TEST_USERNAME) {
return false;
@@ -259,6 +293,13 @@ class AccountRepository
curl_close($ch);
}
+ public function findUserByOauth($providerId, $oauthUserId)
+ {
+ return User::where('oauth_user_id', $oauthUserId)
+ ->where('oauth_provider_id', $providerId)
+ ->first();
+ }
+
public function findUserAccounts($userId1, $userId2 = false)
{
if (!Schema::hasTable('user_accounts')) {
diff --git a/app/Ninja/Repositories/InvoiceRepository.php b/app/Ninja/Repositories/InvoiceRepository.php
index 054b8d19739a..ea5d2251240e 100644
--- a/app/Ninja/Repositories/InvoiceRepository.php
+++ b/app/Ninja/Repositories/InvoiceRepository.php
@@ -374,6 +374,13 @@ class InvoiceRepository
$invoice->custom_taxes1 = $data['custom_taxes1'] ? true : false;
$invoice->custom_taxes2 = $data['custom_taxes2'] ? true : false;
+ if (isset($data['custom_text_value1'])) {
+ $invoice->custom_text_value1 = trim($data['custom_text_value1']);
+ }
+ if (isset($data['custom_text_value2'])) {
+ $invoice->custom_text_value2 = trim($data['custom_text_value2']);
+ }
+
// custom fields charged taxes
if ($invoice->custom_value1 && $invoice->custom_taxes1) {
$total += $invoice->custom_value1;
@@ -497,7 +504,9 @@ class InvoiceRepository
'custom_value2',
'custom_taxes1',
'custom_taxes2',
- 'partial'] as $field) {
+ 'partial',
+ 'custom_text_value1',
+ 'custom_text_value2'] as $field) {
$clone->$field = $invoice->$field;
}
@@ -615,6 +624,8 @@ class InvoiceRepository
$invoice->custom_value2 = $recurInvoice->custom_value2;
$invoice->custom_taxes1 = $recurInvoice->custom_taxes1;
$invoice->custom_taxes2 = $recurInvoice->custom_taxes2;
+ $invoice->custom_text_value1 = $recurInvoice->custom_text_value1;
+ $invoice->custom_text_value2 = $recurInvoice->custom_text_value2;
$invoice->is_amount_discount = $recurInvoice->is_amount_discount;
if ($invoice->client->payment_terms != 0) {
diff --git a/app/Services/AuthService.php b/app/Services/AuthService.php
new file mode 100644
index 000000000000..9244dcdb6133
--- /dev/null
+++ b/app/Services/AuthService.php
@@ -0,0 +1,85 @@
+ SOCIAL_GOOGLE,
+ 2 => SOCIAL_FACEBOOK,
+ 3 => SOCIAL_GITHUB,
+ 4 => SOCIAL_LINKEDIN
+ ];
+
+ public function __construct(AccountRepository $repo)
+ {
+ $this->accountRepo = $repo;
+ }
+
+ public function execute($provider, $hasCode)
+ {
+ if (!$hasCode) {
+ return $this->getAuthorization($provider);
+ }
+
+ $socialiteUser = Socialite::driver($provider)->user();
+ $providerId = AuthService::getProviderId($provider);
+
+ if (Auth::check()) {
+ $user = Auth::user();
+ $isRegistered = $user->registered;
+
+ $email = $socialiteUser->email;
+ $oauthUserId = $socialiteUser->id;
+ $name = Utils::splitName($socialiteUser->name);
+ $result = $this->accountRepo->updateUserFromOauth($user, $name[0], $name[1], $email, $providerId, $oauthUserId);
+
+ if ($result === true) {
+ if (!$isRegistered) {
+ event(new UserSignedUp());
+ Session::flash('warning', trans('texts.success_message'));
+ } else {
+ Session::flash('message', trans('texts.updated_settings'));
+ return redirect()->to('/company/details');
+ }
+ } else {
+ Session::flash('error', $result);
+ }
+ } else {
+ if ($user = $this->accountRepo->findUserByOauth($providerId, $socialiteUser->id)) {
+ Auth::login($user, true);
+ event(new UserLoggedIn());
+ } else {
+ Session::flash('error', trans('texts.invalid_credentials'));
+ return redirect()->to('login');
+ }
+ }
+
+ $redirectTo = Input::get('redirect_to') ?: 'dashboard';
+ return redirect()->to($redirectTo);
+ }
+
+ private function getAuthorization($provider)
+ {
+ return Socialite::driver($provider)->redirect();
+ }
+
+ public static function getProviderId($provider)
+ {
+ return array_search(strtolower($provider), array_map('strtolower', AuthService::$providers));
+ }
+
+ public static function getProviderName($providerId)
+ {
+ return $providerId ? AuthService::$providers[$providerId] : '';
+ }
+}
diff --git a/app/Services/EmailService.php b/app/Services/EmailService.php
new file mode 100644
index 000000000000..47e130810496
--- /dev/null
+++ b/app/Services/EmailService.php
@@ -0,0 +1,48 @@
+userMailer = $userMailer;
+ }
+
+ public function markOpened($messageId)
+ {
+ $invitation = Invitation::whereMessageId($messageId)
+ ->first();
+
+ if (!$invitation) {
+ return false;
+ }
+
+ $invitation->opened_date = Carbon::now()->toDateTimeString();
+ $invitation->save();
+
+ return true;
+ }
+
+ public function markBounced($messageId, $error)
+ {
+ $invitation = Invitation::with('user', 'invoice', 'contact')
+ ->whereMessageId($messageId)
+ ->first();
+
+ if (!$invitation) {
+ return false;
+ }
+
+ $invitation->email_error = $error;
+ $invitation->save();
+
+ $this->userMailer->sendEmailBounced($invitation);
+
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/app/Services/PaymentService.php b/app/Services/PaymentService.php
index 9fa0d58e50e0..3d82cd4d39a8 100644
--- a/app/Services/PaymentService.php
+++ b/app/Services/PaymentService.php
@@ -214,15 +214,16 @@ class PaymentService {
$account = $invoice->account;
$invitation = $invoice->invitations->first();
$accountGateway = $account->getGatewayConfig(GATEWAY_STRIPE);
+ $token = $client->getGatewayToken();
- if (!$invitation || !$accountGateway) {
+ if (!$invitation || !$accountGateway || !$token) {
return false;
}
// setup the gateway/payment info
$gateway = $this->createGateway($accountGateway);
$details = $this->getPaymentDetails($invitation);
- $details['cardReference'] = $client->getGatewayToken();
+ $details['cardReference'] = $token;
// submit purchase/get response
$response = $gateway->purchase($details)->send();
diff --git a/composer.json b/composer.json
index 4fa692e16924..4427ad4a1d00 100644
--- a/composer.json
+++ b/composer.json
@@ -37,7 +37,8 @@
"guzzlehttp/guzzle": "~5.0",
"laravelcollective/html": "~5.0",
"wildbit/laravel-postmark-provider": "dev-master",
- "Dwolla/omnipay-dwolla": "dev-master"
+ "Dwolla/omnipay-dwolla": "dev-master",
+ "laravel/socialite": "~2.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0",
diff --git a/composer.lock b/composer.lock
index d7295a127c92..fa625eb6b2cd 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "064b3e3608e030ecf2bfbf705b02ca5a",
+ "hash": "48ed13e4113a177339d3a20f31dbc6bb",
"packages": [
{
"name": "alfaproject/omnipay-neteller",
@@ -120,12 +120,12 @@
"source": {
"type": "git",
"url": "https://github.com/formers/former.git",
- "reference": "a2fbec9d29cf820d54dfa6f0ddb875339d77e930"
+ "reference": "9e75217536bf6c377318e5a6f68d4c1f96a8ae3b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/formers/former/zipball/a2fbec9d29cf820d54dfa6f0ddb875339d77e930",
- "reference": "a2fbec9d29cf820d54dfa6f0ddb875339d77e930",
+ "url": "https://api.github.com/repos/formers/former/zipball/9e75217536bf6c377318e5a6f68d4c1f96a8ae3b",
+ "reference": "9e75217536bf6c377318e5a6f68d4c1f96a8ae3b",
"shasum": ""
},
"require": {
@@ -171,7 +171,7 @@
"foundation",
"laravel"
],
- "time": "2015-06-01 18:46:46"
+ "time": "2015-09-24 15:56:30"
},
{
"name": "anahkiasen/html-object",
@@ -214,16 +214,16 @@
},
{
"name": "barryvdh/laravel-debugbar",
- "version": "v2.0.5",
+ "version": "v2.0.6",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git",
- "reference": "753106cd1f9c724d05bb48728bc652231174e279"
+ "reference": "23672cbbe78278ff1fdb258caa0b1de7b5d0bc0c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/753106cd1f9c724d05bb48728bc652231174e279",
- "reference": "753106cd1f9c724d05bb48728bc652231174e279",
+ "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/23672cbbe78278ff1fdb258caa0b1de7b5d0bc0c",
+ "reference": "23672cbbe78278ff1fdb258caa0b1de7b5d0bc0c",
"shasum": ""
},
"require": {
@@ -235,7 +235,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-master": "2.1-dev"
}
},
"autoload": {
@@ -264,7 +264,7 @@
"profiler",
"webprofiler"
],
- "time": "2015-07-09 14:51:59"
+ "time": "2015-09-09 11:39:27"
},
{
"name": "barryvdh/laravel-ide-helper",
@@ -702,16 +702,16 @@
},
{
"name": "doctrine/annotations",
- "version": "v1.2.6",
+ "version": "v1.2.7",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
- "reference": "f4a91702ca3cd2e568c3736aa031ed00c3752af4"
+ "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/annotations/zipball/f4a91702ca3cd2e568c3736aa031ed00c3752af4",
- "reference": "f4a91702ca3cd2e568c3736aa031ed00c3752af4",
+ "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
+ "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535",
"shasum": ""
},
"require": {
@@ -766,20 +766,20 @@
"docblock",
"parser"
],
- "time": "2015-06-17 12:21:22"
+ "time": "2015-08-31 12:32:49"
},
{
"name": "doctrine/cache",
- "version": "v1.4.1",
+ "version": "v1.4.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
- "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03"
+ "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/cache/zipball/c9eadeb743ac6199f7eec423cb9426bc518b7b03",
- "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03",
+ "url": "https://api.github.com/repos/doctrine/cache/zipball/8c434000f420ade76a07c64cbe08ca47e5c101ca",
+ "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca",
"shasum": ""
},
"require": {
@@ -836,7 +836,7 @@
"cache",
"caching"
],
- "time": "2015-04-15 00:11:59"
+ "time": "2015-08-31 12:36:41"
},
{
"name": "doctrine/collections",
@@ -906,16 +906,16 @@
},
{
"name": "doctrine/common",
- "version": "v2.5.0",
+ "version": "v2.5.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/common.git",
- "reference": "cd8daf2501e10c63dced7b8b9b905844316ae9d3"
+ "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/common/zipball/cd8daf2501e10c63dced7b8b9b905844316ae9d3",
- "reference": "cd8daf2501e10c63dced7b8b9b905844316ae9d3",
+ "url": "https://api.github.com/repos/doctrine/common/zipball/0009b8f0d4a917aabc971fb089eba80e872f83f9",
+ "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9",
"shasum": ""
},
"require": {
@@ -975,20 +975,20 @@
"persistence",
"spl"
],
- "time": "2015-04-02 19:55:44"
+ "time": "2015-08-31 13:00:22"
},
{
"name": "doctrine/dbal",
- "version": "v2.5.1",
+ "version": "v2.5.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
- "reference": "628c2256b646ae2417d44e063bce8aec5199d48d"
+ "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/dbal/zipball/628c2256b646ae2417d44e063bce8aec5199d48d",
- "reference": "628c2256b646ae2417d44e063bce8aec5199d48d",
+ "url": "https://api.github.com/repos/doctrine/dbal/zipball/01dbcbc5cd0a913d751418e635434a18a2f2a75c",
+ "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c",
"shasum": ""
},
"require": {
@@ -1046,7 +1046,7 @@
"persistence",
"queryobject"
],
- "time": "2015-01-12 21:52:47"
+ "time": "2015-09-16 16:29:33"
},
{
"name": "doctrine/inflector",
@@ -1646,12 +1646,12 @@
"source": {
"type": "git",
"url": "https://github.com/Intervention/image.git",
- "reference": "1124ff3c6298f0dcf9edf9156623904d7a5c3428"
+ "reference": "44c9a6bb292e50cf8a1e4b5030c7954c2709c089"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Intervention/image/zipball/1124ff3c6298f0dcf9edf9156623904d7a5c3428",
- "reference": "1124ff3c6298f0dcf9edf9156623904d7a5c3428",
+ "url": "https://api.github.com/repos/Intervention/image/zipball/44c9a6bb292e50cf8a1e4b5030c7954c2709c089",
+ "reference": "44c9a6bb292e50cf8a1e4b5030c7954c2709c089",
"shasum": ""
},
"require": {
@@ -1700,7 +1700,7 @@
"thumbnail",
"watermark"
],
- "time": "2015-08-16 15:31:59"
+ "time": "2015-08-30 15:37:50"
},
{
"name": "ircmaxell/password-compat",
@@ -2055,6 +2055,60 @@
],
"time": "2015-06-09 13:12:19"
},
+ {
+ "name": "laravel/socialite",
+ "version": "v2.0.13",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel/socialite.git",
+ "reference": "5995d2c9c60b47362412a84286e2a0707e0db386"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel/socialite/zipball/5995d2c9c60b47362412a84286e2a0707e0db386",
+ "reference": "5995d2c9c60b47362412a84286e2a0707e0db386",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "~5.0|~6.0",
+ "illuminate/contracts": "~5.0",
+ "illuminate/http": "~5.0",
+ "illuminate/support": "~5.0",
+ "league/oauth1-client": "~1.0",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "~0.9",
+ "phpunit/phpunit": "~4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Laravel\\Socialite\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylorotwell@gmail.com"
+ }
+ ],
+ "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.",
+ "keywords": [
+ "laravel",
+ "oauth"
+ ],
+ "time": "2015-09-24 20:59:56"
+ },
{
"name": "laravelcollective/html",
"version": "v5.0.4",
@@ -2107,21 +2161,24 @@
},
{
"name": "league/flysystem",
- "version": "1.0.11",
+ "version": "1.0.15",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
- "reference": "c16222fdc02467eaa12cb6d6d0e65527741f6040"
+ "reference": "31525caf9e8772683672fefd8a1ca0c0736020f4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/c16222fdc02467eaa12cb6d6d0e65527741f6040",
- "reference": "c16222fdc02467eaa12cb6d6d0e65527741f6040",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/31525caf9e8772683672fefd8a1ca0c0736020f4",
+ "reference": "31525caf9e8772683672fefd8a1ca0c0736020f4",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
+ "conflict": {
+ "league/flysystem-sftp": "<1.0.6"
+ },
"require-dev": {
"ext-fileinfo": "*",
"mockery/mockery": "~0.9",
@@ -2184,7 +2241,70 @@
"sftp",
"storage"
],
- "time": "2015-07-28 20:41:58"
+ "time": "2015-09-30 22:26:59"
+ },
+ {
+ "name": "league/oauth1-client",
+ "version": "1.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/oauth1-client.git",
+ "reference": "4d4edd9b6014f882e319231a9b3351e3a1dfdc81"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/4d4edd9b6014f882e319231a9b3351e3a1dfdc81",
+ "reference": "4d4edd9b6014f882e319231a9b3351e3a1dfdc81",
+ "shasum": ""
+ },
+ "require": {
+ "guzzle/guzzle": "3.*",
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "~0.9",
+ "phpunit/phpunit": "~4.0",
+ "squizlabs/php_codesniffer": "~2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "League\\OAuth1\\": "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"
+ ],
+ "time": "2015-08-22 09:49:14"
},
{
"name": "lokielse/omnipay-alipay",
@@ -2192,12 +2312,12 @@
"source": {
"type": "git",
"url": "https://github.com/lokielse/omnipay-alipay.git",
- "reference": "f34ed8783943e01e8ed78abdbbaae487181ce3ba"
+ "reference": "87622e8549b50773a8db83c93c3ad9a22e618991"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/lokielse/omnipay-alipay/zipball/f34ed8783943e01e8ed78abdbbaae487181ce3ba",
- "reference": "f34ed8783943e01e8ed78abdbbaae487181ce3ba",
+ "url": "https://api.github.com/repos/lokielse/omnipay-alipay/zipball/87622e8549b50773a8db83c93c3ad9a22e618991",
+ "reference": "87622e8549b50773a8db83c93c3ad9a22e618991",
"shasum": ""
},
"require": {
@@ -2233,7 +2353,7 @@
"payment",
"purchase"
],
- "time": "2015-08-18 17:43:49"
+ "time": "2015-09-15 16:43:43"
},
{
"name": "maximebf/debugbar",
@@ -2348,16 +2468,16 @@
},
{
"name": "monolog/monolog",
- "version": "1.16.0",
+ "version": "1.17.1",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
- "reference": "c0c0b4bee3aabce7182876b0d912ef2595563db7"
+ "reference": "0524c87587ab85bc4c2d6f5b41253ccb930a5422"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c0c0b4bee3aabce7182876b0d912ef2595563db7",
- "reference": "c0c0b4bee3aabce7182876b0d912ef2595563db7",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/0524c87587ab85bc4c2d6f5b41253ccb930a5422",
+ "reference": "0524c87587ab85bc4c2d6f5b41253ccb930a5422",
"shasum": ""
},
"require": {
@@ -2374,7 +2494,7 @@
"php-console/php-console": "^3.1.3",
"phpunit/phpunit": "~4.5",
"phpunit/phpunit-mock-objects": "2.3.0",
- "raven/raven": "~0.8",
+ "raven/raven": "~0.11",
"ruflin/elastica": ">=0.90 <3.0",
"swiftmailer/swiftmailer": "~5.3",
"videlalvaro/php-amqplib": "~2.4"
@@ -2420,7 +2540,7 @@
"logging",
"psr-3"
],
- "time": "2015-08-09 17:44:44"
+ "time": "2015-08-31 09:17:37"
},
{
"name": "mtdowling/cron-expression",
@@ -2515,16 +2635,16 @@
},
{
"name": "nikic/php-parser",
- "version": "v1.4.0",
+ "version": "v1.4.1",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "196f177cfefa0f1f7166c0a05d8255889be12418"
+ "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/196f177cfefa0f1f7166c0a05d8255889be12418",
- "reference": "196f177cfefa0f1f7166c0a05d8255889be12418",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51",
+ "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51",
"shasum": ""
},
"require": {
@@ -2556,7 +2676,7 @@
"parser",
"php"
],
- "time": "2015-07-14 17:31:05"
+ "time": "2015-09-19 14:15:08"
},
{
"name": "omnipay/2checkout",
@@ -3196,16 +3316,16 @@
},
{
"name": "omnipay/gocardless",
- "version": "v2.1.1",
+ "version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/omnipay-gocardless.git",
- "reference": "106c2cc2f992813319c86f45863347c238771548"
+ "reference": "1c0bebdcc32d89fd243e1183028d2d50316e8bb1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thephpleague/omnipay-gocardless/zipball/106c2cc2f992813319c86f45863347c238771548",
- "reference": "106c2cc2f992813319c86f45863347c238771548",
+ "url": "https://api.github.com/repos/thephpleague/omnipay-gocardless/zipball/1c0bebdcc32d89fd243e1183028d2d50316e8bb1",
+ "reference": "1c0bebdcc32d89fd243e1183028d2d50316e8bb1",
"shasum": ""
},
"require": {
@@ -3250,7 +3370,7 @@
"pay",
"payment"
],
- "time": "2014-09-17 00:39:16"
+ "time": "2015-09-24 14:44:29"
},
{
"name": "omnipay/manual",
@@ -4652,16 +4772,16 @@
},
{
"name": "symfony/class-loader",
- "version": "v2.7.3",
+ "version": "v2.7.5",
"source": {
"type": "git",
- "url": "https://github.com/symfony/ClassLoader.git",
- "reference": "2fccbc544997340808801a7410cdcb96dd12edc4"
+ "url": "https://github.com/symfony/class-loader.git",
+ "reference": "d957ea6295d7016e20d7eff33a6c1deef819c0d4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/ClassLoader/zipball/2fccbc544997340808801a7410cdcb96dd12edc4",
- "reference": "2fccbc544997340808801a7410cdcb96dd12edc4",
+ "url": "https://api.github.com/repos/symfony/class-loader/zipball/d957ea6295d7016e20d7eff33a6c1deef819c0d4",
+ "reference": "d957ea6295d7016e20d7eff33a6c1deef819c0d4",
"shasum": ""
},
"require": {
@@ -4698,7 +4818,7 @@
],
"description": "Symfony ClassLoader Component",
"homepage": "https://symfony.com",
- "time": "2015-06-25 12:52:11"
+ "time": "2015-08-26 17:56:37"
},
{
"name": "symfony/console",
@@ -4821,16 +4941,16 @@
},
{
"name": "symfony/event-dispatcher",
- "version": "v2.7.3",
+ "version": "v2.7.5",
"source": {
"type": "git",
- "url": "https://github.com/symfony/EventDispatcher.git",
- "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3"
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "ae4dcc2a8d3de98bd794167a3ccda1311597c5d9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/9310b5f9a87ec2ea75d20fec0b0017c77c66dac3",
- "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ae4dcc2a8d3de98bd794167a3ccda1311597c5d9",
+ "reference": "ae4dcc2a8d3de98bd794167a3ccda1311597c5d9",
"shasum": ""
},
"require": {
@@ -4875,20 +4995,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2015-06-18 19:21:56"
+ "time": "2015-09-22 13:49:29"
},
{
"name": "symfony/filesystem",
- "version": "v2.7.3",
+ "version": "v2.7.5",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Filesystem.git",
- "reference": "2d7b2ddaf3f548f4292df49a99d19c853d43f0b8"
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "a17f8a17c20e8614c15b8e116e2f4bcde102cfab"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Filesystem/zipball/2d7b2ddaf3f548f4292df49a99d19c853d43f0b8",
- "reference": "2d7b2ddaf3f548f4292df49a99d19c853d43f0b8",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/a17f8a17c20e8614c15b8e116e2f4bcde102cfab",
+ "reference": "a17f8a17c20e8614c15b8e116e2f4bcde102cfab",
"shasum": ""
},
"require": {
@@ -4924,7 +5044,7 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2015-07-09 16:07:40"
+ "time": "2015-09-09 17:42:36"
},
{
"name": "symfony/finder",
@@ -5513,12 +5633,12 @@
"source": {
"type": "git",
"url": "https://github.com/webpatser/laravel-countries.git",
- "reference": "3142b86c71908a8e63dec07bc8fe48abff9902dd"
+ "reference": "e29dcce821f2c4a522e35483c38632ca534db4ee"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webpatser/laravel-countries/zipball/3142b86c71908a8e63dec07bc8fe48abff9902dd",
- "reference": "3142b86c71908a8e63dec07bc8fe48abff9902dd",
+ "url": "https://api.github.com/repos/webpatser/laravel-countries/zipball/e29dcce821f2c4a522e35483c38632ca534db4ee",
+ "reference": "e29dcce821f2c4a522e35483c38632ca534db4ee",
"shasum": ""
},
"require": {
@@ -5557,7 +5677,7 @@
"iso_3166_3",
"laravel"
],
- "time": "2015-06-10 07:52:21"
+ "time": "2015-08-21 12:12:14"
},
{
"name": "wildbit/laravel-postmark-provider",
@@ -5679,23 +5799,23 @@
},
{
"name": "codeception/codeception",
- "version": "2.1.2",
+ "version": "2.1.3",
"source": {
"type": "git",
"url": "https://github.com/Codeception/Codeception.git",
- "reference": "521adbb2ee34e9debdd8508a2c41ab2b5c2f042b"
+ "reference": "cd810cb78a869408602e17271f9b7368b09a7ca8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Codeception/Codeception/zipball/521adbb2ee34e9debdd8508a2c41ab2b5c2f042b",
- "reference": "521adbb2ee34e9debdd8508a2c41ab2b5c2f042b",
+ "url": "https://api.github.com/repos/Codeception/Codeception/zipball/cd810cb78a869408602e17271f9b7368b09a7ca8",
+ "reference": "cd810cb78a869408602e17271f9b7368b09a7ca8",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-mbstring": "*",
"facebook/webdriver": ">=1.0.1",
- "guzzlehttp/guzzle": ">=4.0|<7.0",
+ "guzzlehttp/guzzle": ">=4.1.4 <7.0",
"guzzlehttp/psr7": "~1.0",
"php": ">=5.4.0",
"phpunit/phpunit": "~4.8.0",
@@ -5755,7 +5875,7 @@
"functional testing",
"unit testing"
],
- "time": "2015-08-09 13:48:55"
+ "time": "2015-10-02 09:38:59"
},
{
"name": "doctrine/instantiator",
@@ -5942,16 +6062,16 @@
},
{
"name": "phpspec/phpspec",
- "version": "2.2.1",
+ "version": "2.3.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/phpspec.git",
- "reference": "e9a40577323e67f1de2e214abf32976a0352d8f8"
+ "reference": "36635a903bdeb54899d7407bc95610501fd98559"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/phpspec/zipball/e9a40577323e67f1de2e214abf32976a0352d8f8",
- "reference": "e9a40577323e67f1de2e214abf32976a0352d8f8",
+ "url": "https://api.github.com/repos/phpspec/phpspec/zipball/36635a903bdeb54899d7407bc95610501fd98559",
+ "reference": "36635a903bdeb54899d7407bc95610501fd98559",
"shasum": ""
},
"require": {
@@ -5963,15 +6083,14 @@
"symfony/console": "~2.3",
"symfony/event-dispatcher": "~2.1",
"symfony/finder": "~2.1",
- "symfony/process": "~2.1",
+ "symfony/process": "^2.6",
"symfony/yaml": "~2.1"
},
"require-dev": {
"behat/behat": "^3.0.11",
"bossa/phpspec2-expect": "~1.0",
"phpunit/phpunit": "~4.4",
- "symfony/filesystem": "~2.1",
- "symfony/process": "~2.1"
+ "symfony/filesystem": "~2.1"
},
"suggest": {
"phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters"
@@ -6016,7 +6135,7 @@
"testing",
"tests"
],
- "time": "2015-05-30 15:21:40"
+ "time": "2015-09-07 07:07:37"
},
{
"name": "phpspec/prophecy",
@@ -6080,16 +6199,16 @@
},
{
"name": "phpunit/php-code-coverage",
- "version": "2.2.2",
+ "version": "2.2.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c"
+ "reference": "ef1ca6835468857944d5c3b48fa503d5554cff2f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2d7c03c0e4e080901b8f33b2897b0577be18a13c",
- "reference": "2d7c03c0e4e080901b8f33b2897b0577be18a13c",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef1ca6835468857944d5c3b48fa503d5554cff2f",
+ "reference": "ef1ca6835468857944d5c3b48fa503d5554cff2f",
"shasum": ""
},
"require": {
@@ -6138,7 +6257,7 @@
"testing",
"xunit"
],
- "time": "2015-08-04 03:42:39"
+ "time": "2015-09-14 06:51:16"
},
{
"name": "phpunit/php-file-iterator",
@@ -6271,16 +6390,16 @@
},
{
"name": "phpunit/php-token-stream",
- "version": "1.4.6",
+ "version": "1.4.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b"
+ "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3ab72c62e550370a6cd5dc873e1a04ab57562f5b",
- "reference": "3ab72c62e550370a6cd5dc873e1a04ab57562f5b",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
+ "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
"shasum": ""
},
"require": {
@@ -6316,20 +6435,20 @@
"keywords": [
"tokenizer"
],
- "time": "2015-08-16 08:51:00"
+ "time": "2015-09-15 10:49:45"
},
{
"name": "phpunit/phpunit",
- "version": "4.8.4",
+ "version": "4.8.10",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "55bf1d6092b0e13a1f26bd5eaffeef3d8ad85ea7"
+ "reference": "463163747474815c5ccd4ae12b5b355ec12158e8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/55bf1d6092b0e13a1f26bd5eaffeef3d8ad85ea7",
- "reference": "55bf1d6092b0e13a1f26bd5eaffeef3d8ad85ea7",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/463163747474815c5ccd4ae12b5b355ec12158e8",
+ "reference": "463163747474815c5ccd4ae12b5b355ec12158e8",
"shasum": ""
},
"require": {
@@ -6388,24 +6507,24 @@
"testing",
"xunit"
],
- "time": "2015-08-15 04:21:23"
+ "time": "2015-10-01 09:14:30"
},
{
"name": "phpunit/phpunit-mock-objects",
- "version": "2.3.6",
+ "version": "2.3.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
- "reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42"
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/18dfbcb81d05e2296c0bcddd4db96cade75e6f42",
- "reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "~1.0,>=1.0.2",
+ "doctrine/instantiator": "^1.0.2",
"php": ">=5.3.3",
"phpunit/php-text-template": "~1.2",
"sebastian/exporter": "~1.2"
@@ -6444,7 +6563,7 @@
"mock",
"xunit"
],
- "time": "2015-07-10 06:54:24"
+ "time": "2015-10-02 06:51:40"
},
{
"name": "sebastian/comparator",
@@ -6819,16 +6938,16 @@
},
{
"name": "symfony/browser-kit",
- "version": "v2.7.3",
+ "version": "v2.7.5",
"source": {
"type": "git",
- "url": "https://github.com/symfony/BrowserKit.git",
- "reference": "176905d3d74c2f99e6ab70f4f5a89460532495ae"
+ "url": "https://github.com/symfony/browser-kit.git",
+ "reference": "277a2457776d4cc25706fbdd9d1e4ab2dac884e4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/BrowserKit/zipball/176905d3d74c2f99e6ab70f4f5a89460532495ae",
- "reference": "176905d3d74c2f99e6ab70f4f5a89460532495ae",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/277a2457776d4cc25706fbdd9d1e4ab2dac884e4",
+ "reference": "277a2457776d4cc25706fbdd9d1e4ab2dac884e4",
"shasum": ""
},
"require": {
@@ -6870,20 +6989,20 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
- "time": "2015-07-09 16:07:40"
+ "time": "2015-09-06 08:36:38"
},
{
"name": "symfony/css-selector",
- "version": "v2.7.3",
+ "version": "v2.7.5",
"source": {
"type": "git",
- "url": "https://github.com/symfony/CssSelector.git",
- "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092"
+ "url": "https://github.com/symfony/css-selector.git",
+ "reference": "abe19cc0429a06be0c133056d1f9859854860970"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/CssSelector/zipball/0b5c07b516226b7dd32afbbc82fe547a469c5092",
- "reference": "0b5c07b516226b7dd32afbbc82fe547a469c5092",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/abe19cc0429a06be0c133056d1f9859854860970",
+ "reference": "abe19cc0429a06be0c133056d1f9859854860970",
"shasum": ""
},
"require": {
@@ -6923,20 +7042,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2015-05-15 13:33:16"
+ "time": "2015-09-22 13:49:29"
},
{
"name": "symfony/dom-crawler",
- "version": "v2.7.3",
+ "version": "v2.7.5",
"source": {
"type": "git",
- "url": "https://github.com/symfony/DomCrawler.git",
- "reference": "9dabece63182e95c42b06967a0d929a5df78bc35"
+ "url": "https://github.com/symfony/dom-crawler.git",
+ "reference": "2e185ca136399f902b948694987e62c80099c052"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/DomCrawler/zipball/9dabece63182e95c42b06967a0d929a5df78bc35",
- "reference": "9dabece63182e95c42b06967a0d929a5df78bc35",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/2e185ca136399f902b948694987e62c80099c052",
+ "reference": "2e185ca136399f902b948694987e62c80099c052",
"shasum": ""
},
"require": {
@@ -6976,20 +7095,20 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
- "time": "2015-07-09 16:07:40"
+ "time": "2015-09-20 21:13:58"
},
{
"name": "symfony/yaml",
- "version": "v2.7.3",
+ "version": "v2.7.5",
"source": {
"type": "git",
- "url": "https://github.com/symfony/Yaml.git",
- "reference": "71340e996171474a53f3d29111d046be4ad8a0ff"
+ "url": "https://github.com/symfony/yaml.git",
+ "reference": "31cb2ad0155c95b88ee55fe12bc7ff92232c1770"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/Yaml/zipball/71340e996171474a53f3d29111d046be4ad8a0ff",
- "reference": "71340e996171474a53f3d29111d046be4ad8a0ff",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/31cb2ad0155c95b88ee55fe12bc7ff92232c1770",
+ "reference": "31cb2ad0155c95b88ee55fe12bc7ff92232c1770",
"shasum": ""
},
"require": {
@@ -7025,7 +7144,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2015-07-28 14:07:07"
+ "time": "2015-09-14 14:14:09"
}
],
"aliases": [],
diff --git a/config/app.php b/config/app.php
index 5b6fdff42998..00fd09f24e75 100644
--- a/config/app.php
+++ b/config/app.php
@@ -149,6 +149,7 @@ return [
'Webpatser\Countries\CountriesServiceProvider',
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
'Illuminate\Html\HtmlServiceProvider',
+ 'Laravel\Socialite\SocialiteServiceProvider',
/*
* Application Service Providers...
@@ -242,6 +243,7 @@ return [
'Countries' => 'Webpatser\Countries\CountriesFacade',
'Carbon' => 'Carbon\Carbon',
'Rocketeer' => 'Rocketeer\Facades\Rocketeer',
+ 'Socialite' => 'Laravel\Socialite\Facades\Socialite',
],
diff --git a/config/services.php b/config/services.php
index c76b0832db58..f353fddd28c7 100644
--- a/config/services.php
+++ b/config/services.php
@@ -36,4 +36,28 @@ return [
'secret' => '',
],
+ 'github' => [
+ 'client_id' => env('GITHUB_CLIENT_ID'),
+ 'client_secret' => env('GITHUB_CLIENT_SECRET'),
+ 'redirect' => 'http://ninja.dev/auth/github'
+ ],
+
+ 'google' => [
+ 'client_id' => '640903115046-dd09j2q24lcc3ilrrv5f2ft2i3n0sreg.apps.googleusercontent.com',
+ 'client_secret' => 'Vsfhldq7mRxsCXQTQI8U_4Ua',
+ 'redirect' => 'http://ninja.dev/auth/google',
+ ],
+
+ 'facebook' => [
+ 'client_id' => '635126583203143',
+ 'client_secret' => '7aa7c391019f2ece3c6aa90f4c9b1485',
+ 'redirect' => 'http://ninja.dev/auth/facebook',
+ ],
+
+ 'linkedin' => [
+ 'client_id' => '778is2j21w25xj',
+ 'client_secret' => 'DvDExxfBLXUtxc81',
+ 'redirect' => 'http://ninja.dev/auth/linkedin',
+ ],
+
];
diff --git a/database/migrations/2015_10_07_135651_add_social_login.php b/database/migrations/2015_10_07_135651_add_social_login.php
new file mode 100644
index 000000000000..ebe1975dc760
--- /dev/null
+++ b/database/migrations/2015_10_07_135651_add_social_login.php
@@ -0,0 +1,64 @@
+string('oauth_user_id')->nullable();
+ $table->unsignedInteger('oauth_provider_id')->nullable();
+ });
+
+ Schema::table('accounts', function ($table) {
+ $table->string('custom_invoice_text_label1')->nullable();
+ $table->string('custom_invoice_text_label2')->nullable();
+ });
+
+ Schema::table('invoices', function ($table) {
+ $table->string('custom_text_value1')->nullable();
+ $table->string('custom_text_value2')->nullable();
+ });
+
+ Schema::table('invitations', function ($table) {
+ $table->timestamp('opened_date')->nullable();
+ $table->string('message_id')->nullable();
+ $table->text('email_error')->nullable();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('users', function ($table) {
+ $table->dropColumn('oauth_user_id');
+ $table->dropColumn('oauth_provider_id');
+ });
+
+ Schema::table('accounts', function ($table) {
+ $table->dropColumn('custom_invoice_text_label1');
+ $table->dropColumn('custom_invoice_text_label2');
+ });
+
+ Schema::table('invoices', function ($table) {
+ $table->dropColumn('custom_text_value1');
+ $table->dropColumn('custom_text_value2');
+ });
+
+ Schema::table('invitations', function ($table) {
+ $table->dropColumn('opened_date');
+ $table->dropColumn('message_id');
+ $table->dropColumn('email_error');
+ });
+ }
+}
diff --git a/public/css/built.css b/public/css/built.css
index d49558d9566e..22367aad6388 100644
--- a/public/css/built.css
+++ b/public/css/built.css
@@ -3332,3 +3332,7 @@ ul.user-accounts a:hover div.remove {
visibility: visible;
}
+.tooltip-inner {
+ text-align:left;
+ width: 350px;
+}
\ No newline at end of file
diff --git a/public/css/style.css b/public/css/style.css
index cdd02ee90740..ddabc40c4928 100644
--- a/public/css/style.css
+++ b/public/css/style.css
@@ -982,3 +982,7 @@ ul.user-accounts a:hover div.remove {
visibility: visible;
}
+.tooltip-inner {
+ text-align:left;
+ width: 350px;
+}
\ No newline at end of file
diff --git a/public/js/built.js b/public/js/built.js
index 1f40652e3845..3b1be8b9d74f 100644
--- a/public/js/built.js
+++ b/public/js/built.js
@@ -30400,6 +30400,26 @@ if (window.ko) {
ko.applyBindingsToNode(element, { attr: { placeholder: underlyingObservable } } );
}
};
+
+ ko.bindingHandlers.tooltip = {
+ init: function(element, valueAccessor) {
+ var local = ko.utils.unwrapObservable(valueAccessor()),
+ options = {};
+
+ ko.utils.extend(options, ko.bindingHandlers.tooltip.options);
+ ko.utils.extend(options, local);
+
+ $(element).tooltip(options);
+
+ ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
+ $(element).tooltip("destroy");
+ });
+ },
+ options: {
+ placement: "bottom",
+ trigger: "hover"
+ }
+ };
}
function getContactDisplayName(contact)
@@ -31995,6 +32015,18 @@ NINJA.invoiceDetails = function(invoice) {
]
];
+ if (invoice.custom_text_value1) {
+ data.push([
+ {text: invoice.account.custom_invoice_text_label1},
+ {text: invoice.custom_text_value1}
+ ])
+ }
+ if (invoice.custom_text_value2) {
+ data.push([
+ {text: invoice.account.custom_invoice_text_label2},
+ {text: invoice.custom_text_value2}
+ ])
+ }
var isPartial = NINJA.parseFloat(invoice.partial);
@@ -32002,18 +32034,18 @@ NINJA.invoiceDetails = function(invoice) {
data.push([
{text: invoiceLabels.total},
{text: formatMoney(invoice.amount, invoice.client.currency_id)}
- ]);
+ ]);
} else if (isPartial) {
data.push([
{text: invoiceLabels.total},
{text: formatMoney(invoice.total_amount, invoice.client.currency_id)}
- ]);
+ ]);
}
data.push([
{text: isPartial ? invoiceLabels.amount_due : invoiceLabels.balance_due, style: ['invoiceDetailBalanceDueLabel']},
{text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style: ['invoiceDetailBalanceDue']}
- ])
+ ])
return NINJA.prepareDataPairs(data, 'invoiceDetails');
}
diff --git a/public/js/pdf.pdfmake.js b/public/js/pdf.pdfmake.js
index bad3cea5d5e7..fb0588113fc5 100644
--- a/public/js/pdf.pdfmake.js
+++ b/public/js/pdf.pdfmake.js
@@ -442,6 +442,18 @@ NINJA.invoiceDetails = function(invoice) {
]
];
+ if (invoice.custom_text_value1) {
+ data.push([
+ {text: invoice.account.custom_invoice_text_label1},
+ {text: invoice.custom_text_value1}
+ ])
+ }
+ if (invoice.custom_text_value2) {
+ data.push([
+ {text: invoice.account.custom_invoice_text_label2},
+ {text: invoice.custom_text_value2}
+ ])
+ }
var isPartial = NINJA.parseFloat(invoice.partial);
@@ -449,18 +461,18 @@ NINJA.invoiceDetails = function(invoice) {
data.push([
{text: invoiceLabels.total},
{text: formatMoney(invoice.amount, invoice.client.currency_id)}
- ]);
+ ]);
} else if (isPartial) {
data.push([
{text: invoiceLabels.total},
{text: formatMoney(invoice.total_amount, invoice.client.currency_id)}
- ]);
+ ]);
}
data.push([
{text: isPartial ? invoiceLabels.amount_due : invoiceLabels.balance_due, style: ['invoiceDetailBalanceDueLabel']},
{text: formatMoney(invoice.balance_amount, invoice.client.currency_id), style: ['invoiceDetailBalanceDue']}
- ])
+ ])
return NINJA.prepareDataPairs(data, 'invoiceDetails');
}
diff --git a/public/js/script.js b/public/js/script.js
index 915d9eb17424..61d58c7f8a74 100644
--- a/public/js/script.js
+++ b/public/js/script.js
@@ -522,6 +522,26 @@ if (window.ko) {
ko.applyBindingsToNode(element, { attr: { placeholder: underlyingObservable } } );
}
};
+
+ ko.bindingHandlers.tooltip = {
+ init: function(element, valueAccessor) {
+ var local = ko.utils.unwrapObservable(valueAccessor()),
+ options = {};
+
+ ko.utils.extend(options, ko.bindingHandlers.tooltip.options);
+ ko.utils.extend(options, local);
+
+ $(element).tooltip(options);
+
+ ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
+ $(element).tooltip("destroy");
+ });
+ },
+ options: {
+ placement: "bottom",
+ trigger: "hover"
+ }
+ };
}
function getContactDisplayName(contact)
diff --git a/resources/lang/da/texts.php b/resources/lang/da/texts.php
index 61a9405ecfcb..34fe4f51939f 100644
--- a/resources/lang/da/texts.php
+++ b/resources/lang/da/texts.php
@@ -796,5 +796,24 @@
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
+
);
\ No newline at end of file
diff --git a/resources/lang/de/texts.php b/resources/lang/de/texts.php
index 9b8aad70c66f..0ab602f7279c 100644
--- a/resources/lang/de/texts.php
+++ b/resources/lang/de/texts.php
@@ -795,5 +795,24 @@ return array(
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
+
);
diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php
index e86e0bc7e6ad..84e9e16fc785 100644
--- a/resources/lang/en/texts.php
+++ b/resources/lang/en/texts.php
@@ -305,7 +305,7 @@ return array(
'email_taken' => 'The email address is already registered',
'working' => 'Working',
'success' => 'Success',
- 'success_message' => 'You have successfully registered. Please visit the link in the account confirmation email to verify your email address.',
+ 'success_message' => 'You have successfully registered! Please visit the link in the account confirmation email to verify your email address.',
'erase_data' => 'This will permanently erase your data.',
'password' => 'Password',
@@ -320,7 +320,7 @@ return array(
-- email us at contact@invoiceninja.com',
'unsaved_changes' => 'You have unsaved changes',
- 'custom_fields' => 'Custom fields',
+ 'custom_fields' => 'Custom Fields',
'company_fields' => 'Company Fields',
'client_fields' => 'Client Fields',
'field_label' => 'Field Label',
@@ -769,7 +769,7 @@ return array(
'iframe_url' => 'Website',
'iframe_url_help1' => 'Copy the following code to a page on your site.',
- 'iframe_url_help2' => 'You can test the feature by clicking \'View as recipient\' for an invoice.',
+ 'iframe_url_help2' => 'Currently only supported with on-site gateways (ie, Stripe and Authorize.net). You can test the feature by clicking \'View as recipient\' for an invoice.',
'auto_bill' => 'Auto Bill',
'military_time' => '24 Hour Time',
@@ -795,6 +795,24 @@ return array(
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
);
diff --git a/resources/lang/es/texts.php b/resources/lang/es/texts.php
index c08cf53f88c2..4b8071a8fd71 100644
--- a/resources/lang/es/texts.php
+++ b/resources/lang/es/texts.php
@@ -773,5 +773,24 @@ return array(
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
+
);
diff --git a/resources/lang/es_ES/texts.php b/resources/lang/es_ES/texts.php
index 5d48d3a9a2ce..af97cee24fd6 100644
--- a/resources/lang/es_ES/texts.php
+++ b/resources/lang/es_ES/texts.php
@@ -795,5 +795,24 @@ return array(
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
+
);
\ No newline at end of file
diff --git a/resources/lang/fr/texts.php b/resources/lang/fr/texts.php
index 8f0ae4e90b80..d97faea24311 100644
--- a/resources/lang/fr/texts.php
+++ b/resources/lang/fr/texts.php
@@ -787,5 +787,24 @@ return array(
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
+
);
diff --git a/resources/lang/fr_CA/texts.php b/resources/lang/fr_CA/texts.php
index 6257451a3f31..dd014c28161c 100644
--- a/resources/lang/fr_CA/texts.php
+++ b/resources/lang/fr_CA/texts.php
@@ -788,5 +788,24 @@ return array(
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
+
);
diff --git a/resources/lang/it/texts.php b/resources/lang/it/texts.php
index 3730c16fa5b7..a3022fd5d9da 100644
--- a/resources/lang/it/texts.php
+++ b/resources/lang/it/texts.php
@@ -789,5 +789,24 @@ return array(
'page_expire' => 'This page will expire soon, :click_here to keep working',
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
);
diff --git a/resources/lang/lt/texts.php b/resources/lang/lt/texts.php
index a9a26e74c7a6..baa7f7c9e3dd 100644
--- a/resources/lang/lt/texts.php
+++ b/resources/lang/lt/texts.php
@@ -789,7 +789,6 @@ return array(
'reset' => 'Reset',
'invoice_not_found' => 'The requested invoice is not available',
-
'referral_program' => 'Referral Program',
'referral_code' => 'Referral Code',
'last_sent_on' => 'Last sent on :date',
@@ -797,6 +796,25 @@ return array(
'page_expire' => 'This page will expire soon, :click_here to keep working',
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
);
diff --git a/resources/lang/nb_NO/texts.php b/resources/lang/nb_NO/texts.php
index de8643b514dd..ae0f3691c751 100644
--- a/resources/lang/nb_NO/texts.php
+++ b/resources/lang/nb_NO/texts.php
@@ -794,5 +794,24 @@ return array(
'page_expire' => 'This page will expire soon, :click_here to keep working',
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
);
\ No newline at end of file
diff --git a/resources/lang/nl/texts.php b/resources/lang/nl/texts.php
index af7f3297ccab..e72ec1aefc20 100644
--- a/resources/lang/nl/texts.php
+++ b/resources/lang/nl/texts.php
@@ -789,5 +789,24 @@ return array(
'page_expire' => 'This page will expire soon, :click_here to keep working',
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
);
diff --git a/resources/lang/pt_BR/texts.php b/resources/lang/pt_BR/texts.php
index 2c5c00f7b414..29f7084859aa 100644
--- a/resources/lang/pt_BR/texts.php
+++ b/resources/lang/pt_BR/texts.php
@@ -789,5 +789,24 @@ return array(
'page_expire' => 'This page will expire soon, :click_here to keep working',
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
);
diff --git a/resources/lang/sv/texts.php b/resources/lang/sv/texts.php
index ca7bbdc3e2af..5754ba7647e0 100644
--- a/resources/lang/sv/texts.php
+++ b/resources/lang/sv/texts.php
@@ -792,5 +792,24 @@ return array(
'page_expire' => 'This page will expire soon, :click_here to keep working',
'upcoming_quotes' => 'Upcoming Quotes',
'expired_quotes' => 'Expired Quotes',
+
+ 'sign_up_using' => 'Sign up using',
+ 'invalid_credentials' => 'These credentials do not match our records',
+ 'show_all_options' => 'Show all options',
+ 'user_details' => 'User Details',
+ 'oneclick_login' => 'One-Click Login',
+ 'disable' => 'Disable',
+ 'invoice_quote_number' => 'Invoice and Quote Numbers',
+ 'invoice_charges' => 'Invoice Charges',
+
+ 'invitation_status' => [
+ 'sent' => 'Email Sent',
+ 'opened' => 'Email Openend',
+ 'viewed' => 'Invoice Viewed',
+ ],
+ 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.',
+ 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice',
+ 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.',
+ 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice',
);
diff --git a/resources/views/accounts/details.blade.php b/resources/views/accounts/details.blade.php
index 6b14fd06bf26..ccbda5019553 100644
--- a/resources/views/accounts/details.blade.php
+++ b/resources/views/accounts/details.blade.php
@@ -18,15 +18,13 @@
{{ Former::populate($account) }}
{{ Former::populateField('military_time', intval($account->military_time)) }}
- @if ($showUser)
- {{ Former::populateField('first_name', $primaryUser->first_name) }}
- {{ Former::populateField('last_name', $primaryUser->last_name) }}
- {{ Former::populateField('email', $primaryUser->email) }}
- {{ Former::populateField('phone', $primaryUser->phone) }}
- @if (Utils::isNinjaDev())
- {{ Former::populateField('dark_mode', intval($primaryUser->dark_mode)) }}
- @endif
- @endif
+ {{ Former::populateField('first_name', $user->first_name) }}
+ {{ Former::populateField('last_name', $user->last_name) }}
+ {{ Former::populateField('email', $user->email) }}
+ {{ Former::populateField('phone', $user->phone) }}
+ @if (Utils::isNinjaDev())
+ {{ Former::populateField('dark_mode', intval($user->dark_mode)) }}
+ @endif
- {!! Former::text('custom_label2')->label(trans('texts.field_label')) !!} - {!! Former::text('custom_value2')->label(trans('texts.field_value')) !!} +
+ {!! Former::text('custom_label2')->label(trans('texts.field_label')) !!} + {!! Former::text('custom_value2')->label(trans('texts.field_value')) !!} + +
{!! Button::success(trans(Input::get('new_company') ? 'texts.login' : 'texts.lets_go'))->large()->submit()->block() !!}
+{!! Button::success(trans('texts.login')) + ->withAttributes(['id' => 'loginButton']) + ->large()->submit()->block() !!}
@if (Input::get('new_company') && Utils::allowNewAccounts())- {{ trans('texts.or') }} -
{!! Button::primary(trans('texts.new_company'))->asLinkTo(URL::to('/invoice_now?new_company=true&sign_up=true'))->large()->submit()->block() !!}
+{!! Button::primary(trans('texts.new_company'))->asLinkTo(URL::to('/invoice_now?new_company=true&sign_up=true'))->large()->submit()->block() !!}
- {{ trans('texts.or') }} -
{!! link_to('/forgot', trans('texts.forgot_password')) !!} {!! link_to(NINJA_WEB_URL.'/knowledgebase/', trans('texts.knowledge_base'), ['target' => '_blank', 'class' => 'pull-right']) !!} @@ -103,7 +106,7 @@