1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-09 20:52:56 +01:00

Working on L5

This commit is contained in:
Hillel Coren 2015-03-31 21:50:58 +03:00
parent 4fc7e3f5d1
commit 7f69991ca8
18 changed files with 64 additions and 355 deletions

View File

@ -8,14 +8,16 @@ class InvoicePaid extends Event {
use SerializesModels;
public $payment;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
public function __construct($payment)
{
//
$this->payment = $payment;
}
}

View File

@ -8,14 +8,16 @@ class InvoiceSent extends Event {
use SerializesModels;
public $invoice;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}
public function __construct($invoice)
{
$this->invoice = $invoice;
}
}

View File

@ -3,7 +3,10 @@
use Auth;
use Utils;
use View;
use URL;
use App\Models\Client;
use App\Models\Invoice;
use App\Models\Size;
use App\Models\PaymentTerm;
use App\Models\Industry;

View File

@ -182,7 +182,6 @@ class InvoiceController extends BaseController
if (!Session::has($invitationKey) && (!Auth::check() || Auth::user()->account_id != $invoice->account_id)) {
Activity::viewInvoice($invitation);
//Event::fire('invoice.viewed', $invoice);
Event::fire(new InvoiceViewed($invoice));
}

View File

@ -15,6 +15,7 @@ use App\Ninja\Repositories\PaymentRepository;
use App\Ninja\Repositories\InvoiceRepository;
use App\Ninja\Repositories\AccountRepository;
use App\Ninja\Mailers\ContactMailer;
use App\Events\InvoicePaid;
class PaymentController extends BaseController
{
@ -669,7 +670,7 @@ class PaymentController extends BaseController
$payment->save();
Event::fire('invoice.paid', $payment);
Event::fire(new InvoicePaid($payment));
return $payment;
}

View File

