-
Notifications
You must be signed in to change notification settings - Fork 140
Create comand #1799
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Create comand #1799
Conversation
|
@GreedVal привет, как успехи, нужна помощь? |
Привет, у меня в целом на работе завал после командировки, и если уже за эту неделю не смогу разгребсти это все то возможно уйду с проэкта чтобы не мешаться, а то под конец года времени перестало на все хватать |
|
@GreedVal ЭЭэххх(((( Грустненько. А тут по задачке в целом получилось продвинуться, или все в зародыше? Можешь оставить пометки-заметки в задача-ишшусе, чтобы кто-то следующий мог взять в работу? |
@fey Я вроде разгреб, долги на работе вчера сделал пул риквест по багу в регистрации, сегодня займусь выгрузкой, так что вроде в строю) |
|
Сделал сервис для выгрузки таблиц в csv файлы, запускается через artisan command |
|
@GreedVal можешь показать пример того, что выгрузится? Еще тестов не хватает. |
|
пример выгрузки id,name,email,github_name,hexlet_nickname,points,created_at я думал вообще сделать выгрузку через админку кнопкой, про тесты забыл сделаю |
| 'type' => 'required|string', | ||
| ]); | ||
|
|
||
| $directory = 'exports/' . now()->format('Y-m-d_H-i-s'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
формирование пути к директории экспорта получается разделилось на несколько частей. используй массив + склейку слешем для создания пути к директории
app/Services/AnalyticsExporter.php
Outdated
|
|
||
| foreach ($collection as $item) { | ||
| $quoted = array_map( | ||
| static fn($value): string => '"' . str_replace('"', '""', (string) $value) . '"', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тут стоит поправить, (здесь и далее). Вообще лучше использовать готовое решение для работы с CSV
| use App\Models\Chapter; | ||
| use Illuminate\Database\Eloquent\Factories\Factory; | ||
|
|
||
| class ChapterFactory extends Factory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Хм, а у нас ведь нет особо необходимости в генерации глав и упражнений. Они ведь есть в коде. Они не подходят?
routes/web.php
Outdated
| Route::resource('solutions', 'SolutionController')->only('index'); | ||
|
|
||
| Route::get('export', 'ExportController@index')->name('export.index'); | ||
| Route::post('export', 'ExportController@export')->name('export'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
давай использовать ресурсный роутинг.
app/Services/AnalyticsExporter.php
Outdated
| Storage::makeDirectory($directory); | ||
|
|
||
| switch ($type) { | ||
| case 'users': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
здесь мы выбираем не тип, а имя таблицы, которую будем экспортировать, или имя сущности. плюсом вместо строки- лучше использовать enum/константы или что-то такое. Например даже имя класса подойдет.
| $this->assertStringContainsString((string)$user->id, $content); | ||
|
|
||
| unlink($filePath); | ||
| rmdir($latestFolder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
вот это можно вынести в tear down метод (очистку)
| rsort($folders); | ||
| $latestFolder = $folders[0]; | ||
|
|
||
| $filePath = $latestFolder . '/users.csv'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
снова конкатенация.
С путями самый удобный и простой способ - этомассив + join, или интерполяция.
Кстати тут советую подумать над тем, как можно не искать директорию, как ты делаешь. Например в экспортер можно передавать директорию, куда он будет сохранять, можно замораживать время в тестах (тк у тебя директория зависит от текущего времени)
app/Services/AnalyticsExporter.php
Outdated
| $this->exportComments("{$directory}/comments.csv"); | ||
| break; | ||
| case 'activity': | ||
| $this->exportActivityLog("{$directory}/activity.csv"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
как будто бы можно не передавать каждый раз директорию, а записать ее в свойство класса, и брать ее при сохранении. Т.е. у тебя экспортер будет иметь настройку, куда он может экспортировать данные.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ну и можно тут обобщить, сделать массив, где ключ - это то что щас в кейсе, и использовать анонимные функции для экспорта. ну, такой продвинутый вариант.
|
|
||
| $this->exporter->export($directory, $request->type); | ||
|
|
||
| $fileName = "{$request->type}.csv"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
несклько обращений к request->type - можно выделить в переменную.
|
|
||
| $fileName = "{$request->type}.csv"; | ||
| $filePath = storage_path("app/{$directory}/{$fileName}"); | ||
| $filePath = storage_path(implode('/', ['app', $directory, $fileName])); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Давай тут в методе нейминг поправим, потому что, щас у тебя есть некая directory - и непонятно, за что она отвечает, потому что в нее проихсодит экспорт на 38 строке, а потом внезапно на 41 создается новый путь, но уже storage/app - выглядит запутано.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Да, я уже думая что у меня совсем логика запутана так как и в сервисе и в контролере отдельно создается путь к сохраненному файлу из за чего неразбериха, наверное правильно будет чтобы сервис возвращал путь к фалу а в контролере я просто его использовал. Так меньше шансов не правильного поведения контролера.
Так в контролер вообще не будет участвовать в формировании пути
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
По фабрикам ChapterFactory.php создавал для тестов но сейчас думаю а зачем аналитикам вообще их выгружать, возможно стоит убрать их в export, а потом если нужно будет добавить
Now the path is created in the service and the controller accepts the already prepared path to the file
| ); | ||
|
|
||
| $csv->setDelimiter(','); | ||
| $csv->setNewline("\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тут все еще самописная работа с csv. Давай возьмем готовое решение, вот к примеру. https://github.com/thephpleague/csv
| 'activity' => 'export/activity.csv', | ||
| ]; | ||
|
|
||
| foreach ($types as $type => $path) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тут подойддет data provider
| } | ||
| } | ||
|
|
||
| public function testUsersCsvContainsCorrectHeadersAndRow(): void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
не думмаю, что имеет смысл отедльно тестировать только для юзеров это.
Смотри, у тебя ведь общая логика для экспорта одна, везде создаются заголовки.
Просто создай фикстуру, и с ней сравнивай результат экспорта. Ну и дата провайдер тебе в этом плане поломожет организовать тест.
|
@GreedVal осмотри по тестам как там работа с activity происходит. Они вроде как генерируются через што-то, чтобы данные консистентные были, т.е. если у юзер должен оставить коммент (перед тестами), то и есть нужная "активность". |

Data export from the database for analytics has been implemented via the admin panel. Data is downloaded as a CSV file.