From d399a8321a5821511ab4f3911009262d223cdfe5 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Thu, 11 Apr 2024 19:33:29 -0300 Subject: [PATCH 01/12] csv data validation for bulk add user fix #85 --- app/Http/Controllers/TurmaController.php | 20 ++++-- app/Rules/CsvRule.php | 91 ++++++++++++++++++++++++ app/Utils/Csv.php | 34 +++++++++ resources/views/exercicio/show.blade.php | 2 + 4 files changed, 140 insertions(+), 7 deletions(-) create mode 100644 app/Rules/CsvRule.php create mode 100644 app/Utils/Csv.php diff --git a/app/Http/Controllers/TurmaController.php b/app/Http/Controllers/TurmaController.php index 002a436..3ed8bc2 100644 --- a/app/Http/Controllers/TurmaController.php +++ b/app/Http/Controllers/TurmaController.php @@ -9,7 +9,7 @@ use App\Models\User; use App\Models\Exercicio; use App\Models\Prazo; -use App\Rules\Emails; +use App\Rules\CsvRule; class TurmaController extends Controller { @@ -154,12 +154,18 @@ public function updateprazos(Request $request, Turma $turma) public function update(Request $request, Turma $turma) { $this->authorize('edit',$turma); - $rules = array( - 'name' => 'required', - 'description'=> 'required', - 'maillist' => [new Emails], - 'defaultpassword' => 'required_with:maillist' - ); + $rules = [ + 'name' => 'required', + 'description'=> 'required', + 'maillist' => [ + 'file', + new CsvRule([ + 'name' => 'required', + 'email' => 'required|email' + ]) + ], + 'defaultpassword' => 'required_with:maillist' + ]; $data = $request->validate($rules); $turma->update(['name' => $data['name'],'description' => $data['description']]); diff --git a/app/Rules/CsvRule.php b/app/Rules/CsvRule.php new file mode 100644 index 0000000..39c1f99 --- /dev/null +++ b/app/Rules/CsvRule.php @@ -0,0 +1,91 @@ +rules = $rules; + $this->colNames = array_keys($this->rules); + } + + /** + * Determine if the validation rule passes. + * + * @param string $attribute + * @param mixed $value + * @return bool + */ + public function passes($attribute, $value) + { + $result = false; + $request = request(); + + if($request->hasFile($attribute)) { + + $errors = []; + + // Get data + $csv = new Csv($request->file($attribute)->get()); + $csv_data = $csv->getData(); + + foreach($csv_data as $row_index => $row_data) { + + $validator = \Validator::make( + $row_data, + $this->rules + ); + + if($validator->fails()) { + + $line_errors = $validator->errors()->toArray(); + + foreach($line_errors as $error_index => $line_error) { + + // Add line information on error message + $errors[] = "Line ".($row_index+2).": ".$line_error[0]; + + } + + } + + } + + $this->error_messages = $errors; + + if(empty($errors)) { + + $result = true; + + } + + } + + return $result; + } + + /** + * Get the validation error messages. + * + * @return array + */ + public function message() + { + return $this->error_messages; + } +} diff --git a/app/Utils/Csv.php b/app/Utils/Csv.php new file mode 100644 index 0000000..ab37687 --- /dev/null +++ b/app/Utils/Csv.php @@ -0,0 +1,34 @@ +columnsNames = array_map('trim', array_shift($rows)); + + foreach ($rows as $row) { + $row = array_map('trim', $row); + if( sizeof($row) == sizeof($this->columnsNames) ) { + $associatedRowData = array_combine($this->columnsNames, $row); + if (empty($keyField)) { + $this->data[] = $associatedRowData; + } else { + $this->data[$associatedRowData[$keyField]] = $associatedRowData; + } + } + } + } + + public function getColumnNames(): array { + return $this->columnsNames; + } + + public function getData(): array { + return $this->data; + } +} \ No newline at end of file diff --git a/resources/views/exercicio/show.blade.php b/resources/views/exercicio/show.blade.php index 852cbdd..95ce069 100644 --- a/resources/views/exercicio/show.blade.php +++ b/resources/views/exercicio/show.blade.php @@ -50,6 +50,8 @@
{{ $message }}
@enderror + +
From b3e207d65910225ea4afe29f01aee419b8c1e5d2 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Thu, 11 Apr 2024 19:33:51 -0300 Subject: [PATCH 02/12] form for turma bulk add user #85 --- resources/views/turma/edit.blade.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/views/turma/edit.blade.php b/resources/views/turma/edit.blade.php index efc5a3c..86ca62f 100644 --- a/resources/views/turma/edit.blade.php +++ b/resources/views/turma/edit.blade.php @@ -6,7 +6,7 @@

