Skip to content

Commit 3153f3e

Browse files
committed
Created the structure for the tethered courses
Can designate a course as alpha Check if they want to import as a beta course Can import an alpha course as a beta course AssignmentController has the start Assignment is replicated in the beta course Can add questions via the remixer Can add questions searching by tag Can direct import questions from the alpha to the beta assignment Can reload the page to the correct question Set alpha to 0 on import Warning if you remove an assignment Get the extra message when removing the question from the summary page Confirmation to remove question in the questions view page Imported the component for the modal Renamed remove question to be more descriptive Can remove questions from the search by tag Worked out for the questions get page Cannot delete a beta assignment or the assessments Added alpha symbol for alpha courses Added list of Beta courses to Alpha Course account Added warnings to Alpha course Fixed spelling mistake Added warnings for unthetered assignments Warnings when adding or importing a new assignment Create Alpha course import code in the database Instructors need a valid import code for alpha courses Fixed foreign key issues with deleting Beta courses Can untether Beta courses Labeling the Beta courses Created the architecture for adding/removing assessments from alpha courses Set up table for approvals Can approve adding assessments from Alpha courses Changed some alpha/beta text Can approval adding the beta questions Can give removal permission Direct add works with the beta course approvals Refactored code Created table with pending approvals Viewable table of pending approvals Created the structure for the beta course notification Created CRON job code for pending approvals Created the email to be sent for the notifications Added BetaCourseApprovals to the kernel Perform the redirect if it is a beta assignment Learning Trees now work with approvals Fixed tethered learning tree bug Fixed issue with syncing up adding and removing questions Can now remove from the questions view modal Determine link by enrollment/course dates Added warning about the course dates Cleaned up some output Can untether Beta courses Fixed issue with alpha option not showing up Can't delete course if there are beta courses Tethered tests pass Changed some language for Beta course approvals Can still import non-alpha courses All tests pass UI fixes for tethered courses Added warning about course dates Fixed height when enroll in cousre modal shown Changed to ordering by course start date
1 parent c71facf commit 3153f3e

63 files changed

Lines changed: 3234 additions & 221 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

app/AlphaCourseImportCode.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class AlphaCourseImportCode extends Model
8+
{
9+
//
10+
}

app/Assignment.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ public function gradersAccess()
8181
return $graders;
8282
}
8383

84+
public function isBetaAssignment()
85+
{
86+
return DB::table('beta_assignments')->where('id', $this->id)->first() !== null;
87+
}
8488

