ldc-crm/app/Http/Controllers/CustomerController.php
Jérémy Munsch 193a93715e Newsletter export Function
- composer require league/csv
2021-09-09 16:08:42 +02:00

208 lines
7.9 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\Support\Carbon;
use Illuminate\Support\Str;
use League\Csv\Writer;
use Symfony\Component\HttpFoundation\StreamedResponse;
class CustomerController extends Controller
{
public function index()
{
$brands = Brand::select('id', 'name')->get();
$query = CustomerInfo::with(['customer']);
if (request()->brand) {
$query = $query->where('brand_id', request()->brand);
}
$customers = $query->paginate();
$modelTable = (new Customer())->getTable();
$modelClass = Customer::class;
// 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;
}
}