Skip to content

Instantly share code, notes, and snippets.

@andrey-helldar
Last active January 23, 2020 14:10
Show Gist options
  • Save andrey-helldar/83faf8a6ebe198811b70fc0584282481 to your computer and use it in GitHub Desktop.
Save andrey-helldar/83faf8a6ebe198811b70fc0584282481 to your computer and use it in GitHub Desktop.
Parseable Example
<?php
namespace App\Contracts;
interface ParseableContract
{
public function parse(): array;
}
<?php
namespace App\Drivers\Parsers;
class CsvParser extends Parser
{
protected $divider = ';';
public function parse(): array
{
return array_map(function ($column) {
return str_getcsv($column, $this->divider);
}, $this->file);
}
}
<?php
namespace App\Drivers\Parsers;
use Illuminate\Container\Container;
class ExcelParser extends Parser
{
protected $excel;
protected $divider = ';';
protected $partner_shop_id;
public function __construct()
{
parent::__construct();
$this->excel();
}
public function partnerId($excel, $partner_shop_id): self
{
$this->partner_shop_id = $partner_shop_id;
return $this;
}
public function parse(): array
{
return $this->excel->getParsedRows($this->file);
}
protected function excel()
{
$this->excel = $this->normalizeExcel();
$this->excel->setPartnerShopId($this->partner_shop_id);
$this->excel->setDelimiter($this->divider);
}
protected function normalizeExcel()
{
return Container::getInstance()
->make(ParseFileInterface::class);
}
}
<?php
namespace App\Drivers\Parsers;
use App\Contracts\ParseableContract;
use Illuminate\Http\File;
abstract class Parser implements ParseableContract
{
protected $file;
public function __construct(File $file)
{
$this->file = $file;
}
}
<?php
namespace App\Exceptions;
use Exception;
class SueshDichException extends Exception
{
public function __construct()
{
parent::__construct('Ti suesh mne kakuyu-to dich', 500);
}
}
<?php
namespace App\Http\Controllers;
use App\Services\YourServiceFromConfigPreset;
use App\Services\YourServiceFromUser;
use Illuminate\Container\Container;
use Illuminate\Http\Request;
class ImportController extends Controller
{
public function storeFromUserChoice(Request $request)
{
return $this->service(YourServiceFromUser::class)
->store($request);
}
public function storeFromConfigPreset(Request $request)
{
return $this->service(YourServiceFromConfigPreset::class)
->store($request);
}
protected function service(string $service)
{
return Container::getInstance()
->make($service);
}
}
<?php
namespace App\Services;
use App\Contracts\ParseableContract;
use App\Drivers\Parsers\CsvParser;
use App\Drivers\Parsers\ExcelParser;
use App\Exceptions\SueshDichException;
use Illuminate\Container\Container;
use Illuminate\Http\File;
use Illuminate\Http\Request;
class YourServiceFromConfigPreset
{
/**
* Метод когда выбор адаптера зависит от настроек приложения.
*
* @param \Illuminate\Http\Request $request
*
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function store(Request $request)
{
$parser = $this->normalizeParser(
$request->file('csv_file')
);
if (method_exists($parser, 'partnerId')) {
$parser->partnerId($request->get('partner_shop_id'));
}
dd($parser->parse());
}
/**
* В конфиге должен быть указан массив с возможными парсерами, например:
*
* // config/services.php
* [
* 'import-catalog' => 'excel',
*
* 'parsers' => [
* 'csv' => \App\Drivers\Parsers\CsvParser::class,
* 'excel' => \App\Drivers\Parsers\ExcelParser::class,
* ]
* ]
*
* @param string $parser
* @param \Illuminate\Http\File $file
*
* @return \App\Contracts\ParseableContract
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
protected function normalizeParser(File $file): ParseableContract
{
$type = config('services.import-catalog', 'excel');
$parser = config('services.parsers.' . $type);
if (! $parser || ! is_subclass_of(ParseableContract::class, $parser)) {
throw new SueshDichException();
}
return Container::getInstance()
->make($parser, compact('file'));
}
}
<?php
namespace App\Services;
use App\Contracts\ParseableContract;
use App\Drivers\Parsers\CsvParser;
use App\Drivers\Parsers\ExcelParser;
use App\Exceptions\SueshDichException;
use Illuminate\Container\Container;
use Illuminate\Http\File;
use Illuminate\Http\Request;
class YourServiceFromUser
{
/**
* Метод когда выбор адаптера зависит от входящих данных.
*
* @return mixed
*/
public function store(Request $request)
{
$file = $request->file('csv_file');
$partner_shop_id = $request->get('partner_shop_id');
$parser = $request->has('header')
? $this->normalizeParser(ExcelParser::class, $file)->partnerId($partner_shop_id)
: $this->normalizeParser(CsvParser::class, $file);
dd($parser->parse());
}
protected function normalizeParser(string $parser, File $file): ParseableContract
{
if (! is_subclass_of(ParseableContract::class, $parser)) {
throw new SueshDichException();
}
return Container::getInstance()
->make($parser, compact('file'));
}
}
@andrey-helldar
Copy link
Author

Привел пример максимально близко к ситуации из сообщения https://t.me/laravel_web/174671 в канале телеги:

photo_2020-01-23_15-08-22

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment