This commit is contained in:
ericli1018
2025-06-13 12:24:35 +08:00
parent 1caae33c43
commit 6dfe3e0677
74 changed files with 1497 additions and 253 deletions

View File

@ -82,11 +82,13 @@ class EventCrudController extends CrudController
'label' => trans('backend.columnName.post_at'),
'type' => 'datetime',
'format' => 'YYYY/MM/DD HH:mm:SS',
'default' => \Carbon\Carbon::now(),
],
[
'name' => 'is_front_show',
'label' => trans('backend.columnName.is_front_show'),
'type' => 'boolean'
'type' => 'boolean',
'default' => true,
],
[
'name' => 'title',
@ -104,6 +106,13 @@ class EventCrudController extends CrudController
'showSingleChoise' => '0', // 0=hidden, 1=show(default)
'showComment' => '0', // 0=hidden, 1=show(default)
],
[
'name' => 'event_at',
'label' => trans('backend.columnName.event_at'),
'type' => 'datetime',
'format' => 'YYYY/MM/DD HH:mm:SS',
'default' => \Carbon\Carbon::now(),
],
[
'name' => 'venue',
'label' => trans('backend.columnName.venue'),
@ -122,9 +131,9 @@ class EventCrudController extends CrudController
'options' => [
//'selector' => 'textarea.tinymce',
//'skin' => 'dick-light',
'plugins' => 'lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'plugins' => 'code lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'menubar' => 'edit insert view format help',
'toolbar' => 'undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'toolbar' => 'code undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'language' => str_replace('-', '_', app()->getLocale()),
'height' => '500px',
],

View File

@ -19,7 +19,17 @@ class HomeCarouselCrudController extends CrudController
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;
//use \Backpack\CRUD\app\Http\Controllers\Operations\ShowOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\ReorderOperation;
use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation { destroy as traitDestroy; }
public function destroy($id)
{
//CRUD::hasAccessOrFail('delete');
if (\App\Models\HomeCarousel::count() <= 7)
{
$this->crud->allowAccess('create');
}
return CRUD::delete($id);
}
/**
* Configure the CrudPanel object. Apply settings to all operations.
*
@ -31,6 +41,7 @@ class HomeCarouselCrudController extends CrudController
CRUD::setRoute(config('backpack.base.route_prefix') . '/home-carousel');
CRUD::setEntityNameStrings(trans('backend.home_carousel.content.item'), trans('backend.home_carousel.content.items'));
}
protected function setupReorderOperation()
@ -51,6 +62,15 @@ class HomeCarouselCrudController extends CrudController
$this->crud->orderBy('lft', 'asc')->orderBy('id', 'desc');
}
if (\App\Models\HomeCarousel::count() >= 6)
{
$this->crud->denyAccess('create');
}
else
{
$this->crud->allowAccess('create');
}
$this->crud->addColumns([
[
'name' => 'is_front_show',
@ -96,6 +116,17 @@ class HomeCarouselCrudController extends CrudController
'label' => trans('backend.columnName.link'),
'type' => 'text'
],
[
'name' => 'featured_photos',
'label' => trans('backend.columnName.featured_img'),
'type' => 'upload_img_multiple',
'upload' => true,
'disk' => 'public',
'hint' => '',
'qty' => 1, // 0=no limit, >0=limit
'showSingleChoise' => '0', // 0=hidden, 1=show(default)
'showComment' => '0', // 0=hidden, 1=show(default)
],
[
'name' => 'photos',
'label' => trans('backend.columnName.cover'),

View File

@ -82,16 +82,20 @@ class NewsCrudController extends CrudController
'label' => trans('backend.columnName.post_at'),
'type' => 'datetime',
'format' => 'YYYY/MM/DD HH:mm:SS',
'default' => \Carbon\Carbon::now(),
],
[
'name' => 'is_front_show',
'label' => trans('backend.columnName.is_front_show'),
'type' => 'boolean'
'type' => 'boolean',
'default' => true,
],
[
'name' => 'title',
'label' => trans('backend.columnName.title'),
'type' => 'text'
'type' => 'text',
],
[
'name' => 'photos',
@ -117,9 +121,9 @@ class NewsCrudController extends CrudController
'options' => [
//'selector' => 'textarea.tinymce',
//'skin' => 'dick-light',
'plugins' => 'lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'plugins' => 'code lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'menubar' => 'edit insert view format help',
'toolbar' => 'undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'toolbar' => 'code undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'language' => str_replace('-', '_', app()->getLocale()),
'height' => '500px',
],

View File

@ -132,7 +132,8 @@ class ProductCrudController extends CrudController
[
'name' => 'is_front_show',
'label' => trans('backend.columnName.is_front_show'),
'type' => 'boolean'
'type' => 'boolean',
'default' => true,
],
[
'name' => 'tip',
@ -168,9 +169,9 @@ class ProductCrudController extends CrudController
'options' => [
//'selector' => 'textarea.tinymce',
//'skin' => 'dick-light',
'plugins' => 'lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'plugins' => 'code lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'menubar' => 'edit insert view format help',
'toolbar' => 'undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'toolbar' => 'code undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'language' => str_replace('-', '_', app()->getLocale()),
'height' => '500px',
],
@ -183,9 +184,9 @@ class ProductCrudController extends CrudController
'options' => [
//'selector' => 'textarea.tinymce',
//'skin' => 'dick-light',
'plugins' => 'lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'plugins' => 'code lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'menubar' => 'edit insert view format help',
'toolbar' => 'undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'toolbar' => 'code undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'language' => str_replace('-', '_', app()->getLocale()),
'height' => '500px',
],
@ -199,13 +200,61 @@ class ProductCrudController extends CrudController
'options' => [
//'selector' => 'textarea.tinymce',
//'skin' => 'dick-light',
'plugins' => 'lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'plugins' => 'code lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'menubar' => 'edit insert view format help',
'toolbar' => 'undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'toolbar' => 'code undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'language' => str_replace('-', '_', app()->getLocale()),
'height' => '500px',
],
],
[
'name' => 'feature_resource',
'lable' => trans('backend.columnName.feature_resource'),
'type' => 'tinymce',
// optional overwrite of the configuration array
'options' => [
//'selector' => 'textarea.tinymce',
//'skin' => 'dick-light',
'plugins' => 'code lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'menubar' => 'edit insert view format help',
'toolbar' => 'code undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'language' => str_replace('-', '_', app()->getLocale()),
'height' => '500px',
],
],
[
'name' => 'feature_related_part',
'lable' => trans('backend.columnName.feature_related_part'),
'type' => 'tinymce',
// optional overwrite of the configuration array
'options' => [
//'selector' => 'textarea.tinymce',
//'skin' => 'dick-light',
'plugins' => 'code lists advlist image link media anchor table hr imagetools importcss insertdatetime paste searchreplace textcolor textpattern help',
'menubar' => 'edit insert view format help',
'toolbar' => 'code undo redo bold italic alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image media link',
'language' => str_replace('-', '_', app()->getLocale()),
'height' => '500px',
],
],
[
'name' => 'productRelateds',
'label' => trans('backend.columnName.product_related'),
'type' => 'select2_multiple',
'entity' => 'productRelateds',
'attribute' => 'title',
'model' => 'App\Models\Product',
'pivot' => true,
'allows_null' => true,
'select_all' => true,
'options' => (function ($query) {
$id = \Route::current()->parameter('id');
return $query->where('id', '<>', $id)->orderBy('title', 'ASC')->get();
}),
],
[
'name' => 'seo_keyword',

View File

@ -97,7 +97,8 @@ class SupportDistributionPartnerCrudController extends CrudController
[
'name' => 'is_front_show',
'label' => trans('backend.columnName.is_front_show'),
'type' => 'boolean'
'type' => 'boolean',
'default' => true,
],
[
'name' => 'photos',

View File

@ -97,7 +97,8 @@ class SupportEcosystemPartnerCrudController extends CrudController
[
'name' => 'is_front_show',
'label' => trans('backend.columnName.is_front_show'),
'type' => 'boolean'
'type' => 'boolean',
'default' => true,
],
[
'name' => 'photos',

View File

@ -24,6 +24,26 @@ class UserCrudController extends OrgController
'label' => trans('backpack::permissionmanager.email'),
'type' => 'email',
],
[
'name' => 'phone',
'label' => trans('backend.columnName.phone'),
'type' => 'text',
],
[
'name' => 'country',
'label' => trans('backend.columnName.country'),
'type' => 'text',
],
[
'name' => 'company',
'label' => trans('backend.columnName.company'),
'type' => 'text',
],
[
'name' => 'job_title',
'label' => trans('backend.columnName.job_title'),
'type' => 'text',
],
[ // n-n relationship (with pivot table)
'label' => trans('backpack::permissionmanager.roles'), // Table column heading
'type' => 'select_multiple',

View File

@ -15,7 +15,7 @@ class EventsController extends Controller
$dataRows = \App\Models\Event::where('is_front_show', '=', true)
->orderBy('post_at', 'desc')
->select('id', 'title', 'venue', 'contact', 'photos', 'post_at');
->select('id', 'title', 'venue', 'event_at', 'contact', 'photos', 'post_at');
return view('events', [
'dataRows' => $dataRows->skip($pageOffset)->take($perPageItems)->get(),

View File

@ -3,6 +3,9 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Mail\SubscripeionMail;
use Validator;
class HomeController extends Controller
{
@ -14,7 +17,7 @@ class HomeController extends Controller
$newsRows = \App\Models\News::where('is_front_show', '=', true)
->orderBy('post_at', 'desc')
->take('3');
$eventRows = \App\Models\News::where('is_front_show', '=', true)
$eventRows = \App\Models\Event::where('is_front_show', '=', true)
->orderBy('post_at', 'desc')
->take('3');
return view('home', [
@ -23,4 +26,53 @@ class HomeController extends Controller
'eventRows' => $eventRows->get(),
]);
}
public function indexPost(Request $request)
{
$message = '';
$result = 'success';
$subscribeInquery = $request->input('subscribeInquery');
if ($subscribeInquery)
{
try
{
//$request->validate();
$validator = Validator::make($request->all(), [
'subscribeInquery' => 'required|email',
], $messages = [
'required' => 'The :attribute field is required.',
'email' => 'The :attribute field is not a email address.',
]);
if ($validator->fails())
{
$result = 'errorSubscribe';
$message = 'Opps Please try again.';
}
else
{
//
Mail::to('newsletter.cri@coreality-inc.com')->send(
new SubscripeionMail($subscribeInquery)
);
$result = 'successSubscribe';
$message = 'We have received your subscribe inquiry';
}
}
catch (Exception $ex)
{
$result = 'errorSubscribe';
$message = 'Opps Please try again.';
}
}
if ($message != '')
{
return redirect()->back()->with($result, $message);
}
else
return redirect()->back();
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
/**
* Display login page.
*
* @return Renderable
*/
public function show()
{
return view('auth.login');
}
/**
* Handle account login request
*
* @param LoginRequest $request
*
* @return \Illuminate\Http\Response
*/
public function login(LoginRequest $request)
{
$credentials = $request->getCredentials();
if(!Auth::validate($credentials)):
return redirect()->to('login')
->withErrors(trans('auth.failed'));
endif;
$user = Auth::getProvider()->retrieveByCredentials($credentials);
Auth::login($user);
return $this->authenticated($request, $user);
}
/**
* Handle response after user authenticated
*
* @param Request $request
* @param Auth $user
*
* @return \Illuminate\Http\Response
*/
protected function authenticated(Request $request, $user)
{
return redirect()->intended();
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
class LogoutController extends Controller
{
/**
* Log out account user.
*
* @return \Illuminate\Routing\Redirector
*/
public function perform()
{
Session::flush();
Auth::logout();
return redirect('login');
}
}

View File

@ -19,12 +19,8 @@ class ProductsController extends Controller
$pageOffset = $perPageItems * ($page - 1);
$productRows = \App\Models\Product::where('is_front_show', '=', true)
->orderByRaw("CASE
WHEN tip = 'none' THEN 1
WHEN tip = 'new' THEN 2
WHEN tip = 'on_sale' THEN 3
END DESC")
->orderBy('id', 'DESC');
->orderByRaw("CASE WHEN tip LIKE 'on_sale' THEN 1 WHEN tip LIKE 'new' THEN 2 ELSE 3 END");
//->orderBy('id', 'DESC');
$dataCatalogs = \App\Models\ProductCatalog::where('is_front_show', '=', true)
->orderBy('lft', 'asc')
@ -61,7 +57,9 @@ class ProductsController extends Controller
$productCount = $productRows->count();
$productRows = $productRows->skip($pageOffset)->take($perPageItems)->get();
$productRows = $productRows->skip($pageOffset)->take($perPageItems);
//var_dump($productRows->toSql());
$productRows = $productRows->get();
foreach ($productRows as $row)
{
$row->{'applications'} = \App\Models\Product::find($row->id)->productApplications()->get();
@ -105,6 +103,7 @@ class ProductsController extends Controller
'catalogName' => $catalogName,
'catalogSlug' => $catalogSlug,
'productApplications' => $dataRow->productApplications()->get(),
'productRelateds' => $dataRow->productRelateds()->get(),
]);
}

View File

@ -0,0 +1,36 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Requests\RegisterRequest;
class RegisterController extends Controller
{
/**
* Display register page.
*
* @return \Illuminate\Http\Response
*/
public function show()
{
return view('auth.register');
}
/**
* Handle account registration request
*
* @param RegisterRequest $request
*
* @return \Illuminate\Http\Response
*/
public function register(RegisterRequest $request)
{
$user = User::create($request->validated());
auth()->login($user);
return redirect('/')->with('success', "Account successfully registered.");
}
}

View File

@ -32,7 +32,7 @@ class SupportDistributionPartnersController extends Controller
$dataRows = \App\Models\SupportDistributionPartner::where('support_distribution_partner_catalog_id', '=', $catalogId)
->where('is_front_show', '=', true)
->orderBy('title', 'desc')
->orderBy('title', 'asc')
->select('id', 'title', 'description', 'photos', 'website');
return view('support-distribution-partners', [

View File

@ -21,12 +21,21 @@ class SupportEcosystemPartnersController extends Controller
->orderBy('lft', 'asc')
->orderBy('id', 'desc')
->select('id', 'name');
if ($catalogId == 0)
{
$catalogRowsGet = $catalogRows->get();
foreach ($catalogRowsGet as $row)
{
$catalogId = $row->id;
break;
}
}
$dataRows = \App\Models\SupportEcosystemPartner::where('support_ecosystem_partner_catalog_id', '=', $catalogId)
->where('is_front_show', '=', true)
->orderBy('title', 'desc')
->orderBy('title', 'asc')
->select('id', 'title', 'description', 'photos', 'website');
return view('support-ecosystem-partners', [
'catalogRows' => $catalogRows->get(),
'catalogCurrentId' => $catalogId,

View File

@ -5,16 +5,26 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request;
use \App\Http\Requests\SupportSaleRequest;
use Carbon\Carbon;
use Illuminate\Support\Facades\Mail;
use App\Mail\SalesInquiryMail;
class SupportSalesInquiryController extends Controller
{
public function index(Request $request)
{
$product = '';
$pid = $request->get('pid');
$product = \App\Models\Product::where('id', '=', $pid)->where('is_front_show', '=', true)->first();
if ($product)
if ($pid > 0)
{
$product = 'I am interested in ' . $product->title;
$product = \App\Models\Product::where('id', '=', $pid)->where('is_front_show', '=', true)->first();
if ($product)
{
$product = 'I am interested in ' . $product->title;
}
}
else if ($request->has('comment'))
{
$product = $request->get('comment');
}
return view('support-sales-inquiry',[
'productName' => $product,
@ -34,6 +44,28 @@ class SupportSalesInquiryController extends Controller
'comments' => $request->input('comments'),
'created_at' => Carbon::now(),
]);
try
{
$data = 'First Name: ' . $request->input('name_first') . "\n";
$data .= 'Last Name: ' . $request->input('name_last') . "\n";
$data .= 'Company Name: ' . $request->input('company_name') . "\n";
$data .= 'Job Title: ' . $request->input('job_title') . "\n";
$data .= 'Email: ' . $request->input('email') . "\n";
$data .= 'Phone: ' . $request->input('phone') . "\n";
$data .= 'Contry: ' . $request->input('contry') . "\n";
$data .= 'Comments: ' . $request->input('comments') . "\n";
$data .= 'Created At ' . Carbon::now() . "\n";
Mail::to('sales.cri@coreality-inc.com')->send(
new SalesInquiryMail($data)
);
}
catch (Exception $ex)
{
}
return redirect()->back()->with('success', 'We have received your sales inquiry');
}
}

View File

@ -5,6 +5,8 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request;
use \App\Http\Requests\SupportTechnicalRequest;
use Carbon\Carbon;
use Illuminate\Support\Facades\Mail;
use App\Mail\CustomerServiceMail;
class SupportTechnicalController extends Controller
{
@ -26,6 +28,27 @@ class SupportTechnicalController extends Controller
'comments' => $request->input('comments'),
'created_at' => Carbon::now(),
]);
return redirect()->back()->with('success', 'We have received your technical inquiry');
try
{
$data = 'First Name: ' . $request->input('name_first') . "\n";
$data .= 'Last Name: ' . $request->input('name_last') . "\n";
$data .= 'Company Name: ' . $request->input('company_name') . "\n";
$data .= 'Job Title: ' . $request->input('job_title') . "\n";
$data .= 'Email: ' . $request->input('email') . "\n";
$data .= 'Phone: ' . $request->input('phone') . "\n";
$data .= 'Contry: ' . $request->input('contry') . "\n";
$data .= 'Comments: ' . $request->input('comments') . "\n";
$data .= 'Created At ' . Carbon::now() . "\n";
Mail::to('service.cri@coreality-inc.com')->send(
new CustomerServiceMail($data)
);
}
catch (Exception $ex)
{
}
return redirect()->back()->with('success', 'We have received your customer sercvice inquiry');
}
}

View File

@ -22,6 +22,7 @@ class Kernel extends HttpKernel
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\Spatie\CookieConsent\CookieConsentMiddleware::class,
\App\Http\Middleware\AddCspNonceToScripts::class,
];
/**

View File

@ -0,0 +1,85 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class AddCspNonceToScripts
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
// 只處理 HTML 響應
if ($response->headers->get('Content-Type') === 'text/html; charset=UTF-8') {
$content = $response->getContent();
// 儲存提取出的樣式內容
$styles = [];
$styleCounter = 0;
// 第一步:處理內聯樣式,將 style 轉換為 class
$content = preg_replace_callback(
'/<([a-z][a-z0-9]*)\b([^>]*)style=["\']([^"\']+)["\']([^>]*)>/i',
function ($matches) use (&$styles, &$styleCounter) {
$tag = $matches[1]; // 標籤名稱,例如 div
$beforeAttrs = trim($matches[2]); // style 前的屬性
$styleContent = $matches[3]; // 內聯樣式內容
$afterAttrs = trim($matches[4]); // style 後的屬性
// 生成唯一的 class 名稱
$className = 'inline-style-' . $styleCounter++;
$styles[$className] = $styleContent;
// 組合新的標籤,保留其他屬性並添加 class
$newAttrs = $beforeAttrs . ($beforeAttrs ? ' ' : '') . 'class="' . $className . '"' . ($afterAttrs ? ' ' : '') . $afterAttrs;
return '<' . $tag . ' ' . trim($newAttrs) . '>';
},
$content
);
// 第二步:為 <script> 和 <style> 標籤添加 nonce
$content = preg_replace_callback(
'/<(script|style)\b([^>]*)>(.*?)<\/\1>/is',
function ($matches) {
$tag = $matches[1];
$attributes = $matches[2];
$contentInside = $matches[3];
if (strpos($attributes, 'nonce=') !== false) {
return $matches[0];
}
$nonce = csp_nonce();
return '<' . $tag . ' ' . $attributes . ' nonce="' . $nonce . '">' . $contentInside . '</' . $tag . '>';
},
$content
);
// 第三步:將提取的樣式追加為 <style> 標籤
if (!empty($styles)) {
$styleBlock = '<style nonce="' . csp_nonce() . '">' . PHP_EOL;
foreach ($styles as $className => $styleContent) {
$styleBlock .= '.' . $className . ' {' . $styleContent . '}' . PHP_EOL;
}
$styleBlock .= '</style>';
// 將樣式塊插入到 </head> 之前(如果有 head否則插入到文件末尾
$content = str_contains($content, '</head>')
? str_replace('</head>', $styleBlock . '</head>', $content)
: $content . $styleBlock;
}
$response->setContent($content);
}
return $response;
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
class LoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'username' => 'required',
'password' => 'required'
];
}
/**
* Get the needed authorization credentials from the request.
*
* @return array
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function getCredentials()
{
// The form field for providing username or password
// have name of "username", however, in order to support
// logging users in with both (username and email)
// we have to check if user has entered one or another
$username = $this->get('username');
if ($this->isEmail($username)) {
return [
'email' => $username,
'password' => $this->get('password')
];
}
return $this->only('username', 'password');
}
/**
* Validate if provided parameter is valid email.
*
* @param $param
* @return bool
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
private function isEmail($param)
{
$factory = $this->container->make(ValidationFactory::class);
return ! $factory->make(
['username' => $param],
['username' => 'email']
)->fails();
}
}

View File

@ -3,6 +3,7 @@
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request;
class ProductApplicationRequest extends FormRequest
{
@ -24,8 +25,9 @@ class ProductApplicationRequest extends FormRequest
*/
public function rules()
{
$slug = request()->post('slug');
return [
'slug' => 'required|unique:product_applications,slug',
'slug' => 'required|unique:product_applications,slug,'.$this->id.',id',
];
}

View File

@ -25,7 +25,7 @@ class ProductCatalogRequest extends FormRequest
public function rules()
{
return [
'slug' => 'required|unique:product_catalogs,slug',
'slug' => 'required|unique:product_catalogs,slug,'.$this->id.',id',
];
}

View File

@ -25,7 +25,7 @@ class ProductRequest extends FormRequest
public function rules()
{
return [
// 'slug' => 'required|unique:products,slug',
'slug' => 'required|unique:product_catalogs,slug,'.$this->id.',id',
];
}

View File

@ -0,0 +1,33 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RegisterRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'email' => 'required|email:rfc,dns|unique:users,email',
//'username' => 'required|unique:users,username',
'password' => 'required|min:8',
'password_confirmation' => 'required|same:password',
'name' => 'required',
'phone' => 'required',
];
}
}