Editando {{ $turma->name }}

- id)}} method="POST"> + id)}} method="POST" enctype="multipart/form-data"> @csrf @method('PUT') @include ('includes.error_alert') @@ -25,8 +25,8 @@ @enderror
- - + + {{ old('maillist','') }} @error('maillist')
{{ $message }}
@enderror From d939881f399fe32477199a8b83fae951c1ef039c Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Fri, 12 Apr 2024 14:47:07 -0300 Subject: [PATCH 03/12] bulk add user working --- app/Http/Controllers/TurmaController.php | 15 ++++++++++----- resources/views/turma/show.blade.php | 24 ++++++++++++------------ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/app/Http/Controllers/TurmaController.php b/app/Http/Controllers/TurmaController.php index 3ed8bc2..acfc1cc 100644 --- a/app/Http/Controllers/TurmaController.php +++ b/app/Http/Controllers/TurmaController.php @@ -10,6 +10,7 @@ use App\Models\Exercicio; use App\Models\Prazo; use App\Rules\CsvRule; +use App\Utils\Csv; class TurmaController extends Controller { @@ -171,10 +172,12 @@ public function update(Request $request, Turma $turma) // bulk add users if ($request->maillist ?? "") { - $emails = array_map('trim', explode("\n", $request->maillist)); //$value + $csv = new Csv($request->maillist->get()); $pssw = $request->defaultpassword; - foreach( $emails as $email ) { - $newmember = User::where('email',$email)->first(); + foreach( $csv->getData() as $user ) { + $email = $user['email']; + $name = $user['name']; + $newmember = User::where('email', $email)->first(); if($newmember) { // if user not in turma, add if ($turma->users()->find($newmember) == null) { @@ -182,8 +185,10 @@ public function update(Request $request, Turma $turma) } } else { // if user doesn't exist, create new - $newmember = User::create(['email' => $email]); - $newmember->password = $pssw; + $newmember = User::create([ + 'email' => $email, + 'name' => $name, + 'password' => $pssw]); $turma->users()->save($newmember); } } diff --git a/resources/views/turma/show.blade.php b/resources/views/turma/show.blade.php index 4578b59..050a1d0 100644 --- a/resources/views/turma/show.blade.php +++ b/resources/views/turma/show.blade.php @@ -30,19 +30,19 @@
@endif - @can ('edit', $turma) - Editar - Alterar prazos - @endcan - @can ('delete', $turma) - id)}}"> - {{ csrf_field() }} - {{ method_field('DELETE') }} +
+ @can ('edit', $turma) + Editar + Alterar prazos + @endcan + @can ('delete', $turma) + id)}}"> + {{ csrf_field() }} + {{ method_field('DELETE') }} -
-
- - @endcan + + @endcan +
@endsection From 412c76b388a31abfeeeae6ec735fcef3222739d5 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 15 May 2024 13:55:39 -0300 Subject: [PATCH 04/12] remove dummy code --- resources/views/exercicio/show.blade.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/resources/views/exercicio/show.blade.php b/resources/views/exercicio/show.blade.php index 95ce069..c2ec7ff 100644 --- a/resources/views/exercicio/show.blade.php +++ b/resources/views/exercicio/show.blade.php @@ -49,9 +49,6 @@ @error('file')
{{ $message }}
@enderror - - -
From 00335da2db8e1da656c17df3a4ec6e4b9bb4f97f Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 15 May 2024 14:01:13 -0300 Subject: [PATCH 05/12] trying to edit gitignore --- storage/app/public/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/storage/app/public/.gitignore b/storage/app/public/.gitignore index d6b7ef3..6ea5f3f 100644 --- a/storage/app/public/.gitignore +++ b/storage/app/public/.gitignore @@ -1,2 +1,3 @@ -* +arquivos/ +!examples/ !.gitignore From c5960ab9ed93c1cee718fc0b72ed8370c9af81d9 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 15 May 2024 14:05:56 -0300 Subject: [PATCH 06/12] example files --- .../app/public/examples/bulk_add_users.csv | 4 +++ storage/app/public/examples/exercicio.yaml | 32 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 storage/app/public/examples/bulk_add_users.csv create mode 100644 storage/app/public/examples/exercicio.yaml diff --git a/storage/app/public/examples/bulk_add_users.csv b/storage/app/public/examples/bulk_add_users.csv new file mode 100644 index 0000000..7701e67 --- /dev/null +++ b/storage/app/public/examples/bulk_add_users.csv @@ -0,0 +1,4 @@ +name,email +Fulano de Tal, fdetal@example.com +Cicrana de Tal, cdetal@example.com +Zé da Silva, zedasilva@example.com \ No newline at end of file diff --git a/storage/app/public/examples/exercicio.yaml b/storage/app/public/examples/exercicio.yaml new file mode 100644 index 0000000..f84f79f --- /dev/null +++ b/storage/app/public/examples/exercicio.yaml @@ -0,0 +1,32 @@ +name: '101.00 Bem-vindo(a) ao notaR' +description: |- +

