diff --git a/app/Http/Controllers/TurmaController.php b/app/Http/Controllers/TurmaController.php index 002a436..acfc1cc 100644 --- a/app/Http/Controllers/TurmaController.php +++ b/app/Http/Controllers/TurmaController.php @@ -9,7 +9,8 @@ use App\Models\User; use App\Models\Exercicio; use App\Models\Prazo; -use App\Rules\Emails; +use App\Rules\CsvRule; +use App\Utils\Csv; class TurmaController extends Controller { @@ -154,21 +155,29 @@ 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']]); // 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) { @@ -176,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/app/Rules/CsvRule.php b/app/Rules/CsvRule.php new file mode 100644 index 0000000..7ebe690 --- /dev/null +++ b/app/Rules/CsvRule.php @@ -0,0 +1,83 @@ +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/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.'; - } -} 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..c2ec7ff 100644 --- a/resources/views/exercicio/show.blade.php +++ b/resources/views/exercicio/show.blade.php @@ -49,7 +49,6 @@ @error('file')
{{ $message }}
@enderror -
diff --git a/resources/views/turma/edit.blade.php b/resources/views/turma/edit.blade.php index efc5a3c..b792e2f 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 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 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 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 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..570e174 --- /dev/null +++ b/storage/app/public/examples/exercicio.yaml @@ -0,0 +1,34 @@ +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: |- + 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, 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, my_salada)', dica: 'O conteúdo do objeto salada está incorreto. Você digitou corretamente?', peso: 1.0 }