8589
public function assignToUsers()
8690
{
@@ -119,6 +123,7 @@ public function getAssignmentsByCourse(Course $course,
119123

120124

121125
$course_assignments = $course->assignments;
126+
$course_beta_assignment_ids = $course->betaAssignmentIds();
122127
if (Auth::user()->role === 4) {
123128
$accessible_assignment_ids = $course->accessbileAssignmentsByGrader(Auth::user()->id);
124129
}
@@ -146,7 +151,7 @@ public function getAssignmentsByCourse(Course $course,
146151
}
147152
$assignments_info[$key] = $assignment->attributesToArray();
148153
$assignments_info[$key]['shown'] = $assignment->shown;
149-
154+
$assignments_info[$key]['is_beta_assignment'] = in_array($assignment->id, $course_beta_assignment_ids);
150155

151156
if (Auth::user()->role === 3) {
152157
$is_extension = isset($extensions_by_assignment[$assignment->id]);
@@ -484,6 +489,36 @@ public function seeds()
484489
return $this->hasMany('App\Seed');
485490
}
486491

492+
493+
public function betaAssignments()
494+
{
495+
if (!$this->course->alpha) {
496+
return [];
497+
}
498+
$beta_assignment_ids = DB::table('beta_assignments')
499+
->where('alpha_assignment_id', $this->id)
500+
->get();
501+
502+
if ($beta_assignment_ids->isNotEmpty()) {
503+
$beta_assignment_ids = $beta_assignment_ids->pluck('id')->toArray();
504+
}
505+
return $this->whereIn('assignments.id', $beta_assignment_ids)
506+
->get();
507+
}
508+
509+
/**
510+
* @return Assignment[]
511+
*/
512+
public function addBetaAssignments()
513+
{
514+
$assignments = [$this];
515+
$beta_assignments = $this->betaAssignments();
516+
foreach ($beta_assignments as $beta_assignment) {
517+
$assignments[] = $beta_assignment;
518+
}
519+
return $assignments;
520+
}
521+
487522
public function course()
488523
{
489524
return $this->belongsTo('App\Course');

app/AssignmentSyncQuestion.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,41 @@
1111
class AssignmentSyncQuestion extends Model
1212
{
1313

14+
public function addLearningTreeIfBetaAssignment(int $assignment_question_id,
15+
int $assignment_id,
16+
int $question_id)
17+
{
18+
$beta_learning_tree = DB::table('beta_course_approvals')
19+
->where('beta_assignment_id', $assignment_id)
20+
->where('beta_question_id', $question_id)
21+
->where('beta_learning_tree_id','<>',0)
22+
->first();
23+
if ($beta_learning_tree) {
24+
DB::table('assignment_question_learning_tree')
25+
->insert([
26+
'assignment_question_id' => $assignment_question_id,
27+
'learning_tree_id' => $beta_learning_tree->id,
28+
'created_at' => Carbon::now(),
29+
'updated_at' => Carbon::now()
30+
]);
31+
}
32+
33+
}
34+
1435
public function completedAllAssignmentQuestions($assignment)
1536
{
1637
$num_technology_questions = $assignment->number_of_randomized_assignments
1738
?: DB::table('assignment_question')
1839
->where('assignment_id', $assignment->id)
19-
->join('questions','assignment_question.question_id','=','questions.id')
40+
->join('questions', 'assignment_question.question_id', '=', 'questions.id')
2041
->where('technology', '<>', 'text')
2142
->count();
2243
$num_non_technology_questions = DB::table('assignment_question')
2344
->where('assignment_id', $assignment->id)
2445
->where('open_ended_submission_type', '<>', '0')
2546
->get()
2647
->count();
27-
if ($num_technology_questions + $num_non_technology_questions === 0){
48+
if ($num_technology_questions + $num_non_technology_questions === 0) {
2849
return false;
2950
}
3051
$num_submitted_technology_questions = DB::table('submissions')

app/BetaAssignment.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class BetaAssignment extends Model
8+
{
9+
protected $guarded = [];
10+
}

app/BetaCourse.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use Illuminate\Database\Eloquent\Model;
6+
7+
class BetaCourse extends Model
8+
{
9+
protected $guarded = [];
10+
11+
public function untether(Course $course)
12+
{
13+
$beta_assignment_ids = $course->assignments->pluck('id')->toArray();
14+
BetaCourseApproval::whereIn('id', $beta_assignment_ids)->delete();
15+
BetaAssignment::whereIn('id', $beta_assignment_ids)->delete();
16+
BetaCourse::where('id', $course->id)->delete();
17+
}
18+
}

app/BetaCourseApproval.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use Exception;
6+
use Illuminate\Database\Eloquent\Model;
7+
use Illuminate\Support\Facades\DB;
8+
use Illuminate\Support\Facades\Log;
9+
10+
class BetaCourseApproval extends Model
11+
{
12+
protected $guarded = [];
13+
14+
public function updateBetaCourseApprovalsForQuestion(Assignment $assignment,
15+
int $question_id,
16+
string $action,
17+
int $learning_tree_id = 0)
18+
{
19+
if (!in_array($action, ['add', 'remove'])) {
20+
throw new Exception ('That is not a valid action.');
21+
}
22+
if ($assignment->course->alpha) {
23+
$beta_assignments = $assignment->betaAssignments();
24+
// if this is an alpha course add the approvals
25+
foreach ($beta_assignments as $beta_assignment) {
26+
$course_approval_exists = BetaCourseApproval::where('beta_assignment_id', $beta_assignment->id)
27+
->where('beta_question_id', $question_id)
28+
->where('beta_learning_tree_id', $learning_tree_id)
29+
->first();
30+
if ($course_approval_exists) {
31+
//add becomes remove or remove becomes an add; either way the beta course doesn't change
32+
BetaCourseApproval::where('beta_assignment_id', $beta_assignment->id)
33+
->where('beta_question_id', $question_id)
34+
->where('beta_learning_tree_id', $learning_tree_id)
35+
->delete();
36+
} else {
37+
BetaCourseApproval::create([
38+
'beta_assignment_id' => $beta_assignment->id,
39+
'action' => $action,
40+
'beta_question_id' => $question_id,
41+
'beta_learning_tree_id' => $learning_tree_id]);
42+
}
43+
}
44+
} else {
45+
///if this is a Beta assignment, remove any approvals
46+
BetaCourseApproval::where('beta_question_id', $question_id)
47+
->where('beta_assignment_id', $assignment->id)
48+
->delete();
49+
}
50+
}
51+
52+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
namespace App\Console\Commands;
4+
5+
use App\Exceptions\Handler;
6+
use Carbon\Carbon;
7+
use Exception;
8+
use Illuminate\Console\Command;
9+
use Illuminate\Support\Facades\DB;
10+
11+
class notifyBetaCourseApprovals extends Command
12+
{
13+
/**
14+
* The name and signature of the console command.
15+
*
16+
* @var string
17+
*/
18+
protected $signature = 'notify:BetaCourseApprovals';
19+
20+
/**
21+
* The console command description.
22+
*
23+
* @var string
24+
*/
25+
protected $description = 'Tell instructors when they need to approve assignments';
26+
27+
/**
28+
* Create a new command instance.
29+
*
30+
* @return void
31+
*/
32+
public function __construct()
33+
{
34+
parent::__construct();
35+
}
36+
37+
/**
38+
* Execute the console command.
39+
*
40+
* @return int
41+
* @throws Exception
42+
*/
43+
public function handle()
44+
{
45+
try {
46+
$yesterday = Carbon::now()->subDay()->format('Y-m-d H:i:s');
47+
$pending_approvals = DB::table('beta_course_approvals')
48+
->join('assignments', 'beta_course_approvals.beta_assignment_id', '=', 'assignments.id')
49+
->join('courses', 'assignments.course_id', '=', 'courses.id')
50+
->join('users', 'courses.user_id', '=', 'users.id')
51+
->select('courses.id', 'courses.name AS course_name',
52+
'assignments.id as assignment_id',
53+
'assignments.name AS assignment_name',
54+
DB::raw('count(*) AS total_pending'),
55+
'users.id AS user_id',
56+
'users.email',
57+
'users.first_name'
58+
)
59+
->where('courses.beta_approval_notifications', 1)
60+
->where('beta_course_approvals.created_at', '>', $yesterday)
61+
->groupBy('assignments.id')
62+
->get();
63+
$pending_approvals_by_user_id = [];
64+
foreach ($pending_approvals as $pending_approval) {
65+
if (!isset($pending_approval_by_user_id[$pending_approval->user_id])) {
66+
$pending_approvals_by_user_id[$pending_approval->user_id] = [];
67+
$pending_approvals_by_user_id[$pending_approval->user_id]['first_name'] = $pending_approval->first_name;
68+
$pending_approvals_by_user_id[$pending_approval->user_id]['email'] = $pending_approval->email;
69+
$pending_approvals_by_user_id[$pending_approval->user_id]['pending_approvals'] = '';
70+
}
71+
$app_url = config('app.url');
72+
$pending_approvals_by_user_id[$pending_approval->user_id]['pending_approvals'] .= "<li>$pending_approval->course_name: <a href='$app_url/instructors/assignments/$pending_approval->assignment_id/information/questions'>$pending_approval->assignment_name</a> has $pending_approval->total_pending pending approvals</li>";
73+
}
74+
75+
foreach ($pending_approvals_by_user_id as $pending_approval) {
76+
$beauty_mail = app()->make(\Snowfire\Beautymail\Beautymail::class);
77+
$to_email = $pending_approval['email'];
78+
$email_info = ['pending_approvals' => $pending_approval['pending_approvals'],
79+
'first_name' => $pending_approval['first_name']
80+
];
81+
$beauty_mail->send('emails.pending_beta_course_approvals', $email_info, function ($message)
82+
use ($to_email) {
83+
$message
84+
->from('adapt@noreply.libretexts.org', 'Adapt')
85+
->to($to_email)
86+
->subject("Pending Beta Course Approvals");
87+
});
88+
}
89+
} catch (Exception $e) {
90+
$h = new Handler(app());
91+
$h->report($e);
92+
exit;
93+
}
94+
return 0;
95+
}
96+
}

app/Console/Kernel.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ protected function schedule(Schedule $schedule)
4444

4545
$schedule->command('dataShop:toS3')->twiceDaily();
4646

47+
$schedule->command('notify:BetaCourseApprovals')->daily();
4748
/* grader notifications */
4849
$schedule->command('notify:gradersForDueAssignments')->hourly();
4950
$schedule->command('notify:gradersForLateSubmissions')->Daily();

0 commit comments

Comments
 (0)