Ingen beskrivning

FiveYearPlansController.php 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. <?php
  2. class FiveYearPlansController extends \BaseController {
  3. /**
  4. * Checks whether a user has permission to view a page in this controller
  5. *
  6. * @var User $user Authenticated user
  7. */
  8. private function userHasAccess($program_id)
  9. {
  10. $user = Auth::user();
  11. switch ($user->role) {
  12. case '3':
  13. $programs = $user->programs->lists('id');
  14. // If program does not belong to user, show 403
  15. if(!in_array($program_id, $programs))
  16. return false;
  17. break;
  18. case '2':
  19. $programs = Program::where('school_id', $user->school_id)->lists('id');
  20. // If program is not in user's school, show 403
  21. if(!in_array($program_id, $programs))
  22. return false;
  23. break;
  24. case '4':
  25. return false;
  26. }
  27. return true;
  28. }
  29. /**
  30. * Page to create a new plan for the current quinquennium
  31. * @var string $title Title for page
  32. * @var Program $programs Collection of programs user has access to
  33. * @var Outcome $outcomes List of outcomes ordered by name
  34. * @var User $user Currently logged user
  35. * @var Course $courses Courses for a particular program
  36. */
  37. public function create(Program $program)
  38. {
  39. $title = 'New Five Year Plan for '.$program->name;
  40. $user = Auth::user();
  41. $outcomes = Outcome::orderBy('name')->get();
  42. $current_quinquennium = Quinquennium::
  43. where('start_date', '<=', date('Y-m-d'))
  44. ->where('end_date', '>=', date('Y-m-d'))
  45. ->first();
  46. $courses = Course::
  47. select('id', 'code', 'number', 'name')
  48. ->where('program_id', $program->id)
  49. ->groupBy('name')
  50. ->orderBy('code','ASC')
  51. ->orderBy('number','ASC')
  52. ->orderBy('name','ASC')
  53. ->get();
  54. // Check if user can create a plan
  55. if(!$this->userHasAccess($program->id))
  56. {
  57. return View::make('global.403');
  58. }
  59. return View::make('local.managers.shared.create_five_year_plan', compact('title', 'program', 'current_quinquennium', 'outcomes', 'courses'));
  60. }
  61. /**
  62. * Lists five year plans by quinquennium and program
  63. * @var string $title Title for page
  64. * @var Program $programs Collection of programs user has access to
  65. * @var User $user Authenticated user
  66. */
  67. public function index()
  68. {
  69. $title = 'Five Year Plans';
  70. $user = Auth::user();
  71. $quinquenniums = Quinquennium::all();
  72. $current_quinquennium = Quinquennium::
  73. where('start_date', '<=', date('Y-m-d'))
  74. ->where('end_date', '>=', date('Y-m-d'))
  75. ->first();
  76. switch ($user->role) {
  77. case '1':
  78. $programs = Program::all();
  79. break;
  80. case '2':
  81. $programs = Program::where('school_id', $user->school_id)->get();
  82. break;
  83. case 3:
  84. $programs = $user->programs;
  85. break;
  86. default:
  87. App::abort('404');
  88. break;
  89. }
  90. return View::make('local.managers.shared.index_five_year_plans', compact('title', 'quinquenniums', 'programs', 'current_quinquennium'));
  91. }
  92. /**
  93. * Processes and stores five year plan for a particular program
  94. *
  95. * @var array $input JSON object containing new plan information
  96. * @var FiveYearPlan $plan Instance of newly created plan
  97. * @var FypPart $mini_plan Instance of limited annual plan belonging to five year plan
  98. * @var string response Encoded JSON string containing response for the browser
  99. * @return string Encoded JSON string
  100. */
  101. public function store()
  102. {
  103. header('Content-Type: application/json');
  104. $input = json_decode(Input::get('five_year_plan')); // Get plan as string
  105. DB::beginTransaction();
  106. try {
  107. // Create five year plan base structure
  108. $plan = FiveYearPlan::create(array(
  109. 'program_id' => $input->program_id,
  110. 'quinquennium_id' => $input->quinquennium_id,
  111. )
  112. );
  113. foreach ($input->mini_plans as $mini_plan_input) {
  114. $mini_plan_validator = Validator::make(
  115. array(
  116. 'year_start' => $mini_plan_input->year_start,
  117. 'year_end' => $mini_plan_input->year_end
  118. ),
  119. array(
  120. 'year_start' => 'required|integer|digits:4',
  121. 'year_end' => 'required|integer|digits:4'
  122. )
  123. );
  124. /** If validation fails */
  125. if ($mini_plan_validator->fails())
  126. {
  127. $response = array(
  128. 'status' => 'danger',
  129. );
  130. }
  131. $mini_plan = FypPart::create(array(
  132. 'five_year_plan_id' => $plan->id,
  133. 'year_start' => $mini_plan_input->year_start,
  134. 'year_end' => $mini_plan_input->year_end,
  135. )
  136. );
  137. foreach ($mini_plan_input->outcomes as $index => $outcome_input) {
  138. $outcomes_validator = Validator::make(
  139. array(
  140. 'fyp_part_id'=> $mini_plan->id,
  141. 'outcome_id'=> $outcome_input->id,
  142. 'objectives'=> json_encode($outcome_input->objectives),
  143. 'courses'=> json_encode($outcome_input->courses),
  144. ),
  145. array(
  146. 'fyp_part_id'=> 'required|integer',
  147. 'outcome_id'=> 'required|integer',
  148. 'objectives'=> 'required',
  149. 'courses'=> 'required',
  150. )
  151. );
  152. /** If validation fails */
  153. if ($outcomes_validator->fails())
  154. {
  155. $response = array(
  156. 'status' => 'danger',
  157. );
  158. }
  159. FypPartOutcome::create(array(
  160. 'fyp_part_id'=> $mini_plan->id,
  161. 'outcome_id'=> $outcome_input->id,
  162. 'objectives'=> json_encode($outcome_input->objectives),
  163. 'courses'=> json_encode($outcome_input->courses),
  164. 'display_order'=> $index + 1,
  165. )
  166. );
  167. }
  168. }
  169. DB::commit();
  170. Session::flash('status', 'success');
  171. Session::flash('message', 'Five Year Plan created. You can review it below. Click the Edit button if you want to make any changes. To submit your plan, click the Submit button. Please note that submitted plans are final.');
  172. $response = array(
  173. 'status' => 'success',
  174. 'message' => $input->quinquennium_id,
  175. 'redirect_url' => URL::action('FiveYearPlansController@show', array('program'=> $plan->program_id, 'five_year_plan'=> $plan->id))
  176. );
  177. echo json_encode($response);
  178. return;
  179. } catch (Exception $e) {
  180. DB::rollBack();
  181. $response = array(
  182. 'status' => 'danger',
  183. 'message' => $e->getMessage()
  184. );
  185. echo json_encode($response);
  186. }
  187. }
  188. /**
  189. * Shows five year plan
  190. *
  191. * @param Program $program Program to which the plan belongs to
  192. * @param FiveYearPlan $plan An instance of the Five Year Plan to show
  193. * @var string $quinquennium_start_date Year when the quinquennium starts
  194. * @var string $quinquennium_end_date Year when the quinquennium ends
  195. * @var string title Title of the page
  196. * @var Program $programs Logged user's program(s)
  197. * @var Outcome $outcomes List of all outcomes
  198. */
  199. public function show(Program $program, FiveYearPlan $plan)
  200. {
  201. $outcomes = Outcome::orderBy('name')->get();
  202. $quinquennium_start_date = date('Y', strtotime($plan->quinquennium->start_date));
  203. $quinquennium_end_date = date('Y', strtotime($plan->quinquennium->end_date));
  204. $title = $quinquennium_start_date.'-'.$quinquennium_end_date.' Five Year Plan for '.$program->name;
  205. // Check if user can create a plan
  206. if(!$this->userHasAccess($program->id))
  207. {
  208. return View::make('global.403');
  209. }
  210. return View::make('local.managers.shared.show_five_year_plan', compact('title', 'program', 'plan', 'outcomes'));
  211. }
  212. /**
  213. * Page to edit a plan for the current quinquennium
  214. * @var string $title Title for page
  215. * @var Program $programs Collection of programs user has access to
  216. * @var User $user Authenticated user
  217. */
  218. public function edit(Program $program, FiveYearPlan $plan)
  219. {
  220. $title = 'Edit Five Year Plan for '.$program->name;
  221. $user = Auth::user();
  222. $outcomes = Outcome::orderBy('name')->get();
  223. $current_quinquennium = Quinquennium::
  224. where('start_date', '<=', date('Y-m-d'))
  225. ->where('end_date', '>=', date('Y-m-d'))
  226. ->first();
  227. $courses = Course::
  228. select('id', 'code', 'number', 'name')
  229. ->where('program_id', $program->id)
  230. ->groupBy('name')
  231. ->orderBy('code','ASC')
  232. ->orderBy('number','ASC')
  233. ->orderBy('name','ASC')
  234. ->get();
  235. // Check if user can create a plan
  236. if(!$this->userHasAccess($program->id))
  237. {
  238. return View::make('global.403');
  239. }
  240. return View::make('local.managers.shared.edit_five_year_plan', compact('title', 'program', 'current_quinquennium', 'outcomes', 'courses', 'plan'));
  241. }
  242. /**
  243. * Processes and stores five year plan for a particular program
  244. *
  245. * @var array $input JSON object containing new plan information
  246. * @var FiveYearPlan $plan Instance of newly created plan
  247. * @var FypPart $mini_plan Instance of limited annual plan belonging to five year plan
  248. * @var string response Encoded JSON string containing response for the browser
  249. * @return string Encoded JSON string
  250. */
  251. public function update()
  252. {
  253. if(Input::get('submit'))
  254. {
  255. }
  256. elseif(Input::get('revert'))
  257. {
  258. }
  259. else
  260. {
  261. header('Content-Type: application/json');
  262. $input = json_decode(Input::get('five_year_plan')); // Get plan as string
  263. DB::beginTransaction();
  264. try {
  265. $plan = FiveYearPlan::find($input->plan_id);
  266. $plan->updated_at = date('Y-m-d H:i:s');
  267. $plan->save();
  268. // Delete all annual (mini) plans and consequently, all their outcomes
  269. FypPart::where('five_year_plan_id', $plan->id)->delete();
  270. foreach ($input->mini_plans as $mini_plan_input) {
  271. $mini_plan_validator = Validator::make(
  272. array(
  273. 'year_start' => $mini_plan_input->year_start,
  274. 'year_end' => $mini_plan_input->year_end
  275. ),
  276. array(
  277. 'year_start' => 'required|integer|digits:4',
  278. 'year_end' => 'required|integer|digits:4'
  279. )
  280. );
  281. /** If validation fails */
  282. if ($mini_plan_validator->fails())
  283. {
  284. $response = array(
  285. 'status' => 'danger',
  286. );
  287. }
  288. $mini_plan = FypPart::create(array(
  289. 'five_year_plan_id' => $plan->id,
  290. 'year_start' => $mini_plan_input->year_start,
  291. 'year_end' => $mini_plan_input->year_end,
  292. )
  293. );
  294. foreach ($mini_plan_input->outcomes as $index => $outcome_input) {
  295. $outcomes_validator = Validator::make(
  296. array(
  297. 'fyp_part_id'=> $mini_plan->id,
  298. 'outcome_id'=> $outcome_input->id,
  299. 'objectives'=> json_encode($outcome_input->objectives),
  300. 'courses'=> json_encode($outcome_input->courses),
  301. ),
  302. array(
  303. 'fyp_part_id'=> 'required|integer',
  304. 'outcome_id'=> 'required|integer',
  305. 'objectives'=> 'required',
  306. 'courses'=> 'required',
  307. )
  308. );
  309. /** If validation fails */
  310. if ($outcomes_validator->fails())
  311. {
  312. $response = array(
  313. 'status' => 'danger',
  314. );
  315. }
  316. FypPartOutcome::create(array(
  317. 'fyp_part_id'=> $mini_plan->id,
  318. 'outcome_id'=> $outcome_input->id,
  319. 'objectives'=> json_encode($outcome_input->objectives),
  320. 'courses'=> json_encode($outcome_input->courses),
  321. 'display_order'=> $index + 1,
  322. )
  323. );
  324. }
  325. }
  326. DB::commit();
  327. Session::flash('status', 'success');
  328. Session::flash('message', 'Five Year Plan updated.');
  329. $response = array(
  330. 'status' => 'success',
  331. 'message' => $input->quinquennium_id,
  332. 'redirect_url' => URL::action('FiveYearPlansController@show', array('program'=> $plan->program_id, 'five_year_plan'=> $plan->id))
  333. );
  334. echo json_encode($response);
  335. return;
  336. } catch (Exception $e) {
  337. DB::rollBack();
  338. $response = array(
  339. 'status' => 'danger',
  340. 'message' => $e->getMessage().' '.$e->getLine()
  341. );
  342. echo json_encode($response);
  343. }
  344. }
  345. }
  346. public function msWord(FiveYearPlan $plan)
  347. {
  348. try {
  349. $filename = 'OLAS Five Year Plan for '.$plan->program->name.' ('.date('d-m-Y').').docx';
  350. require_once 'PHPWord-0.12.1/src/PhpWord/Autoloader.php';
  351. \PhpOffice\PhpWord\Autoloader::register();
  352. // Instantiate new document
  353. $phpWord = new \PhpOffice\PhpWord\PhpWord();
  354. // -----------------
  355. // $styleTable = array(
  356. // 'borderColor'=>'006699',
  357. // 'borderSize'=>6,
  358. // 'cellMargin'=>50);
  359. // $styleFirstRow = array('bgColor'=>'DD0026');
  360. // $phpWord->addTableStyle('table', $styleTable, $styleFirstRow);
  361. /* Note: any element you append to a document must reside inside of a Section. */
  362. // // Adding an empty Section to the document...
  363. // $section = $phpWord->addSection();
  364. // $table = $section->addTable('table');
  365. // $table->addRow(3);
  366. // $table->addCell(3300)->addText("Col 1");
  367. // $table->addCell(3300)->addText("Col 2");
  368. // $table->addCell(3300)
  369. // ->addTable('table')
  370. // ->addRow(2)->addCell(3300)
  371. // ->addText("Col 1");
  372. // ----------------
  373. // Add new section. All elements must be inside a section
  374. $section_style = array(
  375. 'orientation' => 'landscape',
  376. 'lineNumbering' => array(
  377. 'start' => 1
  378. ),
  379. );
  380. $section = $phpWord->addSection($section_style);
  381. // Table styles
  382. $table_styles = $tableStyle = array(
  383. 'borderColor' => 'd0d0d0',
  384. 'borderSize' => 6,
  385. 'cellMargin' => 500
  386. );
  387. $header_styles = array(
  388. 'bgColor' => 'FDFBE2',
  389. 'valign' => 'center',
  390. 'bold' => true,
  391. );
  392. $first_column_styles = array(
  393. 'bgColor' => 'F5F5F5',
  394. 'valign' => 'center',
  395. 'bold' => true,
  396. );
  397. $rowspan_restart = array('vMerge' => 'restart');
  398. $rowspan_continue = array('vMerge' => 'continue');
  399. foreach($plan->fypParts as $number => $mini_plan)
  400. {
  401. $table = $section->addTable('table'.$number, $table_styles);
  402. // Header row
  403. $table->addRow(700, array('exactHeight'=>true));
  404. $table->addCell(3300, $header_styles)->addText("Academic Year");
  405. $table->addCell(3300, $header_styles)->addText("Learning Outcome to be assessed");
  406. $table->addCell(3300, $header_styles)->addText("Learning Objectives");
  407. $table->addCell(3300, $header_styles)->addText("Courses to use for assessment");
  408. // Body
  409. foreach($mini_plan->fypPartOutcomes as $index => $outcome)
  410. {
  411. $table->addRow();
  412. // If outcome is the first, include multi-row year column
  413. if($index == 0)
  414. {
  415. $table->addCell(3300, array_merge($first_column_styles, $rowspan_restart))->addText($mini_plan->year_start.'-'.$mini_plan->year_end);
  416. }
  417. else
  418. {
  419. $table->addCell(3300, array_merge($first_column_styles, $rowspan_continue))->addText('');
  420. }
  421. // Outcome name
  422. $table->addCell(3300)->addText($outcome->outcome->name);
  423. // Objectives
  424. $cell = $table->addCell(3300);
  425. foreach(json_decode($outcome->objectives) as $objective)
  426. {
  427. $cell->addText('• '.$objective->text);
  428. }
  429. // Courses
  430. $cell = $table->addCell(3300);
  431. foreach(json_decode($outcome->courses) as $course)
  432. {
  433. $cell->addText(trim('• '.$course->code.$course->number.': '.$course->name));
  434. }
  435. }
  436. $section->addTextBreak(2);
  437. }
  438. // Saving the document as OOXML file...
  439. $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
  440. $objWriter->save('exports/'.$filename);
  441. return Response::download('exports/'.$filename);
  442. }
  443. catch(Exception $e)
  444. {
  445. Session::flash('status', 'danger');
  446. Session::flash('message', 'An error occurred while generating the document. Try again later or contact an administrator.');
  447. return Redirect::back();
  448. }
  449. }
  450. }