View File

@ -14,7 +14,8 @@ class SupportSaleRequest extends FormRequest
public function authorize()
{
// only allow updates if the user is logged in
return backpack_auth()->check();
//return backpack_auth()->check();
return true;
}
/**

View File

@ -14,7 +14,8 @@ class SupportTechnicalRequest extends FormRequest
public function authorize()
{
// only allow updates if the user is logged in
return backpack_auth()->check();
//return backpack_auth()->check();
return true;
}
/**

View File

@ -0,0 +1,55 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class CustomerServiceMail extends Mailable
{
use Queueable, SerializesModels;
public $data;
/**
* Create a new message instance.
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: 'Customer Service Mail',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'mail.customer_service',
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class SalesInquiryMail extends Mailable
{
use Queueable, SerializesModels;
public $data;
/**
* Create a new message instance.
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: 'Sales Inquiry Mail',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'mail.sales_inquery',
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class SubscripeionMail extends Mailable
{
use Queueable, SerializesModels;
public $data;
/**
* Create a new message instance.
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: 'Subscripeion Mail',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'mail.subscribe_inquery',
);
}
/**
* Get the attachments for the message.
*
* @return array<int, \Illuminate\Mail\Mailables\Attachment>
*/
public function attachments(): array
{
return [];
}
}

