Improve user permission support

* Hide links based on permissions
* Restrict editing/creating within other UI
This commit is contained in:
Joshua Dwire 2016-03-15 22:07:11 -04:00
parent 0148d06205
commit 90e1f6695c
21 changed files with 182 additions and 33 deletions

View File

@ -345,10 +345,16 @@ class InvoiceController extends BaseController
*/ */
public function store(SaveInvoiceWithClientRequest $request) public function store(SaveInvoiceWithClientRequest $request)
{ {
$data = $request->input();
if(!$this->checkUpdatePermission($data, $response)){
return $response;
}
$action = Input::get('action'); $action = Input::get('action');
$entityType = Input::get('entityType'); $entityType = Input::get('entityType');
$invoice = $this->invoiceService->save($request->input()); $invoice = $this->invoiceService->save($data, true);
$entityType = $invoice->getEntityType(); $entityType = $invoice->getEntityType();
$message = trans("texts.created_{$entityType}"); $message = trans("texts.created_{$entityType}");
@ -379,10 +385,16 @@ class InvoiceController extends BaseController
*/ */
public function update(SaveInvoiceWithClientRequest $request) public function update(SaveInvoiceWithClientRequest $request)
{ {
$data = $request->input();
if(!$this->checkUpdatePermission($data, $response)){
return $response;
}
$action = Input::get('action'); $action = Input::get('action');
$entityType = Input::get('entityType'); $entityType = Input::get('entityType');
$invoice = $this->invoiceService->save($request->input()); $invoice = $this->invoiceService->save($data, true);
$entityType = $invoice->getEntityType(); $entityType = $invoice->getEntityType();
$message = trans("texts.updated_{$entityType}"); $message = trans("texts.updated_{$entityType}");
Session::flash('message', $message); Session::flash('message', $message);

View File

@ -584,6 +584,11 @@ class PaymentController extends BaseController
public function store(CreatePaymentRequest $request) public function store(CreatePaymentRequest $request)
{ {
$input = $request->input(); $input = $request->input();
if(!$this->checkUpdatePermission($input, $response)){
return $response;
}
$input['invoice_id'] = Invoice::getPrivateId($input['invoice']); $input['invoice_id'] = Invoice::getPrivateId($input['invoice']);
$input['client_id'] = Client::getPrivateId($input['client']); $input['client_id'] = Client::getPrivateId($input['client']);
$payment = $this->paymentRepo->save($input); $payment = $this->paymentRepo->save($input);
@ -601,6 +606,11 @@ class PaymentController extends BaseController
public function update(UpdatePaymentRequest $request) public function update(UpdatePaymentRequest $request)
{ {
$input = $request->input(); $input = $request->input();
if(!$this->checkUpdatePermission($input, $response)){
return $response;
}
$payment = $this->paymentRepo->save($input); $payment = $this->paymentRepo->save($input);
Session::flash('message', trans('texts.updated_payment')); Session::flash('message', trans('texts.updated_payment'));

View File

@ -68,10 +68,6 @@ class TaskController extends BaseController
*/ */
public function store() public function store()
{ {
if(!$this->checkCreatePermission($response)){
return $response;
}
return $this->save(); return $this->save();
} }
@ -187,6 +183,12 @@ class TaskController extends BaseController
private function save($publicId = null) private function save($publicId = null)
{ {
$action = Input::get('action'); $action = Input::get('action');
$input = $request->input();
if(!$this->checkUpdatePermission($input, $response)){
return $response;
}
if (in_array($action, ['archive', 'delete', 'restore'])) { if (in_array($action, ['archive', 'delete', 'restore'])) {
return self::bulk(); return self::bulk();

View File

@ -77,7 +77,13 @@ class VendorController extends BaseController
*/ */
public function store(CreateVendorRequest $request) public function store(CreateVendorRequest $request)
{ {
$vendor = $this->vendorService->save($request->input()); $data = $request->input();
if(!$this->checkUpdatePermission($data, $response)){
return $response;
}
$vendor = $this->vendorService->save($data);
Session::flash('message', trans('texts.created_vendor')); Session::flash('message', trans('texts.created_vendor'));
@ -195,7 +201,13 @@ class VendorController extends BaseController
*/ */
public function update(UpdateVendorRequest $request) public function update(UpdateVendorRequest $request)
{ {
$vendor = $this->vendorService->save($request->input()); $data = $request->input();
if(!$this->checkUpdatePermission($data, $response)){
return $response;
}
$vendor = $this->vendorService->save($data);
Session::flash('message', trans('texts.updated_vendor')); Session::flash('message', trans('texts.updated_vendor'));

View File

@ -134,8 +134,16 @@ class EntityModel extends Eloquent
return static::whereId($item_id)->first()->user_id == Auth::user()->id; return static::whereId($item_id)->first()->user_id == Auth::user()->id;
} }
public static function canEditItemByOwner($user_id) {
if(Auth::user()->hasPermission('edit_all')) {
return true;
}
return Auth::user()->id == $user_id;
}
public function canView() { public function canView() {
return static::canEdit($this); return static::canViewItem($this);
} }
public static function canViewItem($item) { public static function canViewItem($item) {
@ -149,4 +157,12 @@ class EntityModel extends Eloquent
return static::whereId($item_id)->first()->user_id == Auth::user()->id; return static::whereId($item_id)->first()->user_id == Auth::user()->id;
} }
public static function canViewItemByOwner($user_id) {
if(Auth::user()->hasPermission('view_all')) {
return true;
}
return Auth::user()->id == $user_id;
}
} }

View File

@ -1,5 +1,6 @@
<?php namespace App\Models; <?php namespace App\Models;
use Auth;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
class Product extends EntityModel class Product extends EntityModel

View File

@ -29,6 +29,7 @@ class CreditRepository extends BaseRepository
'credits.public_id', 'credits.public_id',
'clients.name as client_name', 'clients.name as client_name',
'clients.public_id as client_public_id', 'clients.public_id as client_public_id',
'clients.user_id as client_user_id',
'credits.amount', 'credits.amount',
'credits.balance', 'credits.balance',
'credits.credit_date', 'credits.credit_date',

View File

@ -81,11 +81,15 @@ class ExpenseRepository extends BaseRepository
'expenses.vendor_id', 'expenses.vendor_id',
'expenses.expense_currency_id', 'expenses.expense_currency_id',
'expenses.invoice_currency_id', 'expenses.invoice_currency_id',
'expenses.user_id',
'invoices.public_id as invoice_public_id', 'invoices.public_id as invoice_public_id',
'invoices.user_id as invoice_user_id',
'vendors.name as vendor_name', 'vendors.name as vendor_name',
'vendors.public_id as vendor_public_id', 'vendors.public_id as vendor_public_id',
'vendors.user_id as vendor_user_id',
'clients.name as client_name', 'clients.name as client_name',
'clients.public_id as client_public_id', 'clients.public_id as client_public_id',
'clients.user_id as client_user_id',
'contacts.first_name', 'contacts.first_name',
'contacts.email', 'contacts.email',
'contacts.last_name', 'contacts.last_name',

View File

@ -49,6 +49,7 @@ class InvoiceRepository extends BaseRepository
DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'), DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'),
DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'), DB::raw('COALESCE(clients.country_id, accounts.country_id) country_id'),
'clients.public_id as client_public_id', 'clients.public_id as client_public_id',
'clients.user_id as client_user_id',
'invoice_number', 'invoice_number',
'invoice_status_id', 'invoice_status_id',
'clients.name as client_name', 'clients.name as client_name',
@ -190,7 +191,7 @@ class InvoiceRepository extends BaseRepository
->make(); ->make();
} }
public function save($data) public function save($data, $checkSubPermissions = false)
{ {
$account = \Auth::user()->account; $account = \Auth::user()->account;
$publicId = isset($data['public_id']) ? $data['public_id'] : false; $publicId = isset($data['public_id']) ? $data['public_id'] : false;
@ -406,29 +407,40 @@ class InvoiceRepository extends BaseRepository
$task = false; $task = false;
if (isset($item['task_public_id']) && $item['task_public_id']) { if (isset($item['task_public_id']) && $item['task_public_id']) {
$task = Task::scope($item['task_public_id'])->where('invoice_id', '=', null)->firstOrFail(); $task = Task::scope($item['task_public_id'])->where('invoice_id', '=', null)->firstOrFail();
$task->invoice_id = $invoice->id; if(!$checkSubPermissions || $task->canEdit()){
$task->client_id = $invoice->client_id; $task->invoice_id = $invoice->id;
$task->save(); $task->client_id = $invoice->client_id;
$task->save();
}
} }
$expense = false; $expense = false;
if (isset($item['expense_public_id']) && $item['expense_public_id']) { if (isset($item['expense_public_id']) && $item['expense_public_id']) {
$expense = Expense::scope($item['expense_public_id'])->where('invoice_id', '=', null)->firstOrFail(); $expense = Expense::scope($item['expense_public_id'])->where('invoice_id', '=', null)->firstOrFail();
$expense->invoice_id = $invoice->id; if(!$checkSubPermissions || $expense->canEdit()){
$expense->client_id = $invoice->client_id; $expense->invoice_id = $invoice->id;
$expense->save(); $expense->client_id = $invoice->client_id;
$expense->save();
}
} }
if ($productKey = trim($item['product_key'])) { if ($productKey = trim($item['product_key'])) {
if (\Auth::user()->account->update_products && ! strtotime($productKey)) { if (\Auth::user()->account->update_products && ! strtotime($productKey)) {
$product = Product::findProductByKey($productKey); $product = Product::findProductByKey($productKey);
if (!$product) { if (!$product) {
$product = Product::createNew(); if(!$checkSubPermissions || Product::canCreate()){
$product->product_key = trim($item['product_key']); $product = Product::createNew();
$product->product_key = trim($item['product_key']);
}
else{
$product = null;
}
}
if($product && (!$checkSubPermissions || $product->canEdit())){
$product->notes = ($task || $expense) ? '' : $item['notes'];
$product->cost = $expense ? 0 : $item['cost'];
$product->save();
} }
$product->notes = ($task || $expense) ? '' : $item['notes'];
$product->cost = $expense ? 0 : $item['cost'];
$product->save();
} }
} }

View File

@ -36,9 +36,11 @@ class PaymentRepository extends BaseRepository
'payments.transaction_reference', 'payments.transaction_reference',
'clients.name as client_name', 'clients.name as client_name',
'clients.public_id as client_public_id', 'clients.public_id as client_public_id',
'clients.user_id as client_user_id',
'payments.amount', 'payments.amount',
'payments.payment_date', 'payments.payment_date',
'invoices.public_id as invoice_public_id', 'invoices.public_id as invoice_public_id',
'invoices.user_id as invoice_user_id',
'invoices.invoice_number', 'invoices.invoice_number',
'contacts.first_name', 'contacts.first_name',
'contacts.last_name', 'contacts.last_name',

View File

@ -27,6 +27,7 @@ class TaskRepository
'tasks.public_id', 'tasks.public_id',
'clients.name as client_name', 'clients.name as client_name',
'clients.public_id as client_public_id', 'clients.public_id as client_public_id',
'clients.user_id as client_user_id',
'contacts.first_name', 'contacts.first_name',
'contacts.email', 'contacts.email',
'contacts.last_name', 'contacts.last_name',
@ -36,6 +37,7 @@ class TaskRepository
'tasks.deleted_at', 'tasks.deleted_at',
'invoices.invoice_number', 'invoices.invoice_number',
'invoices.public_id as invoice_public_id', 'invoices.public_id as invoice_public_id',
'invoices.user_id as invoice_user_id',
'tasks.is_running', 'tasks.is_running',
'tasks.time_log', 'tasks.time_log',
'tasks.created_at', 'tasks.created_at',

View File

@ -5,6 +5,8 @@ use App\Services\DatatableService;
class BaseService class BaseService
{ {
public static $bulk_actions = array('archive', 'restore', 'delete');
use DispatchesJobs; use DispatchesJobs;
protected function getRepo() protected function getRepo()
@ -14,14 +16,16 @@ class BaseService
public function bulk($ids, $action) public function bulk($ids, $action)
{ {
if ( ! $ids) { if ( ! $ids || ! in_array($action, static::$bulk_actions) ) {
return 0; return 0;
} }
$entities = $this->getRepo()->findByPublicIdsWithTrashed($ids); $entities = $this->getRepo()->findByPublicIdsWithTrashed($ids);
foreach ($entities as $entity) { foreach ($entities as $entity) {
$this->getRepo()->$action($entity); if($entity->canEdit()){
$this->getRepo()->$action($entity);
}
} }
return count($entities); return count($entities);

View File

@ -3,6 +3,8 @@
use Utils; use Utils;
use URL; use URL;
use App\Services\BaseService; use App\Services\BaseService;
use App\Models\Client;
use App\Models\Payment;
use App\Ninja\Repositories\CreditRepository; use App\Ninja\Repositories\CreditRepository;
@ -30,6 +32,10 @@ class CreditService extends BaseService
public function getDatatable($clientPublicId, $search) public function getDatatable($clientPublicId, $search)
{ {
$query = $this->creditRepo->find($clientPublicId, $search); $query = $this->creditRepo->find($clientPublicId, $search);
if(!Utils::hasPermission('view_all')){
$query->where('expenses.user_id', '=', Auth::user()->id);
}
return $this->createDatatable(ENTITY_CREDIT, $query, !$clientPublicId); return $this->createDatatable(ENTITY_CREDIT, $query, !$clientPublicId);
} }
@ -40,6 +46,10 @@ class CreditService extends BaseService
[ [
'client_name', 'client_name',
function ($model) { function ($model) {
if(!Client::canViewItemByOwner($model->client_user_id)){
return Utils::getClientDisplayName($model);
}
return $model->client_public_id ? link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml() : ''; return $model->client_public_id ? link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml() : '';
}, },
! $hideClient ! $hideClient
@ -78,6 +88,9 @@ class CreditService extends BaseService
trans('texts.apply_credit'), trans('texts.apply_credit'),
function ($model) { function ($model) {
return URL::to("payments/create/{$model->client_public_id}") . '?paymentTypeId=1'; return URL::to("payments/create/{$model->client_public_id}") . '?paymentTypeId=1';
},
function ($model) {
return Payment::canCreate();
} }
] ]
]; ];

View File

@ -14,7 +14,9 @@ class DatatableService
if ($actions && $showCheckbox) { if ($actions && $showCheckbox) {
$table->addColumn('checkbox', function ($model) { $table->addColumn('checkbox', function ($model) {
return '<input type="checkbox" name="ids[]" value="' . $model->public_id $can_edit = Auth::user()->hasPermission('edit_all') || (isset($model->user_id) && Auth::user()->id == $model->user_id);
return !$can_edit?'':'<input type="checkbox" name="ids[]" value="' . $model->public_id
. '" ' . Utils::getEntityRowClass($model) . '>'; . '" ' . Utils::getEntityRowClass($model) . '>';
}); });
} }

View File

@ -70,6 +70,10 @@ class ExpenseService extends BaseService
function ($model) function ($model)
{ {
if ($model->vendor_public_id) { if ($model->vendor_public_id) {
if(!Vendor::canViewItemByOwner($model->vendor_user_id)){
return $model->vendor_name;
}
return link_to("vendors/{$model->vendor_public_id}", $model->vendor_name)->toHtml(); return link_to("vendors/{$model->vendor_public_id}", $model->vendor_name)->toHtml();
} else { } else {
return ''; return '';
@ -81,6 +85,10 @@ class ExpenseService extends BaseService
function ($model) function ($model)
{ {
if ($model->client_public_id) { if ($model->client_public_id) {
if(!Client::canViewItemByOwner($model->client_user_id)){
return Utils::getClientDisplayName($model);
}
return link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml(); return link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml();
} else { } else {
return ''; return '';
@ -90,6 +98,10 @@ class ExpenseService extends BaseService
[ [
'expense_date', 'expense_date',
function ($model) { function ($model) {
if(!Expense::canEditItemByOwner($model->user_id)){
return Utils::fromSqlDate($model->expense_date);
}
return link_to("expenses/{$model->public_id}/edit", Utils::fromSqlDate($model->expense_date))->toHtml(); return link_to("expenses/{$model->public_id}/edit", Utils::fromSqlDate($model->expense_date))->toHtml();
} }
], ],
@ -169,7 +181,7 @@ class ExpenseService extends BaseService
return URL::to("/invoices/{$model->invoice_public_id}/edit"); return URL::to("/invoices/{$model->invoice_public_id}/edit");
}, },
function ($model) { function ($model) {
return $model->invoice_public_id && Invoice::canEditItemById($model->invoice_public_id); return $model->invoice_public_id && Invoice::canEditItemByOwner($model->invoice_user_id);
} }
], ],
[ [

View File

@ -9,6 +9,7 @@ use App\Ninja\Repositories\ClientRepository;
use App\Events\QuoteInvitationWasApproved; use App\Events\QuoteInvitationWasApproved;
use App\Models\Invitation; use App\Models\Invitation;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Client;
use App\Models\Payment; use App\Models\Payment;
class InvoiceService extends BaseService class InvoiceService extends BaseService
@ -29,14 +30,26 @@ class InvoiceService extends BaseService
return $this->invoiceRepo; return $this->invoiceRepo;
} }
public function save($data) public function save($data, $checkSubPermissions = false)
{ {
if (isset($data['client'])) { if (isset($data['client'])) {
$client = $this->clientRepo->save($data['client']); $can_save_client = !$checkSubPermissions;
$data['client_id'] = $client->id; if(!$can_save_client){
if(empty($data['client']['public_id']) || $data['client']['public_id']=='-1'){
$can_save_client = Client::canCreate();
}
else{
$can_save_client = Client::wherePublicId($data['client']['public_id'])->first()->canEdit();
}
}
if($can_save_client){
$client = $this->clientRepo->save($data['client']);
$data['client_id'] = $client->id;
}
} }
$invoice = $this->invoiceRepo->save($data); $invoice = $this->invoiceRepo->save($data, $checkSubPermissions);
$client = $invoice->client; $client = $invoice->client;
$client->load('contacts'); $client->load('contacts');
@ -124,12 +137,19 @@ class InvoiceService extends BaseService
[ [
'invoice_number', 'invoice_number',
function ($model) use ($entityType) { function ($model) use ($entityType) {
if(!Invoice::canEditItem($model)){
return $model->invoice_number;
}
return link_to("{$entityType}s/{$model->public_id}/edit", $model->invoice_number, ['class' => Utils::getEntityRowClass($model)])->toHtml(); return link_to("{$entityType}s/{$model->public_id}/edit", $model->invoice_number, ['class' => Utils::getEntityRowClass($model)])->toHtml();
} }
], ],
[ [
'client_name', 'client_name',
function ($model) { function ($model) {
if(!Client::canViewItemByOwner($model->client_user_id)){
return Utils::getClientDisplayName($model);
}
return link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml(); return link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml();
}, },
! $hideClient ! $hideClient

View File

@ -11,6 +11,8 @@ use CreditCard;
use App\Models\Payment; use App\Models\Payment;
use App\Models\Account; use App\Models\Account;
use App\Models\Country; use App\Models\Country;
use App\Models\Client;
use App\Models\Invoice;
use App\Models\AccountGatewayToken; use App\Models\AccountGatewayToken;
use App\Ninja\Repositories\PaymentRepository; use App\Ninja\Repositories\PaymentRepository;
use App\Ninja\Repositories\AccountRepository; use App\Ninja\Repositories\AccountRepository;
@ -300,12 +302,20 @@ class PaymentService extends BaseService
[ [
'invoice_number', 'invoice_number',
function ($model) { function ($model) {
if(!Invoice::canEditItemByOwner($model->invoice_user_id)){
return $model->invoice_number;
}
return link_to("invoices/{$model->invoice_public_id}/edit", $model->invoice_number, ['class' => Utils::getEntityRowClass($model)])->toHtml(); return link_to("invoices/{$model->invoice_public_id}/edit", $model->invoice_number, ['class' => Utils::getEntityRowClass($model)])->toHtml();
} }
], ],
[ [
'client_name', 'client_name',
function ($model) { function ($model) {
if(!Client::canViewItemByOwner($model->client_user_id)){
return Utils::getClientDisplayName($model);
}
return $model->client_public_id ? link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml() : ''; return $model->client_public_id ? link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml() : '';
}, },
! $hideClient ! $hideClient

View File

@ -5,6 +5,7 @@ use URL;
use Utils; use Utils;
use App\Models\Task; use App\Models\Task;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Client;
use App\Ninja\Repositories\TaskRepository; use App\Ninja\Repositories\TaskRepository;
use App\Services\BaseService; use App\Services\BaseService;
@ -48,6 +49,10 @@ class TaskService extends BaseService
[ [
'client_name', 'client_name',
function ($model) { function ($model) {
if(!Client::canViewItemByOwner($model->client_user_id)){
return Utils::getClientDisplayName($model);
}
return $model->client_public_id ? link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml() : ''; return $model->client_public_id ? link_to("clients/{$model->client_public_id}", Utils::getClientDisplayName($model))->toHtml() : '';
}, },
! $hideClient ! $hideClient
@ -97,7 +102,7 @@ class TaskService extends BaseService
return URL::to("/invoices/{$model->invoice_public_id}/edit"); return URL::to("/invoices/{$model->invoice_public_id}/edit");
}, },
function ($model) { function ($model) {
return $model->invoice_number && Invoice::canEditItemById($model->invoice_number); return $model->invoice_number && Invoice::canEditItemByOwner($model->invoice_user_id);
} }
], ],
[ [

View File

@ -38,6 +38,10 @@ class VendorService extends BaseService
public function getDatatable($search) public function getDatatable($search)
{ {
$query = $this->vendorRepo->find($search); $query = $this->vendorRepo->find($search);
if(!Utils::hasPermission('view_all')){
$query->where('vendors.user_id', '=', Auth::user()->id);
}
return $this->createDatatable(ENTITY_VENDOR, $query); return $this->createDatatable(ENTITY_VENDOR, $query);
} }

View File

@ -1068,7 +1068,7 @@ $LANG = array(
'administrator' => 'Administrator', 'administrator' => 'Administrator',
'administrator_help' => 'Allow user to manage users, change settings, and view and modify all data', 'administrator_help' => 'Allow user to manage users, change settings, and view and modify all data',
'user_create_all' => 'Create clients, invoices, etc.', 'user_create_all' => 'Create clients, invoices, etc.',
'user_view_all' => 'View All clients, invoices, etc.', 'user_view_all' => 'View all clients, invoices, etc.',
'user_edit_all' => 'Edit all clients, invoices, etc.', 'user_edit_all' => 'Edit all clients, invoices, etc.',
); );

View File

@ -63,8 +63,13 @@
<label for="client" class="control-label col-lg-4 col-sm-4">{{ trans('texts.client') }}</label> <label for="client" class="control-label col-lg-4 col-sm-4">{{ trans('texts.client') }}</label>
<div class="col-lg-8 col-sm-8"> <div class="col-lg-8 col-sm-8">
<h4><div data-bind="text: getClientDisplayName(ko.toJS(client()))"></div></h4> <h4><div data-bind="text: getClientDisplayName(ko.toJS(client()))"></div></h4>
<a id="editClientLink" class="pointer" data-bind="click: $root.showClientForm">{{ trans('texts.edit_client') }}</a> |
{!! link_to('/clients/'.$invoice->client->public_id, trans('texts.view_client'), ['target' => '_blank']) !!} @if($invoice->client->canView() || true)
@if ($invoice->client->canEdit() || true)
<a id="editClientLink" class="pointer" data-bind="click: $root.showClientForm">{{ trans('texts.edit_client') }}</a> |
@endif
{!! link_to('/clients/'.$invoice->client->public_id, trans('texts.view_client'), ['target' => '_blank']) !!}
@endif
</div> </div>
</div> </div>
<div style="display:none"> <div style="display:none">