Olá! Este deve ser o primeiro exercício que você resolve no notaR, e ele serve para você ganhar familiaridade com o conceito de um corretor automático e com o funcionamento deste sistema.

+

O notaR funciona executando o script (código) que você envia e verificando se esse script cumpre os requisitos do exercício. Nós não estamos verificando quais são os comandos que você escreve, e sim qual é o resultado, já que existem várias maneiras de resolver os mesmos problemas.

+

Para pegar um gostinho de como o sistema funciona, nesse exercício você precisa criar 2 objetos. O primeiro deles é um vetor da classe "character" chamado carambola, contendo os elementos "abacaxi" e "beterraba".

+

Para isso, crie um arquivo no seu computador contendo o comando: +
+ +  carambola <- c("abacaxi", "beterraba") + +

Salve esse arquivo e envie para o corretor usando a caixinha abaixo.

+

Feito? Você deve ter recebido uma mensagem indicando que seu aproveitamento foi de 50% até agora, e dando uma dica de como melhorar! O próximo passo é criar um objeto chamado salada, contendo "beringela" e "batata". Acrescente no seu script a seguinte linha (perceba que ela tem errinhos de digitação):
+ + salada <- c("berinjuela", "babata") + + +

Envie para o corretor e veja qual é a mensagem de ajuda agora! Corrija a digitação e envie de novo para receber a nota máxima!

+

Por fim, às vezes cometemos erros e o código não executa. Tente enviar um arquivo com a seguinte linha (onde faltam os (parênteses)) para ver o que acontece. +
+ + salada <- c"beringela", "batata" + +
+

Se você receber essa mensagem nos próximos exercícios, não se desespere! Clique no linque de ajuda que fica abaixo de todos os enunciados para ver dicas de como descobrir o que está errado!

+precondicoes: '' +testes: + - { condicao: 'exists("carambola")', dica: 'Não existe um objeto chamado carambola. Você selecionou o arquivo correto?', peso: 1.0 } + - { condicao: 'class(carambola)=="character"', dica: 'O objeto carambola deveria ser da classe character', peso: 1.0 } + - { condicao: 'identical(carambola, c("abacaxi", "beterraba"))', dica: 'O conteúdo do objeto carambola está incorreto. Você digitou corretamente?', peso: 1.0 } + - { condicao: 'exists("salada")', dica: 'Não existe um objeto chamado salada', peso: 1.0 } + - { condicao: 'class(salada)=="character"', dica: 'O objeto salada deveria ser da classe character', peso: 1.0 } + - { condicao: 'identical(salada, c("beringela", "batata"))', dica: 'O conteúdo do objeto salada está incorreto. Você digitou corretamente?', peso: 1.0 } From 59c1c7261e6c49dabd1cec571d025bee19799f77 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 15 May 2024 14:06:50 -0300 Subject: [PATCH 07/12] adding volume for example files --- docker-compose.yml | 1 + storage/app/.gitignore | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 82a5822..c24e46d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,6 +16,7 @@ services: volumes: - '.:/var/www/html' - './storage/app/temp:/temp' + - './storage/app/public/examples:/examples' networks: - sail depends_on: diff --git a/storage/app/.gitignore b/storage/app/.gitignore index 8f4803c..2099b16 100644 --- a/storage/app/.gitignore +++ b/storage/app/.gitignore @@ -1,3 +1,2 @@ -* -!public/ +temp/ !.gitignore From b3b82ff18823b398e3dcb0897fa896ab5581030d Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 15 May 2024 14:15:54 -0300 Subject: [PATCH 08/12] prettier example code --- storage/app/public/examples/exercicio.yaml | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/storage/app/public/examples/exercicio.yaml b/storage/app/public/examples/exercicio.yaml index f84f79f..0819580 100644 --- a/storage/app/public/examples/exercicio.yaml +++ b/storage/app/public/examples/exercicio.yaml @@ -1,27 +1,27 @@ name: '101.00 Bem-vindo(a) ao notaR' description: |- -

