mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-13 22:54:25 +01:00
Working on pro plan
This commit is contained in:
parent
3cfa9a5ce5
commit
944ef2ccd3
@ -6,10 +6,12 @@
|
|||||||
|
|
||||||
Most online invoicing sites are expensive. They shouldn't be. The aim of this project is to provide a free, open-source alternative. Additionally, the hope is the codebase will serve as a sample site for Laravel as well as other JavaScript technologies.
|
Most online invoicing sites are expensive. They shouldn't be. The aim of this project is to provide a free, open-source alternative. Additionally, the hope is the codebase will serve as a sample site for Laravel as well as other JavaScript technologies.
|
||||||
|
|
||||||
The high level instructions for setting up the site are below but there's also a [setup guide](http://hillelcoren.com/invoice-ninja/laravel-ubuntu-virtualbox/). If you'd like to translate the site please use [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) for the starter files.
|
The high level instructions for setting up the site are below but there's also a [setup guide](http://hillelcoren.com/invoice-ninja/laravel-ubuntu-virtualbox/).
|
||||||
|
|
||||||
For updates follow [@invoiceninja](https://twitter.com/invoiceninja) or join the [Facebook Group](https://www.facebook.com/invoiceninja). For discussion of the code please use the [Google Group](https://groups.google.com/d/forum/invoiceninja).
|
For updates follow [@invoiceninja](https://twitter.com/invoiceninja) or join the [Facebook Group](https://www.facebook.com/invoiceninja). For discussion of the code please use the [Google Group](https://groups.google.com/d/forum/invoiceninja).
|
||||||
|
|
||||||
|
If you'd like to translate the site please use [caouecs/Laravel4-long](https://github.com/caouecs/Laravel4-lang) for the starter files.
|
||||||
|
|
||||||
Site design by [kantorp-wegl.in](http://kantorp-wegl.in/)
|
Site design by [kantorp-wegl.in](http://kantorp-wegl.in/)
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,7 +114,6 @@ return array(
|
|||||||
'Illuminate\View\ViewServiceProvider',
|
'Illuminate\View\ViewServiceProvider',
|
||||||
'Illuminate\Workbench\WorkbenchServiceProvider',
|
'Illuminate\Workbench\WorkbenchServiceProvider',
|
||||||
'Illuminate\Remote\RemoteServiceProvider',
|
'Illuminate\Remote\RemoteServiceProvider',
|
||||||
'Basset\BassetServiceProvider',
|
|
||||||
'Bootstrapper\BootstrapperServiceProvider',
|
'Bootstrapper\BootstrapperServiceProvider',
|
||||||
'Zizaco\Confide\ConfideServiceProvider',
|
'Zizaco\Confide\ConfideServiceProvider',
|
||||||
'Former\FormerServiceProvider',
|
'Former\FormerServiceProvider',
|
||||||
@ -187,7 +186,6 @@ return array(
|
|||||||
'Validator' => 'Illuminate\Support\Facades\Validator',
|
'Validator' => 'Illuminate\Support\Facades\Validator',
|
||||||
'View' => 'Illuminate\Support\Facades\View',
|
'View' => 'Illuminate\Support\Facades\View',
|
||||||
'SSH' => 'Illuminate\Support\Facades\SSH',
|
'SSH' => 'Illuminate\Support\Facades\SSH',
|
||||||
'Basset' => 'Basset\Facade',
|
|
||||||
'Alert' => 'Bootstrapper\Alert',
|
'Alert' => 'Bootstrapper\Alert',
|
||||||
'Badge' => 'Bootstrapper\Badge',
|
'Badge' => 'Bootstrapper\Badge',
|
||||||
'Breadcrumb' => 'Bootstrapper\Breadcrumb',
|
'Breadcrumb' => 'Bootstrapper\Breadcrumb',
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use ninja\repositories\AccountRepository;
|
use ninja\repositories\AccountRepository;
|
||||||
use ninja\mailers\UserMailer as Mailer;
|
use ninja\mailers\UserMailer;
|
||||||
|
use ninja\mailers\ContactMailer;
|
||||||
|
|
||||||
class AccountController extends \BaseController {
|
class AccountController extends \BaseController {
|
||||||
|
|
||||||
protected $accountRepo;
|
protected $accountRepo;
|
||||||
protected $mailer;
|
protected $userMailer;
|
||||||
|
protected $contactMailer;
|
||||||
|
|
||||||
public function __construct(AccountRepository $accountRepo, Mailer $mailer)
|
public function __construct(AccountRepository $accountRepo, UserMailer $userMailer, ContactMailer $contactMailer)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->accountRepo = $accountRepo;
|
$this->accountRepo = $accountRepo;
|
||||||
$this->mailer = $mailer;
|
$this->userMailer = $userMailer;
|
||||||
|
$this->contactMailer = $contactMailer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getStarted()
|
public function getStarted()
|
||||||
@ -28,7 +31,6 @@ class AccountController extends \BaseController {
|
|||||||
|
|
||||||
if ($guestKey)
|
if ($guestKey)
|
||||||
{
|
{
|
||||||
//$user = User::where('password', '=', $guestKey)->firstOrFail();
|
|
||||||
$user = User::where('password', '=', $guestKey)->first();
|
$user = User::where('password', '=', $guestKey)->first();
|
||||||
|
|
||||||
if ($user && $user->registered)
|
if ($user && $user->registered)
|
||||||
@ -62,9 +64,48 @@ class AccountController extends \BaseController {
|
|||||||
|
|
||||||
$ninjaAccount = $this->getNinjaAccount();
|
$ninjaAccount = $this->getNinjaAccount();
|
||||||
$ninjaClient = $this->getNinjaClient($ninjaAccount);
|
$ninjaClient = $this->getNinjaClient($ninjaAccount);
|
||||||
|
$invoice = $this->createNinjaInvoice($ninjaAccount, $ninjaClient);
|
||||||
|
|
||||||
//$invoice = new Invoice();
|
$this->contactMailer->sendInvoice($invoice);
|
||||||
//$ninjaClient->invoices()->save($invoice);
|
|
||||||
|
return RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createNinjaInvoice($account, $client)
|
||||||
|
{
|
||||||
|
$lastInvoice = Invoice::withTrashed()->whereAccountId($account->id)->orderBy('public_id', 'DESC')->first();
|
||||||
|
$publicId = $lastInvoice ? ($lastInvoice->public_id + 1) : 1;
|
||||||
|
|
||||||
|
$invoice = new Invoice();
|
||||||
|
$invoice->account_id = $account->id;
|
||||||
|
$invoice->user_id = $account->users()->first()->id;
|
||||||
|
$invoice->public_id = $publicId;
|
||||||
|
$invoice->client_id = $client->id;
|
||||||
|
$invoice->invoice_number = $account->getNextInvoiceNumber();
|
||||||
|
$invoice->invoice_date = date_create()->format('Y-m-d');
|
||||||
|
$invoice->amount = PRO_PLAN_PRICE;
|
||||||
|
$invoice->balance = PRO_PLAN_PRICE;
|
||||||
|
$invoice->save();
|
||||||
|
|
||||||
|
$item = new InvoiceItem();
|
||||||
|
$item->account_id = $account->id;
|
||||||
|
$item->user_id = $account->users()->first()->id;
|
||||||
|
$item->public_id = $publicId;
|
||||||
|
$item->qty = 1;
|
||||||
|
$item->cost = PRO_PLAN_PRICE;
|
||||||
|
$item->notes = trans('texts.pro_plan_description');
|
||||||
|
$item->product_key = trans('texts.pro_plan_product');
|
||||||
|
$invoice->invoice_items()->save($item);
|
||||||
|
|
||||||
|
$invitation = new Invitation();
|
||||||
|
$invitation->account_id = $account->id;
|
||||||
|
$invitation->user_id = $account->users()->first()->id;
|
||||||
|
$invitation->invoice_id = $invoice->id;
|
||||||
|
$invitation->contact_id = $client->contacts()->first()->id;
|
||||||
|
$invitation->invitation_key = str_random(RANDOM_KEY_LENGTH);
|
||||||
|
$invitation->save();
|
||||||
|
|
||||||
|
return $invoice;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getNinjaAccount()
|
private function getNinjaAccount()
|
||||||
@ -87,6 +128,8 @@ class AccountController extends \BaseController {
|
|||||||
$random = str_random(RANDOM_KEY_LENGTH);
|
$random = str_random(RANDOM_KEY_LENGTH);
|
||||||
|
|
||||||
$user = new User();
|
$user = new User();
|
||||||
|
$user->registered = true;
|
||||||
|
$user->confirmed = true;
|
||||||
$user->email = 'contact@invoiceninja.com';
|
$user->email = 'contact@invoiceninja.com';
|
||||||
$user->password = $random;
|
$user->password = $random;
|
||||||
$user->password_confirmation = $random;
|
$user->password_confirmation = $random;
|
||||||
@ -103,11 +146,7 @@ class AccountController extends \BaseController {
|
|||||||
{
|
{
|
||||||
$client = Client::whereAccountId($ninjaAccount->id)->wherePublicId(Auth::user()->account_id)->first();
|
$client = Client::whereAccountId($ninjaAccount->id)->wherePublicId(Auth::user()->account_id)->first();
|
||||||
|
|
||||||
if ($client)
|
if (!$client)
|
||||||
{
|
|
||||||
return $client;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
$client = new Client;
|
$client = new Client;
|
||||||
$client->public_id = Auth::user()->account_id;
|
$client->public_id = Auth::user()->account_id;
|
||||||
@ -127,6 +166,8 @@ class AccountController extends \BaseController {
|
|||||||
}
|
}
|
||||||
$client->contacts()->save($contact);
|
$client->contacts()->save($contact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $client;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setTrashVisible($entityType, $visible)
|
public function setTrashVisible($entityType, $visible)
|
||||||
@ -662,7 +703,7 @@ class AccountController extends \BaseController {
|
|||||||
$user->registered = true;
|
$user->registered = true;
|
||||||
$user->amend();
|
$user->amend();
|
||||||
|
|
||||||
$this->mailer->sendConfirmation($user);
|
$this->userMailer->sendConfirmation($user);
|
||||||
|
|
||||||
$activities = Activity::scope()->get();
|
$activities = Activity::scope()->get();
|
||||||
foreach ($activities as $activity)
|
foreach ($activities as $activity)
|
||||||
|
@ -88,6 +88,9 @@ class UserController extends BaseController {
|
|||||||
Event::fire('user.login');
|
Event::fire('user.login');
|
||||||
Session::reflash();
|
Session::reflash();
|
||||||
|
|
||||||
|
return Redirect::to('/dashboard');
|
||||||
|
|
||||||
|
/*
|
||||||
$invoice = Invoice::scope()->orderBy('id', 'desc')->first();
|
$invoice = Invoice::scope()->orderBy('id', 'desc')->first();
|
||||||
|
|
||||||
if ($invoice)
|
if ($invoice)
|
||||||
@ -98,6 +101,7 @@ class UserController extends BaseController {
|
|||||||
{
|
{
|
||||||
return Redirect::to('/dashboard');
|
return Redirect::to('/dashboard');
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -306,5 +306,8 @@ return array(
|
|||||||
'erase_data' => 'This will permanently erase your data.',
|
'erase_data' => 'This will permanently erase your data.',
|
||||||
'password' => 'Password',
|
'password' => 'Password',
|
||||||
|
|
||||||
|
'pro_plan_product' => 'Pro Plan',
|
||||||
|
'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan',
|
||||||
|
'pro_plan_succes' => 'We\'ve sent you an invoice. Once paid the kfeatures will be enabled.',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
@ -213,4 +213,30 @@ class Account extends Eloquent
|
|||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isPro()
|
||||||
|
{
|
||||||
|
if ($this->account_key == NINJA_ACCOUNT_KEY)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Auth::check())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$datePaid = $this->pro_plan_paid;
|
||||||
|
|
||||||
|
if (!$datePaid || $datePaid == '0000-00-00')
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$today = new DateTime('now');
|
||||||
|
$datePaid = DateTime::createFromFormat('Y-m-d', $datePaid);
|
||||||
|
$interval = $today->diff($datePaid);
|
||||||
|
|
||||||
|
return $interval->y == 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -75,6 +75,11 @@ class User extends ConfideUser implements UserInterface, RemindableInterface
|
|||||||
return $this->email;
|
return $this->email;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isPro()
|
||||||
|
{
|
||||||
|
return $this->account->isPro();
|
||||||
|
}
|
||||||
|
|
||||||
public function getDisplayName()
|
public function getDisplayName()
|
||||||
{
|
{
|
||||||
if ($this->getFullName())
|
if ($this->getFullName())
|
||||||
@ -104,27 +109,6 @@ class User extends ConfideUser implements UserInterface, RemindableInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isPro()
|
|
||||||
{
|
|
||||||
if (!Auth::check())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$datePaid = $this->account->pro_plan_paid;
|
|
||||||
|
|
||||||
if (!$datePaid || $datePaid == '0000-00-00')
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$today = new DateTime('now');
|
|
||||||
$datePaid = DateTime::createFromFormat('Y-m-d', $datePaid);
|
|
||||||
$interval = $today->diff($datePaid);
|
|
||||||
|
|
||||||
return $interval->y == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function showGreyBackground()
|
public function showGreyBackground()
|
||||||
{
|
{
|
||||||
return !$this->theme_id || in_array($this->theme_id, [2, 3, 5, 6, 7, 8, 10, 11, 12]);
|
return !$this->theme_id || in_array($this->theme_id, [2, 3, 5, 6, 7, 8, 10, 11, 12]);
|
||||||
|
@ -11,9 +11,7 @@ class Mailer {
|
|||||||
'emails.'.$view.'_text'
|
'emails.'.$view.'_text'
|
||||||
];
|
];
|
||||||
|
|
||||||
//$view = 'emails.' . $view;
|
Mail::send($views, $data, function($message) use ($toEmail, $fromEmail, $fromName, $subject)
|
||||||
|
|
||||||
Mail::queue($views, $data, function($message) use ($toEmail, $fromEmail, $fromName, $subject)
|
|
||||||
{
|
{
|
||||||
$message->to($toEmail)->from($fromEmail, $fromName)->sender($fromEmail, $fromName)
|
$message->to($toEmail)->from($fromEmail, $fromName)->sender($fromEmail, $fromName)
|
||||||
->replyTo($fromEmail, $fromName)->returnPath($fromEmail)->subject($subject);
|
->replyTo($fromEmail, $fromName)->returnPath($fromEmail)->subject($subject);
|
||||||
|
@ -136,7 +136,7 @@ class InvoiceRepository
|
|||||||
$invoice->po_number = trim($data['po_number']);
|
$invoice->po_number = trim($data['po_number']);
|
||||||
$invoice->invoice_design_id = $data['invoice_design_id'];
|
$invoice->invoice_design_id = $data['invoice_design_id'];
|
||||||
|
|
||||||
if (isset($data['tax_rate']) && Utils::parseFloat($data['tax_rate']) > 0)
|
if (isset($data['tax_name']) && isset($data['tax_rate']) && Utils::parseFloat($data['tax_rate']) > 0)
|
||||||
{
|
{
|
||||||
$invoice->tax_rate = Utils::parseFloat($data['tax_rate']);
|
$invoice->tax_rate = Utils::parseFloat($data['tax_rate']);
|
||||||
$invoice->tax_name = trim($data['tax_name']);
|
$invoice->tax_name = trim($data['tax_name']);
|
||||||
|
@ -231,8 +231,13 @@ define('DEFAULT_DATETIME_FORMAT', 'F j, Y, g:i a');
|
|||||||
define('DEFAULT_QUERY_CACHE', 120); // minutes
|
define('DEFAULT_QUERY_CACHE', 120); // minutes
|
||||||
define('DEFAULT_LOCALE', 'en');
|
define('DEFAULT_LOCALE', 'en');
|
||||||
|
|
||||||
|
define('RESULT_SUCCESS', 'success');
|
||||||
|
define('RESULT_FAILURE', 'failure');
|
||||||
|
|
||||||
define('GATEWAY_PAYPAL_EXPRESS', 17);
|
define('GATEWAY_PAYPAL_EXPRESS', 17);
|
||||||
define('NINJA_ACCOUNT_KEY', 'zg4ylmzDkdkPOT8yoKQw9LTWaoZJx79h');
|
define('NINJA_ACCOUNT_KEY', 'zg4ylmzDkdkPOT8yoKQw9LTWaoZJx79h');
|
||||||
|
define('PRO_PLAN_PRICE', 40);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (Auth::check() && !Session::has(SESSION_TIMEZONE))
|
if (Auth::check() && !Session::has(SESSION_TIMEZONE))
|
||||||
|
@ -274,9 +274,8 @@
|
|||||||
<iframe id="theFrame" style="display:none" frameborder="1" width="100%" height="1180"></iframe>
|
<iframe id="theFrame" style="display:none" frameborder="1" width="100%" height="1180"></iframe>
|
||||||
<canvas id="theCanvas" style="display:none;width:100%;border:solid 1px #CCCCCC;"></canvas>
|
<canvas id="theCanvas" style="display:none;width:100%;border:solid 1px #CCCCCC;"></canvas>
|
||||||
|
|
||||||
@if (!Auth::user()->isPro())
|
@if (!Auth::user()->account->isPro())
|
||||||
<a href="#" onclick="showProPlan()">{{ trans('texts.pro_plan.remove_logo_link') }}</a>
|
{{ trans('texts.pro_plan.remove_logo', ['link'=>'<a href="#" onclick="showProPlan()">'.trans('texts.pro_plan.remove_logo_link').'</a>']) }}
|
||||||
{{ trans('texts.pro_plan.remove_logo') }}
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div class="modal fade" id="clientModal" tabindex="-1" role="dialog" aria-labelledby="clientModalLabel" aria-hidden="true">
|
<div class="modal fade" id="clientModal" tabindex="-1" role="dialog" aria-labelledby="clientModalLabel" aria-hidden="true">
|
||||||
@ -434,7 +433,6 @@
|
|||||||
{{ Former::close() }}
|
{{ Former::close() }}
|
||||||
|
|
||||||
|
|
||||||
{{ Former::open('account/go_pro') }}
|
|
||||||
<div class="modal fade" id="proPlanModal" tabindex="-1" role="dialog" aria-labelledby="proPlanModalLabel" aria-hidden="true">
|
<div class="modal fade" id="proPlanModal" tabindex="-1" role="dialog" aria-labelledby="proPlanModalLabel" aria-hidden="true">
|
||||||
<div class="modal-dialog" style="min-width:150px">
|
<div class="modal-dialog" style="min-width:150px">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@ -443,20 +441,34 @@
|
|||||||
<h4 class="modal-title" id="proPlanModalLabel">{{ trans('texts.sign_up') }}</h4>
|
<h4 class="modal-title" id="proPlanModalLabel">{{ trans('texts.sign_up') }}</h4>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="background-color: #fff; padding-left: 16px; padding-right: 16px">
|
<div style="background-color: #fff; padding-left: 16px; padding-right: 16px" id="proPlanDiv">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer" style="margin-top: 0px">
|
|
||||||
|
<div style="padding-left:40px;padding-right:40px;display:none;min-height:130px" id="proPlanWorking">
|
||||||
|
<h3>{{ trans('texts.working') }}...</h3>
|
||||||
|
<div class="progress progress-striped active">
|
||||||
|
<div class="progress-bar" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="background-color: #fff; padding-right:20px;padding-left:20px; display:none" id="proPlanSuccessDiv">
|
||||||
|
<br/>
|
||||||
|
<h3>{{ trans('texts.success') }}</h3>
|
||||||
|
{{ trans('texts.pro_plan_succes') }}<br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="modal-footer" style="margin-top: 0px" id="proPlanFooter">
|
||||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.close') }}</button>
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ trans('texts.close') }}</button>
|
||||||
{{ Button::primary_submit(trans('texts.sign_up')) }}
|
<button type="button" class="btn btn-primary" data-dismiss="modal" id="proPlanButton" onclick="submitProPlan()">{{ trans('texts.sign_up') }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ Former::close() }}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -474,6 +486,22 @@
|
|||||||
$('#proPlanModal').modal('show');
|
$('#proPlanModal').modal('show');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function submitProPlan() {
|
||||||
|
|
||||||
|
$('#proPlanDiv, #proPlanFooter').hide();
|
||||||
|
$('#proPlanWorking').show();
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '{{ URL::to('account/go_pro') }}',
|
||||||
|
success: function(result) {
|
||||||
|
$('#proPlanSuccessDiv, #proPlanFooter').show();
|
||||||
|
$('#proPlanWorking, #proPlanButton').hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
||||||
$('#country_id').combobox().on('change', function(e) {
|
$('#country_id').combobox().on('change', function(e) {
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"laravel/framework": "4.1.*",
|
"laravel/framework": "4.1.*",
|
||||||
"jasonlewis/basset": "dev-master",
|
|
||||||
"patricktalmadge/bootstrapper": "dev-develop",
|
"patricktalmadge/bootstrapper": "dev-develop",
|
||||||
"zizaco/confide": "3.1.x",
|
"zizaco/confide": "3.1.x",
|
||||||
"anahkiasen/former": "dev-master",
|
"anahkiasen/former": "dev-master",
|
||||||
|
Loading…
Reference in New Issue
Block a user