@ -9,6 +9,7 @@ use Redirect;
use Cache;
use App\Models\Currency;
use App\Events\UserSettingsChanged;
class StartupCheck {
@ -106,7 +107,7 @@ class StartupCheck {
// Make sure the account/user localization settings are in the session
if (Auth::check() && !Session::has(SESSION_TIMEZONE))
{
Event::fire('user.refresh');
Event::fire(new UserSettingsChanged());
}
// Check if the user is claiming a license (ie, additional invoices, white label, etc.)

View File

@ -32,6 +32,7 @@ class HandleInvoicePaid {
public function handle(InvoicePaid $event)
{
$this->contactMailer->sendPaymentConfirmation($payment);
$invoice = $payment->invoice;
foreach ($invoice->account->users as $user)
{

View File

@ -28,6 +28,8 @@ class HandleInvoiceSent {
*/
public function handle(InvoiceSent $event)
{
$invoice = $event->invoice;
foreach ($invoice->account->users as $user)
{
if ($user->{'notify_sent'})

View File

@ -1,5 +1,7 @@
<?php namespace App\Models;
use DB;
use Illuminate\Database\Eloquent\SoftDeletes;
class Client extends EntityModel
@ -133,17 +135,6 @@ class Client extends EntityModel
return $str;
}
public function getIdNumber()
{
$str = '';
if ($this->id_number) {
$str .= '<i class="fa fa-id-number" style="width: 20px"></i>'.trans('texts.id_number').': '.$this->id_number;
}
return $str;
}
public function getVatNumber()
{
$str = '';

View File

@ -1,5 +1,7 @@
<?php namespace App\Models;
use HTML;
use Illuminate\Database\Eloquent\SoftDeletes;
class Contact extends EntityModel

View File

@ -1,11 +1,14 @@
<?php namespace App\Ninja\Mailers;
use Invoice;
use Payment;
use Contact;
use Invitation;
use Activity;
use Utils;
use Events;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\Contact;
use App\Models\Invitation;
use App\Models\Activity;
use App\Events\InvoiceSent;
class ContactMailer extends Mailer
{
@ -56,7 +59,7 @@ class ContactMailer extends Mailer
$invoice->save();
}
\Event::fire('invoice.sent', $invoice);
Event::fire(new InvoiceSent($invoice));
}
public function sendPaymentConfirmation(Payment $payment)

View File

@ -1,10 +1,11 @@
<?php namespace App\Ninja\Mailers;
use Invoice;
use Payment;
use User;
use Utils;
use App\Models\Invoice;
use App\Models\Payment;
use App\Models\User;
class UserMailer extends Mailer
{
public function sendConfirmation(User $user, User $invitor = null)

View File

@ -1,303 +0,0 @@
<?php namespace App\Providers;
use App;
use Illuminate\Routing\Router;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider {
/**
* This namespace is applied to the controller routes in your routes file.
*
* In addition, it is set as the URL generator's root namespace.
*
* @var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @param \Illuminate\Routing\Router $router
* @return void
*/
public function boot(Router $router)
{
parent::boot($router);
App::before(function($request)
{
// Ensure all request are over HTTPS in production
if (App::environment() == ENV_PRODUCTION)
{
if (!Request::secure())
{
return Redirect::secure(Request::getRequestUri());
}
}
// If the database doens't yet exist we'll skip the rest
if (!Utils::isNinja() && !Utils::isDatabaseSetup())
{
return;
}
// check the application is up to date and for any news feed messages
if (Auth::check())
{
$count = Session::get(SESSION_COUNTER, 0);
Session::put(SESSION_COUNTER, ++$count);
if (!Utils::startsWith($_SERVER['REQUEST_URI'], '/news_feed') && !Session::has('news_feed_id')) {
$data = false;
if (Utils::isNinja()) {
$data = Utils::getNewsFeedResponse();
} else {
$file = @file_get_contents(NINJA_APP_URL . '/news_feed/' . Utils::getUserType() . '/' . NINJA_VERSION);
$data = @json_decode($file);
}
if ($data) {
if ($data->version != NINJA_VERSION) {
$params = [
'user_version' => NINJA_VERSION,
'latest_version'=> $data->version,
'releases_link' => link_to(RELEASES_URL, 'Invoice Ninja', ['target' => '_blank'])
];
Session::put('news_feed_id', NEW_VERSION_AVAILABLE);
Session::put('news_feed_message', trans('texts.new_version_available', $params));
} else {
Session::put('news_feed_id', $data->id);
if ($data->message && $data->id > Auth::user()->news_feed_id) {
Session::put('news_feed_message', $data->message);
}
}
} else {
Session::put('news_feed_id', true);
}
}
}
// Check if we're requesting to change the account's language
if (Input::has('lang'))
{
$locale = Input::get('lang');
App::setLocale($locale);
Session::set(SESSION_LOCALE, $locale);
if (Auth::check())
{
if ($language = Language::whereLocale($locale)->first())
{
$account = Auth::user()->account;
$account->language_id = $language->id;
$account->save();
}
}
}
else if (Auth::check())
{
$locale = Session::get(SESSION_LOCALE, DEFAULT_LOCALE);
App::setLocale($locale);
}
// Make sure the account/user localization settings are in the session
if (Auth::check() && !Session::has(SESSION_TIMEZONE))
{
Event::fire('user.refresh');
}
// Check if the user is claiming a license (ie, additional invoices, white label, etc.)
$claimingLicense = Utils::startsWith($_SERVER['REQUEST_URI'], '/claim_license');
if (!$claimingLicense && Input::has('license_key') && Input::has('product_id'))
{
$licenseKey = Input::get('license_key');
$productId = Input::get('product_id');
$data = trim(file_get_contents((Utils::isNinjaDev() ? 'http://ninja.dev' : NINJA_APP_URL) . "/claim_license?license_key={$licenseKey}&product_id={$productId}"));
if ($productId == PRODUCT_INVOICE_DESIGNS)
{
if ($data = json_decode($data))
{
foreach ($data as $item)
{
$design = new InvoiceDesign();
$design->id = $item->id;
$design->name = $item->name;
$design->javascript = $item->javascript;
$design->save();
}
if (!Utils::isNinjaProd()) {
Cache::forget('invoice_designs_cache_' . Auth::user()->maxInvoiceDesignId());
}
Session::flash('message', trans('texts.bought_designs'));
}
}
else if ($productId == PRODUCT_WHITE_LABEL)
{
if ($data == 'valid')
{
$account = Auth::user()->account;
$account->pro_plan_paid = NINJA_DATE;
$account->save();
Session::flash('message', trans('texts.bought_white_label'));
}
}
}
});
/*
|--------------------------------------------------------------------------
| Authentication Filters
|--------------------------------------------------------------------------
|
| The following filters are used to verify that the user of the current
| session is logged into this application. The "basic" filter easily
| integrates HTTP Basic authentication for quick, simple checking.
|
*/
$router->filter('auth', function()
{
if (Auth::guest())
{
if (Utils::isNinja() || Account::count() == 0)
{
return Redirect::guest('/');
}
else
{
return Redirect::guest('/login');
}
}
});
$router->filter('auth.basic', function()
{
return Auth::basic();
});
$router->filter('api.access', function()
{
$headers = Utils::getApiHeaders();
// check for a valid token
$token = AccountToken::where('token', '=', Request::header('X-Ninja-Token'))->first(['id', 'user_id']);
if ($token) {
Auth::loginUsingId($token->user_id);
Session::set('token_id', $token->id);
} else {
sleep(3);
return Response::make('Invalid token', 403, $headers);
}
if (!Utils::isNinja()) {
return null;
}
if (!Utils::isPro()) {
return Response::make('API requires pro plan', 403, $headers);
} else {
$accountId = Auth::user()->account->id;
// http://stackoverflow.com/questions/1375501/how-do-i-throttle-my-sites-api-users
$hour = 60 * 60;
$hour_limit = 100; # users are limited to 100 requests/hour
$hour_throttle = Cache::get("hour_throttle:{$accountId}", null);
$last_api_request = Cache::get("last_api_request:{$accountId}", 0);
$last_api_diff = time() - $last_api_request;
if (is_null($hour_throttle)) {
$new_hour_throttle = 0;
} else {
$new_hour_throttle = $hour_throttle - $last_api_diff;
$new_hour_throttle = $new_hour_throttle < 0 ? 0 : $new_hour_throttle;
$new_hour_throttle += $hour / $hour_limit;
$hour_hits_remaining = floor(( $hour - $new_hour_throttle ) * $hour_limit / $hour);
$hour_hits_remaining = $hour_hits_remaining >= 0 ? $hour_hits_remaining : 0;
}
if ($new_hour_throttle > $hour) {
$wait = ceil($new_hour_throttle - $hour);
sleep(1);
return Response::make("Please wait {$wait} second(s)", 403, $headers);
}
Cache::put("hour_throttle:{$accountId}", $new_hour_throttle, 10);
Cache::put("last_api_request:{$accountId}", time(), 10);
}
return null;
});
/*
|--------------------------------------------------------------------------
| Guest Filter
|--------------------------------------------------------------------------
|
| The "guest" filter is the counterpart of the authentication filters as
| it simply checks that the current user is not logged in. A redirect
| response will be issued if they are, which you may freely change.
|
*/
$router->filter('guest', function()
{
if (Auth::check()) return Redirect::to('/');
});
/*
|--------------------------------------------------------------------------
| CSRF Protection Filter
|--------------------------------------------------------------------------
|
| The CSRF filter is responsible for protecting your application against
| cross-site request forgery attacks. If this special token in a user
| session does not match the one given in this request, we'll bail.
|
*/
$router->filter('csrf', function()
{
if ($_SERVER['REQUEST_URI'] != '/signup/register')
{
$token = Request::ajax() ? Request::header('X-CSRF-Token') : Input::get('_token');
if (Session::token() != $token)
{
Session::flash('warning', trans('texts.session_expired'));
return Redirect::to('/');
//throw new Illuminate\Session\TokenMismatchException;
}
}
});
}
/**
* Define the routes for the application.
*
* @param \Illuminate\Routing\Router $router
* @return void
*/
public function map(Router $router)
{
$router->group(['namespace' => $this->namespace], function($router)
{
require app_path('Http/routes.php');
});
}
}

View File

@ -56,6 +56,8 @@
{!! Former::open('login')->rules(['email' => 'required|email', 'password' => 'required'])->addClass('form-signin') !!}
{{ Former::populateField('remember', 'true') }}
<div class="modal-header">
<img src="{{ asset('images/icon-login.png') }}" />
<h4>Invoice Ninja | {{ trans('texts.account_login') }}</h4></div>
@ -63,9 +65,10 @@
<p>
{!! Former::text('email')->placeholder(trans('texts.email_address'))->raw() !!}
{!! Former::password('password')->placeholder(trans('texts.password'))->raw() !!}
{!! Former::hidden('remember')->raw() !!}
</p>
<p>{!! Button::success(trans('texts.lets_go'))->withAttributes(array('class' => 'btn-lg'))->submit()->block() !!}</p>
<p>{!! Button::success(trans('texts.lets_go'))->large()->submit()->block() !!}</p>
<p class="link">
{!! link_to('/forgot', trans('texts.forgot_password')) !!}

View File

@ -63,7 +63,7 @@
{!! Former::text('email')->placeholder(trans('texts.email_address'))->raw() !!}
</p>
<p>{!! Button::success(trans('texts.send_email'))->withAttributes(array('class' => 'btn-lg'))->submit()->block() !!}</p>
<p>{!! Button::success(trans('texts.send_email'))->large()->submit()->block() !!}</p>
@if (count($errors->all()))
<div class="alert alert-danger">

View File

@ -72,7 +72,7 @@
</p>
<p>{!! Button::success(trans('texts.save'), array('class' => 'btn-lg'))->submit()->block() !!}</p>
<p>{!! Button::success(trans('texts.save'))->large()->submit()->block() !!}</p>
@if (count($errors->all()))

View File

@ -11,24 +11,23 @@
</div>
@if ($gatewayLink)
{{ Button::link($gatewayLink, trans('texts.view_in_stripe'), ['target' => '_blank']) }}
{!! Button::link($gatewayLink, trans('texts.view_in_stripe'), ['target' => '_blank']) !!}
@endif
@if ($client->trashed())
{{ Button::primary(trans('texts.restore_client'), ['onclick' => 'onRestoreClick()']) }}
{!! Button::primary(trans('texts.restore_client'), ['onclick' => 'onRestoreClick()']) !!}
@else
{{ DropdownButton::normal(trans('texts.edit_client'),
Navigation::links(
[
[trans('texts.edit_client'), URL::to('clients/' . $client->public_id . '/edit')],
[Navigation::DIVIDER],
[trans('texts.archive_client'), "javascript:onArchiveClick()"],
[trans('texts.delete_client'), "javascript:onDeleteClick()"],
{!! DropdownButton::normal(trans('texts.edit_client'))
->withAttributes(['class'=>'normalDropDown'])
->withContents([
['label' => trans('texts.edit_client'), 'url' => URL::to('clients/' . $client->public_id . '/edit')],
Navigation::NAVIGATION_DIVIDER,
['label' => trans('texts.archive_client'), 'url' => "javascript:onArchiveClick()"],
['label' => trans('texts.delete_client'), 'url' => "javascript:onDeleteClick()"],
]
)
, ['id'=>'normalDropDown'])->split() }}
)->split() !!}
{{ DropdownButton::primary(trans('texts.create_invoice'), Navigation::links($actionLinks), ['id'=>'primaryDropDown'])->split() }}
{!! DropdownButton::primary(trans('texts.create_invoice'), Navigation::links($actionLinks), ['id'=>'primaryDropDown'])->split() !!}
@endif
{!! Former::close() !!}
@ -46,9 +45,11 @@
<div class="col-md-3">
<h3>{{ trans('texts.details') }}</h3>
<p>{{ $client->getIdNumber() }}</p>
@if ($client->id_number)
<p><i class="fa fa-id-number" style="width: 20px"></i>{{ trans('texts.id_number').': '.$this->id_number }}</p>
@endif
<p>{{ $client->getVatNumber() }}</p>
<p>{{ $client->getAddress() }}</p>
<p>{{ $client->getAddress() }}</p>
<p>{{ $client->getCustomFields() }}</p>
<p>{{ $client->getPhone() }}</p>
<p>{{ $client->getNotes() }}</p>
@ -203,10 +204,10 @@
<script type="text/javascript">
$(function() {
$('#normalDropDown > button:first').click(function() {
$('.normalDropDown').click(function() {
window.location = '{{ URL::to('clients/' . $client->public_id . '/edit') }}';
});
$('#primaryDropDown > button:first').click(function() {
$('.primaryDropDown').click(function() {
window.location = '{{ URL::to('invoices/create/' . $client->public_id ) }}';
});
});

View File

@ -24,10 +24,10 @@
@if ($invoice->is_quote)
{!! Button::normal(trans('texts.download_pdf', array('onclick' => 'onDownloadClick()')))->large() !!}&nbsp;&nbsp;
@if (!$isConverted)
{!! Button::success(trans('texts.approve'))->asLinkTo(URL::to('approve/' . $invitation->invitation_key))->withAttributes(array('class' => 'btn-lg')) !!}
{!! Button::success(trans('texts.approve'))->asLinkTo(URL::to('approve/' . $invitation->invitation_key))->large() !!}
@endif
@elseif ($invoice->client->account->isGatewayConfigured() && !$invoice->isPaid() && !$invoice->is_recurring)
{!! Button::normal(trans('texts.download_pdf'), array('onclick' => 'onDownloadClick()', 'class' => 'btn-lg')) !!}&nbsp;&nbsp;
{!! Button::normal(trans('texts.download_pdf'), array('onclick' => 'onDownloadClick()'))->large() !!}&nbsp;&nbsp;
@if ($hasToken)
{!! DropdownButton::success_lg(trans('texts.pay_now'), [
['url' => URL::to("payment/{$invitation->invitation_key}?use_token=true&use_paypal=false"), 'label' => trans('texts.use_card_on_file')],
@ -39,7 +39,7 @@
['url' => URL::to("payment/{$invitation->invitation_key}?use_paypal=false"), 'label' => trans('texts.pay_with_card')]
])->addClass('btn-lg') !!}
@else
{!! Button::success_link(URL::to('payment/' . $invitation->invitation_key), trans('texts.pay_now'), array('class' => 'btn-lg')) !!}
{!! Button::success_link(URL::to('payment/' . $invitation->invitation_key), trans('texts.pay_now'))->large() !!}
@endif
@else
{!! Button::success('Download PDF', array('onclick' => 'onDownloadClick()'))->large() !!}