Olá! Este deve ser o primeiro exercício que você resolve no notaR, e ele serve para você ganhar familiaridade com o conceito de um corretor automático e com o funcionamento deste sistema.

-

O notaR funciona executando o script (código) que você envia e verificando se esse script cumpre os requisitos do exercício. Nós não estamos verificando quais são os comandos que você escreve, e sim qual é o resultado, já que existem várias maneiras de resolver os mesmos problemas.

-

Para pegar um gostinho de como o sistema funciona, nesse exercício você precisa criar 2 objetos. O primeiro deles é um vetor da classe "character" chamado carambola, contendo os elementos "abacaxi" e "beterraba".

-

Para isso, crie um arquivo no seu computador contendo o comando: -
+ Olá! Este deve ser o primeiro exercício que você resolve no notaR, e ele serve para você ganhar familiaridade com o conceito de um corretor automático e com o funcionamento deste sistema. + + O notaR funciona executando o script (código) que você envia e verificando se esse script cumpre os requisitos do exercício. Nós não estamos verificando quais são os comandos que você escreve, e sim qual é o resultado, já que existem várias maneiras de resolver os mesmos problemas. + + Para pegar um gostinho de como o sistema funciona, nesse exercício você precisa criar 2 objetos. O primeiro deles é um vetor da classe "character" chamado carambola, contendo os elementos "abacaxi" e "beterraba". + Para isso, crie um arquivo no seu computador contendo o comando:  carambola <- c("abacaxi", "beterraba") -

Salve esse arquivo e envie para o corretor usando a caixinha abaixo.

-

Feito? Você deve ter recebido uma mensagem indicando que seu aproveitamento foi de 50% até agora, e dando uma dica de como melhorar! O próximo passo é criar um objeto chamado salada, contendo "beringela" e "batata". Acrescente no seu script a seguinte linha (perceba que ela tem errinhos de digitação):
+ Salve esse arquivo e envie para o corretor usando a caixinha abaixo. + + Feito? Você deve ter recebido uma mensagem indicando que seu aproveitamento foi de 50% até agora, e dando uma dica de como melhorar! O próximo passo é criar um objeto chamado salada, contendo "beringela" e "batata". Acrescente no seu script a seguinte linha (perceba que ela tem errinhos de digitação): salada <- c("berinjuela", "babata") + Envie para o corretor e veja qual é a mensagem de ajuda agora! Corrija a digitação e envie de novo para receber a nota máxima! -

Envie para o corretor e veja qual é a mensagem de ajuda agora! Corrija a digitação e envie de novo para receber a nota máxima!

-

Por fim, às vezes cometemos erros e o código não executa. Tente enviar um arquivo com a seguinte linha (onde faltam os (parênteses)) para ver o que acontece. -
+ Por fim, às vezes cometemos erros e o código não executa. Tente enviar um arquivo com a seguinte linha (onde faltam os (parênteses)) para ver o que acontece. salada <- c"beringela", "batata" -
-

Se você receber essa mensagem nos próximos exercícios, não se desespere! Clique no linque de ajuda que fica abaixo de todos os enunciados para ver dicas de como descobrir o que está errado!

