mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Refactor client portal and email settings requests
This commit is contained in:
parent
6ba3b22ec3
commit
b6527cddc3
@ -39,6 +39,9 @@ use App\Services\AuthService;
|
|||||||
use App\Services\PaymentService;
|
use App\Services\PaymentService;
|
||||||
use App\Http\Requests\UpdateAccountRequest;
|
use App\Http\Requests\UpdateAccountRequest;
|
||||||
|
|
||||||
|
use App\Http\Requests\SaveClientPortalSettings;
|
||||||
|
use App\Http\Requests\SaveEmailSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AccountController
|
* Class AccountController
|
||||||
*/
|
*/
|
||||||
@ -714,14 +717,10 @@ class AccountController extends BaseController
|
|||||||
return AccountController::export();
|
return AccountController::export();
|
||||||
} elseif ($section === ACCOUNT_INVOICE_SETTINGS) {
|
} elseif ($section === ACCOUNT_INVOICE_SETTINGS) {
|
||||||
return AccountController::saveInvoiceSettings();
|
return AccountController::saveInvoiceSettings();
|
||||||
} elseif ($section === ACCOUNT_EMAIL_SETTINGS) {
|
|
||||||
return AccountController::saveEmailSettings();
|
|
||||||
} elseif ($section === ACCOUNT_INVOICE_DESIGN) {
|
} elseif ($section === ACCOUNT_INVOICE_DESIGN) {
|
||||||
return AccountController::saveInvoiceDesign();
|
return AccountController::saveInvoiceDesign();
|
||||||
} elseif ($section === ACCOUNT_CUSTOMIZE_DESIGN) {
|
} elseif ($section === ACCOUNT_CUSTOMIZE_DESIGN) {
|
||||||
return AccountController::saveCustomizeDesign();
|
return AccountController::saveCustomizeDesign();
|
||||||
} elseif ($section === ACCOUNT_CLIENT_PORTAL) {
|
|
||||||
return AccountController::saveClientPortal();
|
|
||||||
} elseif ($section === ACCOUNT_TEMPLATES_AND_REMINDERS) {
|
} elseif ($section === ACCOUNT_TEMPLATES_AND_REMINDERS) {
|
||||||
return AccountController::saveEmailTemplates();
|
return AccountController::saveEmailTemplates();
|
||||||
} elseif ($section === ACCOUNT_PRODUCTS) {
|
} elseif ($section === ACCOUNT_PRODUCTS) {
|
||||||
@ -789,53 +788,27 @@ class AccountController extends BaseController
|
|||||||
/**
|
/**
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
*/
|
*/
|
||||||
private function saveClientPortal()
|
public function saveClientPortalSettings(SaveClientPortalSettings $request)
|
||||||
{
|
{
|
||||||
$account = Auth::user()->account;
|
$account = $request->user()->account;
|
||||||
$account->fill(Input::all());
|
$account->fill($request->all());
|
||||||
|
|
||||||
// Only allowed for pro Invoice Ninja users or white labeled self-hosted users
|
|
||||||
if (Auth::user()->account->hasFeature(FEATURE_CLIENT_PORTAL_CSS)) {
|
|
||||||
$input_css = Input::get('client_view_css');
|
|
||||||
if (Utils::isNinja()) {
|
|
||||||
// Allow referencing the body element
|
|
||||||
$input_css = preg_replace('/(?<![a-z0-9\-\_\#\.])body(?![a-z0-9\-\_])/i', '.body', $input_css);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Inspired by http://stackoverflow.com/a/5209050/1721527, dleavitt <https://stackoverflow.com/users/362110/dleavitt>
|
|
||||||
//
|
|
||||||
|
|
||||||
// Create a new configuration object
|
|
||||||
$config = \HTMLPurifier_Config::createDefault();
|
|
||||||
$config->set('Filter.ExtractStyleBlocks', true);
|
|
||||||
$config->set('CSS.AllowImportant', true);
|
|
||||||
$config->set('CSS.AllowTricky', true);
|
|
||||||
$config->set('CSS.Trusted', true);
|
|
||||||
|
|
||||||
// Create a new purifier instance
|
|
||||||
$purifier = new \HTMLPurifier($config);
|
|
||||||
|
|
||||||
// Wrap our CSS in style tags and pass to purifier.
|
|
||||||
// we're not actually interested in the html response though
|
|
||||||
$html = $purifier->purify('<style>'.$input_css.'</style>');
|
|
||||||
|
|
||||||
// The "style" blocks are stored seperately
|
|
||||||
$output_css = $purifier->context->get('StyleBlocks');
|
|
||||||
|
|
||||||
// Get the first style block
|
|
||||||
$sanitized_css = count($output_css) ? $output_css[0] : '';
|
|
||||||
} else {
|
|
||||||
$sanitized_css = $input_css;
|
|
||||||
}
|
|
||||||
|
|
||||||
$account->client_view_css = $sanitized_css;
|
|
||||||
}
|
|
||||||
|
|
||||||
$account->save();
|
$account->save();
|
||||||
|
|
||||||
Session::flash('message', trans('texts.updated_settings'));
|
return redirect('settings/' . ACCOUNT_CLIENT_PORTAL)
|
||||||
|
->with('message', trans('texts.updated_settings'));
|
||||||
|
}
|
||||||
|
|
||||||
return Redirect::to('settings/'.ACCOUNT_CLIENT_PORTAL);
|
/**
|
||||||
|
* @return $this|\Illuminate\Http\RedirectResponse
|
||||||
|
*/
|
||||||
|
public function saveEmailSettings(SaveEmailSettings $request)
|
||||||
|
{
|
||||||
|
$account = $request->user()->account;
|
||||||
|
$account->fill($request->all());
|
||||||
|
$account->save();
|
||||||
|
|
||||||
|
return redirect('settings/' . ACCOUNT_EMAIL_SETTINGS)
|
||||||
|
->with('message', trans('texts.updated_settings'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -905,74 +878,6 @@ class AccountController extends BaseController
|
|||||||
return Redirect::to('settings/'.ACCOUNT_PRODUCTS);
|
return Redirect::to('settings/'.ACCOUNT_PRODUCTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return $this|\Illuminate\Http\RedirectResponse
|
|
||||||
*/
|
|
||||||
private function saveEmailSettings()
|
|
||||||
{
|
|
||||||
if (Auth::user()->account->hasFeature(FEATURE_CUSTOM_EMAILS)) {
|
|
||||||
$user = Auth::user();
|
|
||||||
$subdomain = null;
|
|
||||||
$iframeURL = null;
|
|
||||||
$rules = [];
|
|
||||||
|
|
||||||
if (Input::get('custom_link') == 'subdomain') {
|
|
||||||
$subdomain = preg_replace('/[^a-zA-Z0-9_\-\.]/', '', substr(strtolower(Input::get('subdomain')), 0, MAX_SUBDOMAIN_LENGTH));
|
|
||||||
if (Utils::isNinja()) {
|
|
||||||
$exclude = [
|
|
||||||
'www',
|
|
||||||
'app',
|
|
||||||
'mail',
|
|
||||||
'admin',
|
|
||||||
'blog',
|
|
||||||
'user',
|
|
||||||
'contact',
|
|
||||||
'payment',
|
|
||||||
'payments',
|
|
||||||
'billing',
|
|
||||||
'invoice',
|
|
||||||
'business',
|
|
||||||
'owner',
|
|
||||||
'info',
|
|
||||||
'ninja',
|
|
||||||
'docs',
|
|
||||||
'doc',
|
|
||||||
'documents'
|
|
||||||
];
|
|
||||||
$rules['subdomain'] = "unique:accounts,subdomain,{$user->account_id},id|not_in:" . implode(',', $exclude);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$iframeURL = preg_replace('/[^a-zA-Z0-9_\-\:\/\.]/', '', substr(strtolower(Input::get('iframe_url')), 0, MAX_IFRAME_URL_LENGTH));
|
|
||||||
$iframeURL = rtrim($iframeURL, '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
$validator = Validator::make(Input::all(), $rules);
|
|
||||||
|
|
||||||
if ($validator->fails()) {
|
|
||||||
return Redirect::to('settings/'.ACCOUNT_EMAIL_SETTINGS)
|
|
||||||
->withErrors($validator)
|
|
||||||
->withInput();
|
|
||||||
} else {
|
|
||||||
$account = Auth::user()->account;
|
|
||||||
$account->subdomain = $subdomain;
|
|
||||||
$account->iframe_url = $iframeURL;
|
|
||||||
$account->pdf_email_attachment = Input::get('pdf_email_attachment') ? true : false;
|
|
||||||
$account->document_email_attachment = Input::get('document_email_attachment') ? true : false;
|
|
||||||
$account->email_design_id = Input::get('email_design_id');
|
|
||||||
$account->bcc_email = Input::get('bcc_email');
|
|
||||||
|
|
||||||
if (Utils::isNinja()) {
|
|
||||||
$account->enable_email_markup = Input::get('enable_email_markup') ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$account->save();
|
|
||||||
Session::flash('message', trans('texts.updated_settings'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Redirect::to('settings/'.ACCOUNT_EMAIL_SETTINGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return $this|\Illuminate\Http\RedirectResponse
|
* @return $this|\Illuminate\Http\RedirectResponse
|
||||||
*/
|
*/
|
||||||
|
58
app/Http/Requests/SaveClientPortalSettings.php
Normal file
58
app/Http/Requests/SaveClientPortalSettings.php
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Utils;
|
||||||
|
use HTMLUtils;
|
||||||
|
|
||||||
|
class SaveClientPortalSettings extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return $this->user()->is_admin && $this->user()->isPro();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
$rules = [];
|
||||||
|
|
||||||
|
if ($this->custom_link == 'subdomain' && Utils::isNinja()) {
|
||||||
|
$rules['subdomain'] = "unique:accounts,subdomain,{$this->user()->account_id},id|valid_subdomain";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rules;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sanitize()
|
||||||
|
{
|
||||||
|
$input = $this->all();
|
||||||
|
|
||||||
|
if ($this->client_view_css && Utils::isNinja()) {
|
||||||
|
$input['client_view_css'] = HTMLUtils::sanitize($this->client_view_css);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->custom_link == 'subdomain') {
|
||||||
|
$subdomain = substr(strtolower($input['subdomain']), 0, MAX_SUBDOMAIN_LENGTH);
|
||||||
|
$input['subdomain'] = preg_replace('/[^a-zA-Z0-9_\-\.]/', '', $subdomain);
|
||||||
|
$input['iframe_url'] = null;
|
||||||
|
} else {
|
||||||
|
$iframeURL = substr(strtolower($input['iframe_url']), 0, MAX_IFRAME_URL_LENGTH);
|
||||||
|
$iframeURL = preg_replace('/[^a-zA-Z0-9_\-\:\/\.]/', '', $iframeURL);
|
||||||
|
$input['iframe_url'] = rtrim($iframeURL, '/');
|
||||||
|
$input['subdomain'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->replace($input);
|
||||||
|
|
||||||
|
return $this->all();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
27
app/Http/Requests/SaveEmailSettings.php
Normal file
27
app/Http/Requests/SaveEmailSettings.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php namespace App\Http\Requests;
|
||||||
|
|
||||||
|
class SaveEmailSettings extends Request
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return $this->user()->is_admin && $this->user()->isPro();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'bcc_email' => 'email',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -244,6 +244,8 @@ Route::group([
|
|||||||
Route::post('tax_rates/bulk', 'TaxRateController@bulk');
|
Route::post('tax_rates/bulk', 'TaxRateController@bulk');
|
||||||
|
|
||||||
Route::get('settings/email_preview', 'AccountController@previewEmail');
|
Route::get('settings/email_preview', 'AccountController@previewEmail');
|
||||||
|
Route::post('settings/client_portal', 'AccountController@saveClientPortalSettings');
|
||||||
|
Route::post('settings/email_settings', 'AccountController@saveEmailSettings');
|
||||||
Route::get('company/{section}/{subSection?}', 'AccountController@redirectLegacy');
|
Route::get('company/{section}/{subSection?}', 'AccountController@redirectLegacy');
|
||||||
Route::get('settings/data_visualizations', 'ReportController@d3');
|
Route::get('settings/data_visualizations', 'ReportController@d3');
|
||||||
Route::get('settings/reports', 'ReportController@showReports');
|
Route::get('settings/reports', 'ReportController@showReports');
|
||||||
|
37
app/Libraries/HTMLUtils.php
Normal file
37
app/Libraries/HTMLUtils.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php namespace App\Libraries;
|
||||||
|
|
||||||
|
use HTMLPurifier;
|
||||||
|
use HTMLPurifier_Config;
|
||||||
|
|
||||||
|
class HTMLUtils
|
||||||
|
{
|
||||||
|
public static function sanitize($css)
|
||||||
|
{
|
||||||
|
// Allow referencing the body element
|
||||||
|
$css = preg_replace('/(?<![a-z0-9\-\_\#\.])body(?![a-z0-9\-\_])/i', '.body', $css);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Inspired by http://stackoverflow.com/a/5209050/1721527, dleavitt <https://stackoverflow.com/users/362110/dleavitt>
|
||||||
|
//
|
||||||
|
|
||||||
|
// Create a new configuration object
|
||||||
|
$config = HTMLPurifier_Config::createDefault();
|
||||||
|
$config->set('Filter.ExtractStyleBlocks', true);
|
||||||
|
$config->set('CSS.AllowImportant', true);
|
||||||
|
$config->set('CSS.AllowTricky', true);
|
||||||
|
$config->set('CSS.Trusted', true);
|
||||||
|
|
||||||
|
// Create a new purifier instance
|
||||||
|
$purifier = new HTMLPurifier($config);
|
||||||
|
|
||||||
|
// Wrap our CSS in style tags and pass to purifier.
|
||||||
|
// we're not actually interested in the html response though
|
||||||
|
$purifier->purify('<style>'.$css.'</style>');
|
||||||
|
|
||||||
|
// The "style" blocks are stored seperately
|
||||||
|
$css = $purifier->context->get('StyleBlocks');
|
||||||
|
|
||||||
|
// Get the first style block
|
||||||
|
return count($css) ? $css[0] : '';
|
||||||
|
}
|
||||||
|
}
|
@ -82,6 +82,13 @@ class Account extends Eloquent
|
|||||||
'show_accept_quote_terms',
|
'show_accept_quote_terms',
|
||||||
'require_invoice_signature',
|
'require_invoice_signature',
|
||||||
'require_quote_signature',
|
'require_quote_signature',
|
||||||
|
'pdf_email_attachment',
|
||||||
|
'document_email_attachment',
|
||||||
|
'email_design_id',
|
||||||
|
'bcc_email',
|
||||||
|
'enable_email_markup',
|
||||||
|
'subdomain',
|
||||||
|
'iframe_url',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -198,6 +198,9 @@ class AppServiceProvider extends ServiceProvider
|
|||||||
return $total <= MAX_INVOICE_AMOUNT;
|
return $total <= MAX_INVOICE_AMOUNT;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Validator::extend('valid_subdomain', function($attribute, $value, $parameters) {
|
||||||
|
return ! in_array($value, ['www', 'app','mail', 'admin', 'blog', 'user', 'contact', 'payment', 'payments', 'billing', 'invoice', 'business', 'owner', 'info', 'ninja', 'docs', 'doc', 'documents']);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -222,7 +222,6 @@ return [
|
|||||||
'View' => 'Illuminate\Support\Facades\View',
|
'View' => 'Illuminate\Support\Facades\View',
|
||||||
|
|
||||||
// Added Class Aliases
|
// Added Class Aliases
|
||||||
'Utils' => 'App\Libraries\Utils',
|
|
||||||
'Form' => 'Collective\Html\FormFacade',
|
'Form' => 'Collective\Html\FormFacade',
|
||||||
'HTML' => 'Collective\Html\HtmlFacade',
|
'HTML' => 'Collective\Html\HtmlFacade',
|
||||||
'SSH' => 'Illuminate\Support\Facades\SSH',
|
'SSH' => 'Illuminate\Support\Facades\SSH',
|
||||||
@ -261,6 +260,9 @@ return [
|
|||||||
'Crawler' => 'Jaybizzle\LaravelCrawlerDetect\Facades\LaravelCrawlerDetect',
|
'Crawler' => 'Jaybizzle\LaravelCrawlerDetect\Facades\LaravelCrawlerDetect',
|
||||||
'Updater' => Codedge\Updater\UpdaterFacade::class,
|
'Updater' => Codedge\Updater\UpdaterFacade::class,
|
||||||
'Module' => Nwidart\Modules\Facades\Module::class,
|
'Module' => Nwidart\Modules\Facades\Module::class,
|
||||||
|
|
||||||
|
'Utils' => App\Libraries\Utils::class,
|
||||||
|
'HTMLUtils' => App\Libraries\HTMLUtils::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
@ -2312,6 +2312,8 @@ $LANG = array(
|
|||||||
'tax_invoice' => 'Tax Invoice',
|
'tax_invoice' => 'Tax Invoice',
|
||||||
'emailed_invoices' => 'Successfully emailed invoices',
|
'emailed_invoices' => 'Successfully emailed invoices',
|
||||||
'emailed_quotes' => 'Successfully emailed quotes',
|
'emailed_quotes' => 'Successfully emailed quotes',
|
||||||
|
'website_url' => 'Website URL',
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return $LANG;
|
return $LANG;
|
||||||
|
@ -76,6 +76,7 @@ return array(
|
|||||||
"has_counter" => "The value must contain {\$counter}",
|
"has_counter" => "The value must contain {\$counter}",
|
||||||
"valid_contacts" => "The contact must have either an email or name",
|
"valid_contacts" => "The contact must have either an email or name",
|
||||||
"valid_invoice_items" => "The invoice exceeds the maximum amount",
|
"valid_invoice_items" => "The invoice exceeds the maximum amount",
|
||||||
|
"valid_subdomain" => "The subdomain is restricted",
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
@ -19,11 +19,14 @@
|
|||||||
@parent
|
@parent
|
||||||
|
|
||||||
{!! Former::open_for_files()
|
{!! Former::open_for_files()
|
||||||
->addClass('warn-on-exit') !!}
|
->rules([
|
||||||
|
'iframe_url' => 'url',
|
||||||
|
])
|
||||||
|
->addClass('warn-on-exit') !!}
|
||||||
|
|
||||||
|
{!! Former::populate($account) !!}
|
||||||
{!! Former::populateField('enable_client_portal', intval($account->enable_client_portal)) !!}
|
{!! Former::populateField('enable_client_portal', intval($account->enable_client_portal)) !!}
|
||||||
{!! Former::populateField('enable_client_portal_dashboard', intval($account->enable_client_portal_dashboard)) !!}
|
{!! Former::populateField('enable_client_portal_dashboard', intval($account->enable_client_portal_dashboard)) !!}
|
||||||
{!! Former::populateField('client_view_css', $client_view_css) !!}
|
|
||||||
{!! Former::populateField('enable_portal_password', intval($enable_portal_password)) !!}
|
{!! Former::populateField('enable_portal_password', intval($enable_portal_password)) !!}
|
||||||
{!! Former::populateField('send_portal_password', intval($send_portal_password)) !!}
|
{!! Former::populateField('send_portal_password', intval($send_portal_password)) !!}
|
||||||
{!! Former::populateField('enable_buy_now_buttons', intval($account->enable_buy_now_buttons)) !!}
|
{!! Former::populateField('enable_buy_now_buttons', intval($account->enable_buy_now_buttons)) !!}
|
||||||
@ -47,16 +50,41 @@
|
|||||||
|
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title">{!! trans('texts.navigation') !!}</h3>
|
<h3 class="panel-title">{!! trans('texts.settings') !!}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="col-md-10 col-md-offset-1">
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
|
||||||
|
{!! Former::inline_radios('custom_invoice_link')
|
||||||
|
->onchange('onCustomLinkChange()')
|
||||||
|
->label(trans('texts.website_url'))
|
||||||
|
->radios([
|
||||||
|
trans('texts.subdomain') => ['value' => 'subdomain', 'name' => 'custom_link'],
|
||||||
|
trans('texts.website') => ['value' => 'website', 'name' => 'custom_link'],
|
||||||
|
])->check($account->iframe_url ? 'website' : 'subdomain') !!}
|
||||||
|
{{ Former::setOption('capitalize_translations', false) }}
|
||||||
|
|
||||||
|
{!! Former::text('subdomain')
|
||||||
|
->placeholder(trans('texts.www'))
|
||||||
|
->onchange('onSubdomainChange()')
|
||||||
|
->addGroupClass('subdomain')
|
||||||
|
->label(' ')
|
||||||
|
->help(trans('texts.subdomain_help')) !!}
|
||||||
|
|
||||||
|
{!! Former::text('iframe_url')
|
||||||
|
->placeholder('https://www.example.com/invoice')
|
||||||
|
->appendIcon('question-sign')
|
||||||
|
->addGroupClass('iframe_url')
|
||||||
|
->label(' ')
|
||||||
|
->help(trans('texts.subdomain_help')) !!}
|
||||||
|
|
||||||
|
|
||||||
{!! Former::checkbox('enable_client_portal')
|
{!! Former::checkbox('enable_client_portal')
|
||||||
->text(trans('texts.enable'))
|
->text(trans('texts.enable'))
|
||||||
->help(trans('texts.enable_client_portal_help'))
|
->help(trans('texts.enable_client_portal_help'))
|
||||||
->value(1) !!}
|
->value(1) !!}
|
||||||
</div>
|
|
||||||
<div class="col-md-10 col-md-offset-1">
|
|
||||||
{!! Former::checkbox('enable_client_portal_dashboard')
|
{!! Former::checkbox('enable_client_portal_dashboard')
|
||||||
->text(trans('texts.enable'))
|
->text(trans('texts.enable'))
|
||||||
->help(trans('texts.enable_client_portal_dashboard_help'))
|
->help(trans('texts.enable_client_portal_dashboard_help'))
|
||||||
@ -251,6 +279,38 @@
|
|||||||
|
|
||||||
{!! Former::close() !!}
|
{!! Former::close() !!}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="modal fade" id="iframeHelpModal" tabindex="-1" role="dialog" aria-labelledby="iframeHelpModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog" style="min-width:150px">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
|
<h4 class="modal-title" id="iframeHelpModalLabel">{{ trans('texts.iframe_url') }}</h4>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>{{ trans('texts.iframe_url_help1') }}</p>
|
||||||
|
<pre><center>
|
||||||
|
<iframe id="invoiceIFrame" width="100%" height="1200" style="max-width:1000px"></iframe>
|
||||||
|
<center>
|
||||||
|
<script language="javascript">
|
||||||
|
var iframe = document.getElementById('invoiceIFrame');
|
||||||
|
iframe.src = '{{ rtrim(SITE_URL ,'/') }}/view/'
|
||||||
|
+ window.location.search.substring(1);
|
||||||
|
</script></pre>
|
||||||
|
<p>{{ trans('texts.iframe_url_help2') }}</p>
|
||||||
|
<p><b>{{ trans('texts.iframe_url_help3') }}</b></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer" style="margin-top: 0px">
|
||||||
|
<button type="button" class="btn btn-primary" data-dismiss="modal">{{ trans('texts.close') }}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
var products = {!! $products !!};
|
var products = {!! $products !!};
|
||||||
@ -320,6 +380,44 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function onSubdomainChange() {
|
||||||
|
var input = $('#subdomain');
|
||||||
|
var val = input.val();
|
||||||
|
if (!val) return;
|
||||||
|
val = val.replace(/[^a-zA-Z0-9_\-]/g, '').toLowerCase().substring(0, {{ MAX_SUBDOMAIN_LENGTH }});
|
||||||
|
input.val(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCustomLinkChange() {
|
||||||
|
var val = $('input[name=custom_link]:checked').val()
|
||||||
|
if (val == 'subdomain') {
|
||||||
|
$('.subdomain').show();
|
||||||
|
$('.iframe_url').hide();
|
||||||
|
} else {
|
||||||
|
$('.subdomain').hide();
|
||||||
|
$('.iframe_url').show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.iframe_url .input-group-addon').click(function() {
|
||||||
|
$('#iframeHelpModal').modal('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.email_design_id .input-group-addon').click(function() {
|
||||||
|
$('#designHelpModal').modal('show');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
onCustomLinkChange();
|
||||||
|
|
||||||
|
$('#subdomain').change(function() {
|
||||||
|
$('#iframe_url').val('');
|
||||||
|
});
|
||||||
|
$('#iframe_url').change(function() {
|
||||||
|
$('#subdomain').val('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
@include('accounts.nav', ['selected' => ACCOUNT_EMAIL_SETTINGS, 'advanced' => true])
|
@include('accounts.nav', ['selected' => ACCOUNT_EMAIL_SETTINGS, 'advanced' => true])
|
||||||
|
|
||||||
{!! Former::open()->rules([
|
{!! Former::open()->rules([
|
||||||
'iframe_url' => 'url',
|
|
||||||
'bcc_email' => 'email',
|
'bcc_email' => 'email',
|
||||||
])->addClass('warn-on-exit') !!}
|
])->addClass('warn-on-exit') !!}
|
||||||
|
|
||||||
{{ Former::populate($account) }}
|
{{ Former::populate($account) }}
|
||||||
{{ Former::populateField('pdf_email_attachment', intval($account->pdf_email_attachment)) }}
|
{{ Former::populateField('pdf_email_attachment', intval($account->pdf_email_attachment)) }}
|
||||||
{{ Former::populateField('document_email_attachment', intval($account->document_email_attachment)) }}
|
{{ Former::populateField('document_email_attachment', intval($account->document_email_attachment)) }}
|
||||||
@ -49,29 +49,6 @@
|
|||||||
|
|
||||||
{{-- Former::select('recurring_hour')->options($recurringHours) --}}
|
{{-- Former::select('recurring_hour')->options($recurringHours) --}}
|
||||||
|
|
||||||
{!! Former::inline_radios('custom_invoice_link')
|
|
||||||
->onchange('onCustomLinkChange()')
|
|
||||||
->label(trans('texts.invoice_link'))
|
|
||||||
->radios([
|
|
||||||
trans('texts.subdomain') => ['value' => 'subdomain', 'name' => 'custom_link'],
|
|
||||||
trans('texts.website') => ['value' => 'website', 'name' => 'custom_link'],
|
|
||||||
])->check($account->iframe_url ? 'website' : 'subdomain') !!}
|
|
||||||
{{ Former::setOption('capitalize_translations', false) }}
|
|
||||||
|
|
||||||
{!! Former::text('subdomain')
|
|
||||||
->placeholder(trans('texts.www'))
|
|
||||||
->onchange('onSubdomainChange()')
|
|
||||||
->addGroupClass('subdomain')
|
|
||||||
->label(' ')
|
|
||||||
->help(trans('texts.subdomain_help')) !!}
|
|
||||||
|
|
||||||
{!! Former::text('iframe_url')
|
|
||||||
->placeholder('https://www.example.com/invoice')
|
|
||||||
->appendIcon('question-sign')
|
|
||||||
->addGroupClass('iframe_url')
|
|
||||||
->label(' ')
|
|
||||||
->help(trans('texts.subdomain_help')) !!}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -107,36 +84,6 @@
|
|||||||
</center>
|
</center>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div class="modal fade" id="iframeHelpModal" tabindex="-1" role="dialog" aria-labelledby="iframeHelpModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" style="min-width:150px">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
|
||||||
<h4 class="modal-title" id="iframeHelpModalLabel">{{ trans('texts.iframe_url') }}</h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-body">
|
|
||||||
<p>{{ trans('texts.iframe_url_help1') }}</p>
|
|
||||||
<pre><center>
|
|
||||||
<iframe id="invoiceIFrame" width="100%" height="1200" style="max-width:1000px"></iframe>
|
|
||||||
<center>
|
|
||||||
<script language="javascript">
|
|
||||||
var iframe = document.getElementById('invoiceIFrame');
|
|
||||||
iframe.src = '{{ rtrim(SITE_URL ,'/') }}/view/'
|
|
||||||
+ window.location.search.substring(1);
|
|
||||||
</script></pre>
|
|
||||||
<p>{{ trans('texts.iframe_url_help2') }}</p>
|
|
||||||
<p><b>{{ trans('texts.iframe_url_help3') }}</b></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-footer" style="margin-top: 0px">
|
|
||||||
<button type="button" class="btn btn-primary" data-dismiss="modal">{{ trans('texts.close') }}</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal fade" id="designHelpModal" tabindex="-1" role="dialog" aria-labelledby="designHelpModalLabel" aria-hidden="true">
|
<div class="modal fade" id="designHelpModal" tabindex="-1" role="dialog" aria-labelledby="designHelpModalLabel" 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">
|
||||||
@ -172,45 +119,4 @@
|
|||||||
|
|
||||||
{!! Former::close() !!}
|
{!! Former::close() !!}
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
function onSubdomainChange() {
|
|
||||||
var input = $('#subdomain');
|
|
||||||
var val = input.val();
|
|
||||||
if (!val) return;
|
|
||||||
val = val.replace(/[^a-zA-Z0-9_\-]/g, '').toLowerCase().substring(0, {{ MAX_SUBDOMAIN_LENGTH }});
|
|
||||||
input.val(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCustomLinkChange() {
|
|
||||||
var val = $('input[name=custom_link]:checked').val()
|
|
||||||
if (val == 'subdomain') {
|
|
||||||
$('.subdomain').show();
|
|
||||||
$('.iframe_url').hide();
|
|
||||||
} else {
|
|
||||||
$('.subdomain').hide();
|
|
||||||
$('.iframe_url').show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.iframe_url .input-group-addon').click(function() {
|
|
||||||
$('#iframeHelpModal').modal('show');
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.email_design_id .input-group-addon').click(function() {
|
|
||||||
$('#designHelpModal').modal('show');
|
|
||||||
});
|
|
||||||
|
|
||||||
$(function() {
|
|
||||||
onCustomLinkChange();
|
|
||||||
|
|
||||||
$('#subdomain').change(function() {
|
|
||||||
$('#iframe_url').val('');
|
|
||||||
});
|
|
||||||
$('#iframe_url').change(function() {
|
|
||||||
$('#subdomain').val('');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
@stop
|
@stop
|
||||||
|
Loading…
x
Reference in New Issue
Block a user