diff --git a/app/Http/Controllers/AutograderController.php b/app/Http/Controllers/AutograderController.php new file mode 100644 index 0000000000000000000000000000000000000000..b349bd6d9d349ce709e036a4aa4a78270bf6cff4 --- /dev/null +++ b/app/Http/Controllers/AutograderController.php @@ -0,0 +1,151 @@ +<?php + +namespace App\Http\Controllers; + +use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; +use Google_Client; + +class AutograderController extends Controller +{ + /** + * Create a new controller instance. + * + * @return void + */ + public function __construct() + { + $this->middleware('auth'); + } + + /** + * Submit Spreadsheet. + * + * @return Score + */ + public function index($id_course, $id_topic, Request $request) + { + $answer_keys = DB::table('spreadsheets')->where('id', $id_topic)->get(); + $cells = []; + $cells_temp = []; + $keys = []; + foreach($answer_keys as $answer_key) { + $cells[] = 'Sheet1!' . $answer_key->cell; + $cells_temp[] = $answer_key->cell; + $keys[] = $answer_key->value; + } + + $answers = AutograderController::getStudentAnswer($request->id_spreadsheet, $cells); + + $results = AutograderController::grade($keys, $answers); + + echo ' + <table class="table"> + <thead> + <tr> + <th scope="col">Cell</th> + <th scope="col">Kunci</th> + <th scope="col">Jawaban</th> + <th scope="col">Skor</th> + </tr> + </thead> + <tbody> + '; + for ($i=0; $i<count($results); $i++) { + echo '<tr>'; + echo '<th>' . $cells_temp[$i] . '</th>'; + echo '<td>' . $keys[$i] . '</td>'; + echo '<td>' . $answers[$i] . '</td>'; + echo '<td>' . $results[$i]*100 . '/100</td>'; + echo '</tr>'; + } + echo ' + </tbody> + </table> + <a href="/course/ ' . $id_course . '" style="float: right;" class="btn btn-primary" role="button">Kembali ke Kelas</a> + '; + } + + /** + * Get grade from answer. + * + * @return grades + */ + public function grade($keys, $answers) + { + $results = []; + for($i=0; $i<count($keys); $i++) { + $key_temp = preg_split("/[)\s,(-]+/", $keys[$i]); + $answer_temp = preg_split("/[)\s,(-]+/", $answers[$i]); + + $key = []; + for($j=0; $j<count($key_temp); $j++) { + if (!empty($key_temp[$j])) { + $key[] = $key_temp[$j]; + } + } + + $answer = []; + for($j=0; $j<count($answer_temp); $j++) { + if (!empty($answer_temp[$j])) { + $answer[] = $answer_temp[$j]; + } + } + + $results[] = AutograderController::jaccardIndex($key, $answer); + } + + return $results; + } + + /** + * Get Jaccard Index score. + * + * @return score + */ + public function jaccardIndex($key, $answer) { + $arr_intersection = count(array_intersect( $key, $answer )); + $arr_union = count(array_merge( $key, $answer )) - $arr_intersection; + $jaccard_index = $arr_intersection / $arr_union; + + return $jaccard_index; + } + + /** + * Get data from spreadsheet. + * + * @return answer + */ + public function getStudentAnswer($id_spreadsheet, $ranges) + { + $client = new Google_Client(); + $client->setApplicationName('Datalearn'); + $client->setAuthConfig(__DIR__.'/credentials.json'); + $client->addScope(\Google_Service_Sheets::SPREADSHEETS); + $client->setAccessType('offline'); + + $service = new \Google_Service_Sheets($client); + + $responses = $service->spreadsheets_values->batchGet($id_spreadsheet, [ + 'valueRenderOption' => 'FORMULA', + 'dateTimeRenderOption' => 'SERIAL_NUMBER', + 'ranges' => $ranges + ]); + + $answers = []; + foreach ($responses->valueRanges as $response) { + if ($response->values == NULL) { + $answers[] = NULL; + } else { + $answers[] = strtoupper(strval(($response->values)[0][0])); + } + } + + return $answers; + } + + public function test() + { + echo strtoupper("=sum(A1,A2)"); + } +} diff --git a/app/Http/Controllers/LearnController.php b/app/Http/Controllers/LearnController.php index 91a8b8b245de2b0a9f624e0168e36c77509a986b..9b81636331e3442d051a4c383d9c977664092f3f 100644 --- a/app/Http/Controllers/LearnController.php +++ b/app/Http/Controllers/LearnController.php @@ -23,18 +23,19 @@ class LearnController extends Controller * * @return \Illuminate\Contracts\Support\Renderable */ - public function index($id_course, $id_spreadsheet) + public function index($id_course, $id_topic) { + $topic = DB::table('topics')->where('id', $id_topic)->first(); + $content = $topic->content; + $client = LearnController::getClient(); $service = new \Google_Service_Drive($client); $copy = new \Google_Service_Drive_DriveFile(); - $response = $service->files->copy($id_spreadsheet, $copy); + $response = $service->files->copy($topic->id_spreadsheet, $copy); $permission_response = LearnController::edit_permission($response->id); - $topic = DB::table('topics')->where('id_spreadsheet', $id_spreadsheet)->first(); - $content = $topic->content; return view('learn', ['id_spreadsheet' => $response->id, 'content' => $content]); } @@ -96,10 +97,10 @@ class LearnController extends Controller * * @return view */ - public function edit($id_course, $id_spreadsheet) + public function edit($id_course, $id_topic) { - $topic = DB::table('topics')->where('id_spreadsheet', $id_spreadsheet)->first(); - return view('edit', ['id_spreadsheet' => $id_spreadsheet, 'topic' => $topic]); + $topic = DB::table('topics')->where('id', $id_topic)->first(); + return view('edit', ['id_spreadsheet' => $topic->id_spreadsheet, 'topic' => $topic]); } /** @@ -107,64 +108,55 @@ class LearnController extends Controller * * @return message */ - public function save(Request $request) + public function save($id_course, $id_topic, Request $request) { - echo $request->id_spreadsheet; - echo $request->myTextArea; - echo $request->richh; - DB::table('topics')->insert([ - 'id_course' => '2', - 'name' => 'ahaha', - 'content' => $request->richh, - 'id_spreadsheet' => $request->id_spreadsheet - ]); - } + $cells = []; + foreach ($request->cells as $cell) { + $cells[] = strtoupper($cell); + } - /** - * Submit Spreadsheet. - * - * @return Score - */ - public function submit(Request $request) - { - $id = $request->id_spreadsheet; $client = LearnController::getClient(); $service = new \Google_Service_Sheets($client); - - $ranges = []; - $ranges[] = 'Sheet1!A1'; - $ranges[] = 'Sheet1!A2'; - $ranges[] = 'Sheet1!A3'; + + // Get Answer $responses = $service->spreadsheets_values->batchGet($request->id_spreadsheet, [ 'valueRenderOption' => 'FORMULA', 'dateTimeRenderOption' => 'SERIAL_NUMBER', - 'ranges' => $ranges + 'ranges' => $cells ]); + $answers = []; foreach ($responses->valueRanges as $response) { if ($response->values == NULL) { - echo "Kosong \n"; + $answers[] = NULL; } else { - echo '<pre>', var_export(strval(($response->values)[0][0]), true), '</pre>', "\n"; + $answers[] = strtoupper(strval(($response->values)[0][0])); } } - } - public function test() - { - $answer = DB::table('spreadsheets')->where('id', 1)->get(); - $j = []; - foreach($answer as $a) { - $j[] = 'Sheet1!' . $a->cell; + // Clear Answer + $requestBody = new \Google_Service_Sheets_BatchClearValuesRequest([ + 'ranges' => $cells + ]); + + $response = $service->spreadsheets_values->batchClear($request->id_spreadsheet, $requestBody); + + // Save to Database + DB::table('spreadsheets')->where('id',$id_topic)->delete(); + for ($i=0; $i<count($answers); $i++) { + DB::table('spreadsheets')->insert([ + 'id' => $id_topic, + 'cell' => $cells[$i], + 'value' => $answers[$i], + 'type' => 0 + ]); } - var_dump($j); + DB::table('topics')->where('id', $id_topic)->update([ + 'content' => $request->rich_text, + ]); - $ranges = []; - $ranges[] = 'Sheet1!A1'; - $ranges[] = 'Sheet1!A2'; - $ranges[] = 'Sheet1!A3'; - var_dump($ranges); + return redirect()->route('course', ['id_course' => $id_course, 'msg' => 2]); } /** diff --git a/public/js/learn.js b/public/js/learn.js new file mode 100644 index 0000000000000000000000000000000000000000..e42ad59958790cdcc963a83ce4fe3d530d14e911 --- /dev/null +++ b/public/js/learn.js @@ -0,0 +1,28 @@ +function submit(id_spreadsheet, url) { + document.getElementById("submit").disabled = true; + var xmlhttp = new XMLHttpRequest(); + xmlhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + document.getElementById("result-detail").innerHTML = this.responseText; + var x = document.getElementById("result"); + if (x.style.display === "none") { + x.style.display = "block"; + } + } + }; + xmlhttp.open("POST", url, true); + xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + xmlhttp.setRequestHeader('X-CSRF-TOKEN', $('meta[name="csrf-token"]').attr('content')); + xmlhttp.send("id_spreadsheet=" + id_spreadsheet); +} + +function setForm(number) { + if (number > 0) { + document.getElementById("cell-answers").innerHTML = ''; + var str = ""; + for (i=0; i<number; i++) { + str = str.concat('<div class="col-3" style="margin-bottom:1rem;"> <input type="text" name="cells[]" class="form-control"></div>'); + } + document.getElementById("cell-answers").innerHTML = str; + } +} \ No newline at end of file diff --git a/resources/views/course.blade.php b/resources/views/course.blade.php index ebb19b8d438519f9b6b5353692268987e9cb47a7..6b5b2d0354324ff6db1d54bcef0ea7d09ceba979 100644 --- a/resources/views/course.blade.php +++ b/resources/views/course.blade.php @@ -4,12 +4,25 @@ <div class="container"> @isset(request()->msg) @if( request()->get('msg') == 1 ) - <div class="alert alert-success" role="alert"> + <div class="alert alert-success alert-dismissible fade show" role="alert"> Pembuatan Topik Berhasil + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + @elseif( request()->get('msg') == 2 ) + <div class="alert alert-success alert-dismissible fade show" role="alert"> + Perubahan Topik Berhasil Disimpan + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> </div> @else - <div class="alert alert-danger" role="alert"> + <div class="alert alert-danger alert-dismissible fade show" role="alert"> Pembuatan Topik Gagal + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> </div> @endif @endisset @@ -32,18 +45,21 @@ <div class="card-body"> {{ $topic->content }} <br/> <br/> @if(Auth::user()->role == 1) - <a href="<?php echo $topic->id_course; ?>/learn/<?php echo $topic->id_spreadsheet; ?>/edit" class="btn btn-primary" role="button">Buka Topik</a> + <a href="<?php echo $topic->id_course; ?>/learn/<?php echo $topic->id; ?>/edit" class="btn btn-primary" role="button">Buka Topik</a> @else - <a href="<?php echo $topic->id_course; ?>/learn/<?php echo $topic->id_spreadsheet; ?>" class="btn btn-primary" role="button">Buka Topik</a> + <a href="<?php echo $topic->id_course; ?>/learn/<?php echo $topic->id; ?>" class="btn btn-primary" role="button">Buka Topik</a> @endif </div> </div> </div> @endforeach - </div> <br/> - <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter"> - Tambah Topik - </button> + </div> + @if(Auth::user()->role == 1) + <br/> + <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModalCenter"> + Tambah Topik + </button> + @endif <div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered" role="document"> <div class="modal-content"> diff --git a/resources/views/edit.blade.php b/resources/views/edit.blade.php index 70c7f3d17e0dc9fb2d7cf3e7ed70b3733bed1950..75e71a145ae198ab71844ee73a80f291a66596ad 100644 --- a/resources/views/edit.blade.php +++ b/resources/views/edit.blade.php @@ -19,35 +19,57 @@ <div class="col-lg-4"> <h4>Materi: {{ $topic->name }}</h4> <div class="accordion" id="accordionCourses"> - <div class="card"> - <div class="card-header" id="heading1" style="transform: rotate(0);"> - <h5 class="mb-0"> - <button class="btn stretched-link" type="button" data-toggle="collapse" data-target="#collapse1" aria-expanded="false" aria-controls="collapse1"> - Persoalan - </button> - </h5> - </div> - <div id="collapse1" class="collapse show" aria-labelledby="heading1" data-parent="#accordionCourses"> - <form action="<?php echo Request::url(); ?>/save" name="myform" id="myform" method="post"> - @csrf + <form action="<?php echo Request::url(); ?>/save" name="myform" id="myform" method="post"> + @csrf + <div class="card"> + <div class="card-header" id="heading1" style="transform: rotate(0);"> + <h5 class="mb-0"> + <button class="btn stretched-link" type="button" data-toggle="collapse" data-target="#collapse1" aria-expanded="false" aria-controls="collapse1"> + Atur Persoalan + </button> + </h5> + </div> + <div id="collapse1" class="collapse show" aria-labelledby="heading1" data-parent="#accordionCourses"> <input type="hidden" value="<?php echo $id_spreadsheet; ?>" class="form-control" name="id_spreadsheet" id="id_spreadsheet"> - <textarea name="richh" id="richh"><?php echo $topic->content;?></textarea> - <button style="float: right; margin-top: 1rem; margin-bottom: 1rem;" type="submit" class="btn btn-primary"><b>Simpan</b></button> - </form> - </div> - </div> - <div class="card"> - <div class="card-header" id="heading2" style="transform: rotate(0);"> - <h5 class="mb-0"> - <button class="btn stretched-link" type="button" data-toggle="collapse" data-target="#collapse2" aria-expanded="false" aria-controls="collapse2"> - Kunci Jawaban - </button> - </h5> + <textarea name="rich_text" id="rich_text"><?php echo $topic->content;?></textarea> + </div> </div> - <div id="collapse2" class="collapse" aria-labelledby="heading2" data-parent="#accordionCourses"> - Iki isinie + <div class="card"> + <div class="card-header" id="heading2" style="transform: rotate(0);"> + <h5 class="mb-0"> + <button class="btn stretched-link" type="button" data-toggle="collapse" data-target="#collapse2" aria-expanded="false" aria-controls="collapse2"> + Atur Cell Jawaban + </button> + </h5> + </div> + <div id="collapse2" class="collapse" aria-labelledby="heading2" data-parent="#accordionCourses"> + <div class="card-body"> + <label for="exampleFormControlSelect1">Jumlah Cell Jawaban</label> + <input type="number" class="form-control" id="cell-number" min="1" value="5" onkeyup="setForm(this.value)" onchange="setForm(this.value)"> + <br/> + <label for="exampleFormControlSelect1">Masukkan Cell Jawaban</label> + <div class="row" id="cell-answers"> + <div class="col-3" style="margin-bottom:1rem;"> + <input type="text" name="cells[]" class="form-control"> + </div> + <div class="col-3" style="margin-bottom:1rem;"> + <input type="text" name="cells[]" class="form-control"> + </div> + <div class="col-3" style="margin-bottom:1rem;"> + <input type="text" name="cells[]" class="form-control"> + </div> + <div class="col-3" style="margin-bottom:1rem;"> + <input type="text" name="cells[]" class="form-control"> + </div> + <div class="col-3" style="margin-bottom:1rem;"> + <input type="text" name="cells[]" class="form-control"> + </div> + </div> + </div> + </div> </div> - </div> + <button style="float: right; margin-top: 1rem;" type="submit" class="btn btn-primary"><b>Simpan</b></button> + </form> </div> </div> <div class="col-lg-8"> diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 407fd88f135dcb4d194e35e9e11243119dd00d37..4d7ae8364dc99a98734821db7ab180e66dafe610 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -12,6 +12,7 @@ <!-- Scripts --> <script src="{{ asset('js/app.js') }}" defer></script> <script src="{{ asset('js/text.js') }}" defer></script> + <script src="{{ asset('js/learn.js') }}" defer></script> <script src="https://cdn.tiny.cloud/1/yaezxtmh9h1roazzxnkx70is63n62nbov3xskxim3rpnbcoj/tinymce/5/tinymce.min.js" referrerpolicy="origin"></script> <script>tinymce.init({selector:'textarea'});</script> diff --git a/resources/views/learn.blade.php b/resources/views/learn.blade.php index 26361af8a5c876e653d49400d4f13c624716aa16..856d9afa09f650d3790c5f71e8d4537e31bc6ba6 100644 --- a/resources/views/learn.blade.php +++ b/resources/views/learn.blade.php @@ -2,7 +2,7 @@ @section('content') <div class="container-fluid"> - <div class="row"> + <div class="row justify-content-center"> <div class="col-lg-4"> <div class="card"> <div class="card-header">Judul</div> @@ -17,11 +17,13 @@ frameBorder="0" src="https://docs.google.com/spreadsheets/d/<?php echo $id_spreadsheet; ?>/edit?usp=drivesdk&rm=embedded"> </iframe> - <form action="<?php echo Request::url(); ?>/submit" name="myform" id="myform" method="post"> - @csrf - <input type="hidden" value="<?php echo $id_spreadsheet; ?>" class="form-control" name="id_spreadsheet" id="id_spreadsheet"> - <button style="float: right;" type="submit" class="btn btn-success"><b>Submit</b></button> - </form> + <button id="submit" style="float: right;" type="text" onclick="submit('<?php echo $id_spreadsheet; ?>', '<?php echo Request::url(); ?>/submit')" class="btn btn-success"><b>Submit</b></button> + </div> + <div id="result" class="col-lg-10" style="margin-top: 1rem; display:none"> + <div class="card"> + <div class="card-header">Hasil</div> + <div id="result-detail" class="card-body"></div> + </div> </div> </div> </div> diff --git a/routes/web.php b/routes/web.php index 5311d3cc1348dd18e86663d5fc87ce4cba73b081..7b30b804c53a6b5e4bc89aa7dbe64e8bbddf3491 100644 --- a/routes/web.php +++ b/routes/web.php @@ -18,10 +18,10 @@ Route::get('/', function () { Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); -Route::get('/test', 'LearnController@test')->name('test'); +Route::get('/test', 'AutograderController@test')->name('test'); Route::get('/course/{id_course}', 'CourseController@index')->name('course'); Route::post('/course/{id_course}/learn/new', 'LearnController@new')->name('learn/new'); -Route::get('/course/{id_course}/learn/{id_spreadsheet}', 'LearnController@index')->name('learn'); -Route::get('/course/{id_course}/learn/{id_spreadsheet}/edit', 'LearnController@edit')->name('edit'); -Route::post('/course/{id_course}/learn/{id_spreadsheet}/edit/save', 'LearnController@save')->name('edit/save'); -Route::post('/course/{id_course}/learn/{id_spreadsheet}/submit', 'LearnController@submit')->name('learn/submit'); \ No newline at end of file +Route::get('/course/{id_course}/learn/{id_topic}', 'LearnController@index')->name('learn'); +Route::get('/course/{id_course}/learn/{id_topic}/edit', 'LearnController@edit')->name('edit'); +Route::post('/course/{id_course}/learn/{id_topic}/edit/save', 'LearnController@save')->name('edit/save'); +Route::post('/course/{id_course}/learn/{id_topic}/submit', 'AutograderController@index')->name('autograder'); \ No newline at end of file