+ Se você receber essa mensagem nos próximos exercícios, não se desespere! Clique no linque de ajuda que fica abaixo de todos os enunciados para ver dicas de como descobrir o que está errado! precondicoes: '' testes: - { condicao: 'exists("carambola")', dica: 'Não existe um objeto chamado carambola. Você selecionou o arquivo correto?', peso: 1.0 } From 5ca537ba73918688ba7f9ab8db963779f447caeb Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 15 May 2024 14:23:07 -0300 Subject: [PATCH 09/12] example now has preconds --- storage/app/public/examples/exercicio.yaml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/storage/app/public/examples/exercicio.yaml b/storage/app/public/examples/exercicio.yaml index 0819580..570e174 100644 --- a/storage/app/public/examples/exercicio.yaml +++ b/storage/app/public/examples/exercicio.yaml @@ -22,11 +22,13 @@ description: |- salada <- c"beringela", "batata" Se você receber essa mensagem nos próximos exercícios, não se desespere! Clique no linque de ajuda que fica abaixo de todos os enunciados para ver dicas de como descobrir o que está errado! -precondicoes: '' +precondicoes: |- + my_carambola <- c("abacaxi", "beterraba") + my_salada <- c("beringela", "batata") testes: - { condicao: 'exists("carambola")', dica: 'Não existe um objeto chamado carambola. Você selecionou o arquivo correto?', peso: 1.0 } - { condicao: 'class(carambola)=="character"', dica: 'O objeto carambola deveria ser da classe character', peso: 1.0 } - - { condicao: 'identical(carambola, c("abacaxi", "beterraba"))', dica: 'O conteúdo do objeto carambola está incorreto. Você digitou corretamente?', peso: 1.0 } + - { condicao: 'identical(carambola, my_carambola)', dica: 'O conteúdo do objeto carambola está incorreto. Você digitou corretamente?', peso: 1.0 } - { condicao: 'exists("salada")', dica: 'Não existe um objeto chamado salada', peso: 1.0 } - { condicao: 'class(salada)=="character"', dica: 'O objeto salada deveria ser da classe character', peso: 1.0 } - - { condicao: 'identical(salada, c("beringela", "batata"))', dica: 'O conteúdo do objeto salada está incorreto. Você digitou corretamente?', peso: 1.0 } + - { condicao: 'identical(salada, my_salada)', dica: 'O conteúdo do objeto salada está incorreto. Você digitou corretamente?', peso: 1.0 } From e2d5afe9801c2430f32ec095c02734139dcfe43d Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 15 May 2024 14:54:50 -0300 Subject: [PATCH 10/12] added link to example file --- resources/views/turma/edit.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/turma/edit.blade.php b/resources/views/turma/edit.blade.php index 86ca62f..b792e2f 100644 --- a/resources/views/turma/edit.blade.php +++ b/resources/views/turma/edit.blade.php @@ -25,7 +25,7 @@ @enderror
- + {{ old('maillist','') }} @error('maillist')
{{ $message }}
From 6f2d0f9f0264b7410d00a504858f030020cea106 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 15 May 2024 14:58:56 -0300 Subject: [PATCH 11/12] cleanup --- app/Rules/CsvRule.php | 8 ------- app/Rules/Emails.php | 56 ------------------------------------------- 2 files changed, 64 deletions(-) delete mode 100755 app/Rules/Emails.php diff --git a/app/Rules/CsvRule.php b/app/Rules/CsvRule.php index 39c1f99..7ebe690 100644 --- a/app/Rules/CsvRule.php +++ b/app/Rules/CsvRule.php @@ -54,28 +54,20 @@ public function passes($attribute, $value) if($validator->fails()) { $line_errors = $validator->errors()->toArray(); - foreach($line_errors as $error_index => $line_error) { - // Add line information on error message $errors[] = "Line ".($row_index+2).": ".$line_error[0]; - } - } - } $this->error_messages = $errors; if(empty($errors)) { - $result = true; - } } - return $result; } diff --git a/app/Rules/Emails.php b/app/Rules/Emails.php deleted file mode 100755 index b70d901..0000000 --- a/app/Rules/Emails.php +++ /dev/null @@ -1,56 +0,0 @@ - 'required|email', - ]; - $emails = array_map('trim', explode("\n", $value)); //$value - foreach ($emails as $email) { - $data = [ - 'email' => $email - ]; - $validator = Validator::make($data, $rules); - if ($validator->fails()) { - return false; - } - } - return true; - } - - /** - * Get the validation error message. - * - * @return string - */ - public function message() - { - return 'Um ou mais e-mails inválidos.'; - } -} From 0fd543a5e5f9b52cbe00986488bcec07e094dea0 Mon Sep 17 00:00:00 2001 From: Mali Oz Date: Wed, 15 May 2024 18:13:12 -0300 Subject: [PATCH 12/12] remove unnecessary volume --- docker-compose.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index c24e46d..82a5822 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,7 +16,6 @@ services: volumes: - '.:/var/www/html' - './storage/app/temp:/temp' - - './storage/app/public/examples:/examples' networks: - sail depends_on: