249 lines
9.4 KiB
PHP
249 lines
9.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Enums\CustomerExportType;
|
|
use App\Http\Requests\CustomerExport;
|
|
use App\Models\Brand;
|
|
use App\Models\Customer;
|
|
use App\Models\CustomerInfo;
|
|
use App\Models\CustomerLogin;
|
|
use App\Models\SingleOptin;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Illuminate\Support\Facades\Session;
|
|
use Illuminate\Support\Str;
|
|
use League\Csv\Writer;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
class CustomerController extends Controller
|
|
{
|
|
public function index(Request $request)
|
|
{
|
|
$modelTable = (new Customer())->getTable();
|
|
$modelClass = Customer::class;
|
|
$brands = Brand::select('id', 'name')->get();
|
|
$columns = ['lastname', 'firstname', 'opt_in'];
|
|
|
|
/** @var \Illuminate\Database\Eloquent\Builder */
|
|
$query = CustomerInfo::with(['customer']);
|
|
if (request()->brand) {
|
|
$query = $query->where('brand_id', $request->brand);
|
|
}
|
|
|
|
// Search on crud Label column
|
|
if ($request->search) {
|
|
foreach ($columns as $column) {
|
|
$query = $query->orWhere($column, 'LIKE', "%$request->search%");
|
|
}
|
|
$query = $query->orWhereHas('customer', function ($q) use ($request) {
|
|
$q->where('email', 'LIKE', "%$request->search%");
|
|
});
|
|
}
|
|
|
|
// Sort columns
|
|
if ($request->sort_col) {
|
|
Session::put("crud.$modelTable.sort_col", $request->sort_col);
|
|
}
|
|
if ($request->sort_way) {
|
|
Session::put("crud.$modelTable.sort_way", $request->sort_way);
|
|
}
|
|
|
|
if ($request->rst) {
|
|
Session::remove("crud.$modelTable.sort_way");
|
|
Session::remove("crud.$modelTable.sort_col");
|
|
}
|
|
if (
|
|
Session::has("crud.$modelTable.sort_col") and
|
|
Session::has("crud.$modelTable.sort_way") and
|
|
Schema::hasColumn($modelTable, Session::get("crud.$modelTable.sort_col"))
|
|
) {
|
|
$query = $query->orderBy(
|
|
Session::get("crud.$modelTable.sort_col"),
|
|
Session::get("crud.$modelTable.sort_way")
|
|
);
|
|
}
|
|
|
|
/** @var \Illuminate\Pagination\AbstractPaginator */
|
|
$customers = $query->paginate(config('crud.paginate', 50));
|
|
|
|
// use a crud controller (any) to gather crudModels
|
|
$modelsClasses = (new BrandController())->getCrudModels();
|
|
return view('customer.index', compact(
|
|
'modelsClasses',
|
|
'modelClass',
|
|
'modelTable',
|
|
'customers',
|
|
'brands'
|
|
));
|
|
}
|
|
|
|
public function show(Customer $customer, Brand $brand)
|
|
{
|
|
$customerInfos = CustomerInfo::where('customer_id', $customer->id)
|
|
->where('brand_id', $brand->id)->firstOrFail();
|
|
$customerLogin = CustomerLogin::where('customer_id', $customer->id)
|
|
->where('brand_id', $brand->id)->first();
|
|
|
|
// use a crud controller (any) to gather crudModels
|
|
$modelsClasses = (new BrandController())->getCrudModels();
|
|
return view('customer.show', compact(
|
|
'modelsClasses',
|
|
'customerInfos',
|
|
'customerLogin'
|
|
));
|
|
}
|
|
|
|
public function filter($texte, Brand $brand = null)
|
|
{
|
|
if ($brand) {
|
|
$customers = Customer::join('customer_infos', 'customers.id', '=', 'customer_infos.customer_id')
|
|
->join('customer_logins', 'customers.id', '=', 'customer_logins.customer_id')->select(
|
|
'customer_infos.customer_id',
|
|
'customer_infos.firstname',
|
|
'customer_infos.lastname',
|
|
'customer_infos.opt_in',
|
|
'customers.email',
|
|
'customer_infos.brand_id',
|
|
'customer_logins.last_connection'
|
|
)->where([
|
|
['lastname', 'like', '%' . $texte . '%'],
|
|
['customer_infos.brand_id', $brand->id],
|
|
['customer_logins.brand_id', $brand->id]
|
|
])->orWhere([
|
|
['email', 'like', '%' . $texte . '%'],
|
|
['customer_infos.brand_id', $brand->id],
|
|
['customer_logins.brand_id', $brand->id]
|
|
])->get();
|
|
} else {
|
|
$customers = CustomerInfo::join('customers', 'customers.id', '=', 'customer_infos.customer_id')
|
|
->join('customer_logins', function ($join) {
|
|
$join->on('customer_logins.customer_id', '=', 'customer_infos.customer_id');
|
|
$join->on('customer_logins.brand_id', '=', 'customer_infos.brand_id');
|
|
})->select(
|
|
'customer_infos.customer_id',
|
|
'customer_infos.firstname',
|
|
'customer_infos.lastname',
|
|
'customer_infos.opt_in',
|
|
'customers.email',
|
|
'customer_infos.brand_id',
|
|
'customer_logins.last_connection'
|
|
)->where('lastname', 'like', '%' . $texte . '%')
|
|
->orWhere('email', 'like', '%' . $texte . '%')->get();
|
|
}
|
|
|
|
return response()->json($customers);
|
|
}
|
|
|
|
public function delete(Customer $customer, Brand $brand)
|
|
{
|
|
$nbBrand = $customer->infos()->count();
|
|
|
|
$customer->infos()->where('brand_id', $brand->id)->delete();
|
|
$customer->logins()->where('brand_id', $brand->id)->delete();
|
|
$customer->optInHistory()->where('brand_id', $brand->id)->delete();
|
|
|
|
if ($nbBrand === 1) {
|
|
$customer->delete();
|
|
}
|
|
|
|
return redirect()->route('customers.index')->with('success', "Compte supprimé.");
|
|
}
|
|
|
|
public function export()
|
|
{
|
|
// use a crud controller (any) to gather crudModels
|
|
$modelsClasses = (new BrandController())->getCrudModels();
|
|
return view('customer.export', compact(
|
|
'modelsClasses'
|
|
));
|
|
}
|
|
|
|
public function exportSubmit(CustomerExport $request)
|
|
{
|
|
$pagination = 2000;
|
|
$header = '"lastname";"firstname";"email";"hashcode"';
|
|
|
|
$w = Writer::createFromString($header . PHP_EOL);
|
|
$w->setDelimiter(';');
|
|
$w->setEnclosure('"');
|
|
$w->setOutputBOM(Writer::BOM_UTF8);
|
|
|
|
$exportType = CustomerExportType::make(\intval($request->export_type));
|
|
|
|
//We send the CSV using Symfony StreamedResponse
|
|
$response = new StreamedResponse();
|
|
$response->headers->set('Content-Encoding', 'none');
|
|
$response->headers->set('Content-Type', 'text/csv; charset=UTF-8');
|
|
$response->headers->set('Description', 'File Transfer');
|
|
$response->headers->set(
|
|
'Content-Disposition',
|
|
sprintf(
|
|
'attachment; filename=\"Export pour newsletter %s %s.csv\"',
|
|
Carbon::now()->format('d-m-Y_H-i'),
|
|
Str::slug($exportType)
|
|
)
|
|
);
|
|
|
|
switch ($exportType) {
|
|
case CustomerExportType::both():
|
|
$continue = true;
|
|
// continue
|
|
case CustomerExportType::customer():
|
|
$i = 0;
|
|
/** @var \Illuminate\Database\Eloquent\Builder $req */
|
|
$req = CustomerInfo::where('brand_id', $request->brand);
|
|
$total = $req->count();
|
|
$pages = $total / $pagination;
|
|
do {
|
|
/** @var \Illuminate\Pagination\LengthAwarePaginator $items */
|
|
$items = $req->with('customer', function ($q) {
|
|
$q->select(['id', 'email']);
|
|
})->paginate(
|
|
$pagination,
|
|
['lastname', 'firstname', 'hashcode', 'customer_id'],
|
|
'page',
|
|
$i
|
|
);
|
|
$items->map(function (CustomerInfo $customerInfo) use ($w) {
|
|
$w->insertOne([
|
|
'lastname' => $customerInfo->lastname,
|
|
'firstname' => $customerInfo->firstname,
|
|
'email' => $customerInfo->customer->email,
|
|
'hashcode' => $customerInfo->hashcode
|
|
]);
|
|
});
|
|
} while ($i++ <= $pages);
|
|
if (!isset($continue)) {
|
|
break;
|
|
}
|
|
// continue
|
|
case CustomerExportType::singleOptin():
|
|
SingleOptin::where('brand_id', $request->brand)->get()
|
|
->map(function (SingleOptin $singleOptin) use ($w) {
|
|
$w->insertOne([
|
|
'lastname' => '',
|
|
'firstname' => '',
|
|
'email' => $singleOptin->email,
|
|
'hashcode' => ''
|
|
]);
|
|
});
|
|
break;
|
|
}
|
|
|
|
//we create a callable to output the CSV in chunk
|
|
//with Symfony StreamResponse you can flush the body content if necessary
|
|
//see Symfony documentation for more information
|
|
$flush_threshold = 1000; //the flush value should depend on your CSV size.
|
|
$response->setCallback(function () use ($w, $flush_threshold) {
|
|
foreach ($w->chunk(1024) as $offset => $chunk) {
|
|
echo $chunk;
|
|
if ($offset % $flush_threshold === 0) {
|
|
flush();
|
|
}
|
|
}
|
|
});
|
|
return $response;
|
|
}
|
|
}
|