View File

@ -30,6 +30,7 @@ class Event extends Model
public $translatable = ['title', 'body', 'venue', 'contact', 'seo_keyword', 'seo_description'];
protected $casts = [
'post_at' => 'datetime',
'event_at' => 'datetime',
'photos' => 'array',
];
/*

View File

@ -30,6 +30,7 @@ class HomeCarousel extends Model
public $translatable = ['title','body'];
protected $casts = [
'photos' => 'array',
'featured_photos' => 'array',
];
/*
@ -40,13 +41,28 @@ class HomeCarousel extends Model
public static function boot()
{
parent::boot();
static::creating(function ($model) {
$limit = 6;
$actualCount = HomeCarousel::query()->count();
if ($actualCount >= $limit) {
return false;
}
});
static::deleting(function($obj) {
if (count((array)$obj->photos)) {
foreach ($obj->photos as $item) {
\Storage::disk('public')->delete($item['file_path']);
}
}
if (count((array)$obj->featured_photos)) {
foreach ($obj->featured_photos as $item) {
\Storage::disk('public')->delete($item['file_path']);
}
}
});
}
/*
|--------------------------------------------------------------------------
@ -85,6 +101,14 @@ class HomeCarousel extends Model
$disk = "public";
$destination_path = "home_carousel";
$this->uploadImgMultipleFilesToDisk($value, $attribute_name, $disk, $destination_path);
}
public function setFeaturedPhotosAttribute($value)
{
$attribute_name = "featured_photos";
$disk = "public";
$destination_path = "home_carousel";
$this->uploadImgMultipleFilesToDisk($value, $attribute_name, $disk, $destination_path);
}
}

View File

@ -27,7 +27,7 @@ class Product extends Model
protected $guarded = ['id'];
// protected $fillable = [];
// protected $hidden = [];
public $translatable = ['title', 'tip', 'description', 'body', 'feature_overview', 'feature_spec', 'seo_keyword', 'seo_description'];
public $translatable = ['title', 'description', 'body', 'feature_overview', 'feature_spec', 'seo_keyword', 'seo_description'];
protected $casts = [
'photos' => 'array',
];
@ -53,6 +53,11 @@ class Product extends Model
| RELATIONS
|--------------------------------------------------------------------------
*/
public function productRelateds()
{
return $this->belongsToMany(Product::class, 'product_product_related', 'product_id', 'product_related_id');
}
public function productCatalog()
{
return $this->belongsTo(ProductCatalog::class, 'product_catalog_id');

View File

@ -24,6 +24,10 @@ class User extends Authenticatable
'name',
'email',
'password',
'phone',
'country',
'company',
'job_title',
];
/**

View File

@ -0,0 +1,43 @@
<?php
namespace App\Support;
use Spatie\Csp\Directive;
use Spatie\Csp\Policies\Basic;
class MyCustomPolicy extends Basic
{
public function configure()
{
parent::configure();
$this->addDirective(Directive::FRAME, [
//\Spatie\Csp\Keyword::UNSAFE_INLINE,
\Spatie\Csp\Keyword::SELF,
//\Spatie\Csp\Keyword::UNSAFE_HASHES,
'www.google.com'
]);
$this->addDirective(Directive::STYLE, [
//\Spatie\Csp\Keyword::UNSAFE_INLINE,
\Spatie\Csp\Keyword::SELF,
//\Spatie\Csp\Keyword::UNSAFE_HASHES,
'fonts.googleapis.com'
]);
$this->addDirective(Directive::SCRIPT, [
// \Spatie\Csp\Keyword::UNSAFE_INLINE,
\Spatie\Csp\Keyword::SELF,
//\Spatie\Csp\Keyword::UNSAFE_HASHES,
'fonts.googleapis.com'
]);
$this->addDirective(Directive::FONT, [
\Spatie\Csp\Keyword::STRICT_DYNAMIC,
\Spatie\Csp\Keyword::SELF,
'fonts.gstatic.com'
]);
$this->addDirective(Directive::IMG, [
\Spatie\Csp\Keyword::STRICT_DYNAMIC,
\Spatie\Csp\Keyword::SELF,
'data:'
]);
$this->addNonceForDirective(Directive::SCRIPT)
->addNonceForDirective(Directive::STYLE);
}
}