Test Setup Failed
Push — master ( 93675a...ba3342 )
by Mohamed
14:07 queued 12s
created

ExaminationStudentsController::searchSimilarName()   B

Complexity

Conditions 10
Paths 14

Size

Total Lines 37
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 10
eloc 23
nc 14
nop 2
dl 0
loc 37
rs 7.6666
c 2
b 0
f 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Http\Controllers;
4
5
use Session;
6
use App\Models\Institution;
7
use Illuminate\Http\Request;
8
use App\Models\Security_user;
9
use App\Models\Academic_period;
10
use App\Models\Education_grade;
11
use App\Models\Institution_class;
12
use App\Models\Examination_student;
13
use App\Models\Institution_student;
14
use Maatwebsite\Excel\Facades\Excel;
15
use Illuminate\Support\Facades\Storage;
16
use App\Models\Institution_class_student;
17
use App\Exports\ExaminationStudentsExport;
18
use App\Imports\ExaminationStudentsImport;
19
use App\Models\Institution_student_admission;
20
21
class ExaminationStudentsController extends Controller
22
{
23
    public function __construct($year = 2019, $grade = 'G5')
24
    {
25
        $this->year = $year;
0 ignored issues
show
Bug Best Practice introduced by
The property year does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
26
        $this->grade = $grade;
0 ignored issues
show
Bug Best Practice introduced by
The property grade does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
27
        $this->student = new Security_user();
0 ignored issues
show
Bug Best Practice introduced by
The property student does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
28
        $this->examination_student = new Examination_student();
0 ignored issues
show
Bug Best Practice introduced by
The property examination_student does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
29
        $this->academic_period =  Academic_period::where('code', '=', $this->year)->first();
0 ignored issues
show
Bug Best Practice introduced by
The property academic_period does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
30
        $this->education_grade = Education_grade::where('code', '=', $this->grade)->first();
0 ignored issues
show
Bug Best Practice introduced by
The property education_grade does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
31
        $this->output = new \Symfony\Component\Console\Output\ConsoleOutput();
0 ignored issues
show
Bug Best Practice introduced by
The property output does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
32
    }
33
34
    public function index()
35
    {
36
        return view('uploadcsv');
37
    }
38
39
    public function uploadFile(Request $request)
40
    {
41
42
        if ($request->input('submit') != null) {
43
44
            $file = $request->file('file');
45
46
            // File Details
47
            $filename = 'exams_students.csv';
48
            $extension = $file->getClientOriginalExtension();
49
            $fileSize = $file->getSize();
50
51
            // Valid File Extensions
52
            $valid_extension = array("csv");
53
54
            // 20MB in Bytes
55
            $maxFileSize = 30971520;
56
57
            // Check file extension
58
            if (in_array(strtolower($extension), $valid_extension)) {
59
60
                // Check file size
61
                if ($fileSize <= $maxFileSize) {
62
63
                    // File upload location
64
                    Storage::disk('local')->putFileAs(
65
                        'examination/',
66
                        $file,
0 ignored issues
show
Bug introduced by
It seems like $file can also be of type Illuminate\Http\UploadedFile[] and array; however, parameter $file of Illuminate\Filesystem\Fi...temAdapter::putFileAs() does only seem to accept Illuminate\Http\File|Illuminate\Http\UploadedFile, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

66
                        /** @scrutinizer ignore-type */ $file,
Loading history...
67
                        $filename
68
                    );
69
                    Session::flash('message', 'File upload successfully!');
70
                    // Redirect to index
71
                } else {
72
                    Session::flash('message', 'File too large. File must be less than 20MB.');
73
                }
74
            } else {
75
                Session::flash('message', 'Invalid File Extension.');
76
            }
77
        }
78
        return redirect()->action('ExaminationStudentsController@index');
79
    }
80
81
    /**
82
     * Import students data to the Examinations table 
83
     *
84
     * @return void
85
     */
86
    public static function callOnClick()
87
    {
88
        // Import CSV to Database
89
        $excelFile = "/examination/exams_students.csv";
90
91
        $import = new ExaminationStudentsImport();
92
        $import->import($excelFile, 'local', \Maatwebsite\Excel\Excel::CSV);
93
    }
94
95
    /**
96
     * Iterate over existing student's data
97
     *
98
     * @return void
99
     */
100
    public  function doMatch()
101
    {
102
        $students = Examination_student::get()->toArray();
103
        //    array_walk($students,array($this,'clone'));
104
        array_walk($students, array($this, 'clone'));
105
    }
106
107
    /**
108
     * Set Examination values
109
     *
110
     * @param array $students
111
     * @return array
112
     */
113
    public function setIsTakingExam($students){
114
        $students['taking_g5_exam'] = false;
115
        $students['taking_ol_exam'] = false;
116
        $students['taking_al_exam'] = false;
117
        switch($this->education_grade->code){
0 ignored issues
show
Bug introduced by
The property code does not seem to exist on App\Models\Education_grade. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
118
            case 'G5':
119
                $students['taking_g5_exam'] = true;
120
                break;
121
            case 'G4':
122
                $students['taking_g5_exam'] = true;
123
                break;
124
            case 'G10':
125
                $students['taking_ol_exam'] = true;
126
                break;
127
            case 'G11':
128
                $students['taking_ol_exam'] = true;
129
                break;
130
            case preg_match('13',$this->education_grade->code):  
131
                $students['taking_al_exam'] = true;
132
                break;             
133
        }
134
        return $students;
135
    }
136
137
138
    /**
139
     * Main function to merge the student's to SIS
140
     *
141
     * @param array $student
142
     * @return void
143
     */
144
    public function clone($student)
145
    {
146
        //get student matching with same dob and gender
147
        $matchedStudent = $this->getMatchingStudents($student);
148
149
        // if the first match missing do complete insertion
150
        $institution = Institution::where('code', '=', $student['schoolid'])->first();
151
152
        if (!is_null($institution)) {
153
154
            // ge the class lists to belong the school
155
            $institutionClass = Institution_class::where(
156
                [
157
                    'institution_id' => $institution->id,
158
                    'academic_period_id' => $this->academic_period->id,
159
                    'education_grade_id' => $this->education_grade->id
160
                ]
161
            )->join('institution_class_grades', 'institution_classes.id', 'institution_class_grades.institution_class_id')->get()->toArray();
162
163
            // set search variables 
164
            $admissionInfo = [
165
                'instituion_class' => $institutionClass,
166
                'instituion' => $institution,
167
                'education_grade' =>  $this->education_grade,
168
                'academic_period' => $this->academic_period
169
            ];
170
171
            // if no matching found
172
            if (empty($matchedStudent)) {
173
                $sis_student = $this->student->insertExaminationStudent($student);
174
                $this->updateStudentId($student, $sis_student);
175
176
                //TODO implement insert student to admission table
177
                $student['id'] = $sis_student['id'];
178
179
                $student = $this->setIsTakingExam($student);
180
                if (count($institutionClass) == 1) {
181
                    $admissionInfo['instituion_class'] = $institutionClass[0];
182
                    Institution_student::createExaminationData($student, $admissionInfo);
183
                    Institution_student_admission::createExaminationData($student, $admissionInfo);
184
                    Institution_class_student::createExaminationData($student, $admissionInfo);
185
                } else {
186
                    Institution_student_admission::createExaminationData($student, $admissionInfo);
187
                    Institution_student::createExaminationData($student, $admissionInfo);
188
                }
189
                // update the matched student's data    
190
            } else {
191
                $student = $this->student->updateExaminationStudent($student, $matchedStudent);
192
                $matchedStudent = array_merge((array) $student, $matchedStudent);
193
                Institution_student::updateExaminationData($matchedStudent, $admissionInfo);
194
                $matchedStudent['id'] = $matchedStudent['student_id'];
195
                $this->updateStudentId($student, $matchedStudent);
196
            }
197
        }
198
    }
199
200
    /**
201
     * This function is implemented similar_text search algorithm 
202
     * to get the most matching name with the existing students
203
     * data set
204
     *
205
     * @param array $student
206
     * @return array
207
     */
208
    public function getMatchingStudents($student)
209
    {
210
        $sis_users = $this->student->getMatches($student);
211
        $studentData = [];
212
        if (!is_null($sis_users) && (count($sis_users) > 0)) {
0 ignored issues
show
introduced by
The condition is_null($sis_users) is always false.
Loading history...
213
            $studentData = $this->searchSimilarName($student, $sis_users);
214
        }
215
        return $studentData;
216
    }
217
218
    /**
219
     * Search most matching name
220
     *
221
     * @param array $student
222
     * @param array $sis_students
223
     * @return array
224
     */
225
    public function searchSimilarName($student, $sis_students)
226
    {
227
        $highest = [];
228
        $previousValue = null;
229
        $matchedData = [];
230
231
        // search for matching name with last name
232
        foreach ($sis_students as $key => $value) {
233
            similar_text(get_l_name($student['f_name']), get_l_name($value['first_name']), $percentage);
234
            $value['rate'] = $percentage;
235
236
            if ($value['rate'] == 100) {
237
                $matchedData[] = $value;
238
            }
239
240
            if (($previousValue)) {
241
                $highest =  ($percentage > $previousValue['rate']) ? $value : $value;
242
            } else {
243
                $highest = $value;
244
            }
245
            $previousValue = $value;
246
        }
247
248
        //If the not matched 100% try to get most highest value with full name
249
        if ( ($highest['rate']  < 100) || (count($matchedData) > 1)) {
250
            foreach ($sis_students as $key => $value) {
251
                similar_text($student['f_name'], $value['first_name'], $percentage);
252
                $value['rate'] = $percentage;
253
                if (($previousValue)) {
254
                    $highest =  ($percentage > $previousValue['rate']) ? $value : $value;
255
                } else {
256
                    $highest = $value;
257
                }
258
                $previousValue = $value;
259
            }
260
        }
261
        return $highest;
262
    }
263
264
    /**
265
     * Generate new NSID for students
266
     *
267
     * @param array $student
268
     * @param array $sis_student
269
     * @return void
270
     */
271
    public function updateStudentId($student, $sis_student)
272
    {
273
        $student['nsid'] =  $sis_student['openemis_no'];
274
        // add new NSID to the examinations data set
275
        $this->examination_student->where(['st_no' => $student['st_no']])->update($student);
276
        $this->output->writeln('Updated ' . $sis_student['id'] . ' to NSID' . $sis_student['openemis_no']);
277
    }
278
279
    /**
280
     * export the all data with NSID
281
     *
282
     * @return void
283
     */
284
    public function export()
285
    {
286
        return Excel::download(new ExaminationStudentsExport, 'Students_data_with_nsid.csv');
0 ignored issues
show
Bug Best Practice introduced by
The expression return Maatwebsite\Excel...ts_data_with_nsid.csv') returns the type Symfony\Component\HttpFo...tion\BinaryFileResponse which is incompatible with the documented return type void.
Loading history...
287
    }
288
}
289