'.
+ 'Manual Check Requested on '.$this->date($s['Submission']['created']).
+ 'Delete
'.
+ '
';
+ }
+
+ if (empty($submissions)) {
+ $tpl .= '
'.
+ '
No manual checks requested.
'.
+ '
';
+ }
+
+ $tpl .= '
';
+ return $tpl;
+ }
+
+ public function getGraderTemplate($submissions) {
+ return 'TODO';
+ }
+
+ public function validateSubmission($inject, $submission) {
+ return true;
+ }
+
+ public function handleSubmission($inject, $submission) {
+ return json_encode([
+ 'completed' => false,
+ 'requested' => time(),
+ ]);
+ }
+}
diff --git a/app/Lib/InjectTypes/NoOpSubmission.php b/app/Lib/InjectTypes/NoOpSubmission.php
index ac8add7..b976988 100644
--- a/app/Lib/InjectTypes/NoOpSubmission.php
+++ b/app/Lib/InjectTypes/NoOpSubmission.php
@@ -2,34 +2,34 @@
namespace InjectTypes;
class NoOpSubmission extends InjectSubmissionBase {
- const TPL = '
'.
- '
%s
';
+ const TPL = '
'.
+ '
%s
';
- public function getID() {
- return 'noop';
- }
+ public function getID() {
+ return 'noop';
+ }
- public function getName() {
- return 'NoOp Submission';
- }
+ public function getName() {
+ return 'NoOp Submission';
+ }
- public function getTemplate() {
- return sprintf(self::TPL, 'No submission actions available for this inject.');
- }
+ public function getTemplate() {
+ return sprintf(self::TPL, 'No submission actions available for this inject.');
+ }
- public function getSubmittedTemplate($submissions) {
- return sprintf(self::TPL, 'No submissions.');
- }
+ public function getSubmittedTemplate($submissions) {
+ return sprintf(self::TPL, 'No submissions.');
+ }
- public function getGraderTemplate($submissions) {
- return 'This shouldn\'t happen.';
- }
+ public function getGraderTemplate($submissions) {
+ return 'This shouldn\'t happen.';
+ }
- public function validateSubmission($inject, $submission) {
- return false;
- }
+ public function validateSubmission($inject, $submission) {
+ return false;
+ }
- public function handleSubmission($inject, $submission) {
- throw new BadMethodCallException('No-Op submissions cannot be submitted');
- }
-}
\ No newline at end of file
+ public function handleSubmission($inject, $submission) {
+ throw new BadMethodCallException('No-Op submissions cannot be submitted');
+ }
+}
diff --git a/app/Lib/InjectTypes/TextSubmission.php b/app/Lib/InjectTypes/TextSubmission.php
index c8bdb1e..a735990 100644
--- a/app/Lib/InjectTypes/TextSubmission.php
+++ b/app/Lib/InjectTypes/TextSubmission.php
@@ -3,16 +3,16 @@
class TextSubmission extends InjectSubmissionBase {
- public function getID() {
- return 'text';
- }
+ public function getID() {
+ return 'text';
+ }
- public function getName() {
- return 'Text Submission';
- }
+ public function getName() {
+ return 'Text Submission';
+ }
- public function getTemplate() {
- return <<<'TEMPLATE'
+ public function getTemplate() {
+ return <<<'TEMPLATE'
@@ -23,43 +23,43 @@ public function getTemplate() {
TEMPLATE;
- }
+ }
- public function getSubmittedTemplate($submissions) {
- $tpl = '
';
+ public function getSubmittedTemplate($submissions) {
+ $tpl = '
'.
- 'Submission on '.$this->_date($s['Submission']['created']).
- 'Delete
'.
- '
'.nl2br($s['Submission']['data']).'
'.
- '
';
- }
+ $tpl .= '
'.
+ '
'.
+ 'Submission on '.$this->date($s['Submission']['created']).
+ 'Delete
'.
+ '
'.nl2br($s['Submission']['data']).'
'.
+ '
';
+ }
- if ( empty($submissions) ) {
- $tpl .= '
'.
- '
No submissions.
'.
- '
';
- }
+ if (empty($submissions)) {
+ $tpl .= '
'.
+ '
No submissions.
'.
+ '
';
+ }
- $tpl .= '
';
- return $tpl;
- }
+ $tpl .= '
';
+ return $tpl;
+ }
- public function getGraderTemplate($s) {
- return nl2br($s['Submission']['data']);
- }
+ public function getGraderTemplate($s) {
+ return nl2br($s['Submission']['data']);
+ }
- public function validateSubmission($inject, $submission) {
- return (isset($submission['content']) && !empty($submission['content']));
- }
+ public function validateSubmission($inject, $submission) {
+ return (isset($submission['content']) && !empty($submission['content']));
+ }
- public function handleSubmission($inject, $submission) {
- $clean_content = htmlspecialchars($submission['content']);
+ public function handleSubmission($inject, $submission) {
+ $clean_content = htmlspecialchars($submission['content']);
- return $clean_content;
- }
-}
\ No newline at end of file
+ return $clean_content;
+ }
+}
diff --git a/app/Model/Announcement.php b/app/Model/Announcement.php
index f2e2a54..ac3f2aa 100644
--- a/app/Model/Announcement.php
+++ b/app/Model/Announcement.php
@@ -6,18 +6,18 @@
*
*/
class Announcement extends AppModel {
-
- /**
- * Get's all active announcements
- *
- * @return array The active announcements
- */
- public function getAll() {
- return $this->find('all', [
- 'conditions' => [
- 'Announcement.active' => true,
- 'Announcement.expiration <=' => time(),
- ],
- ]);
- }
+
+ /**
+ * Get's all active announcements
+ *
+ * @return array The active announcements
+ */
+ public function getAll() {
+ return $this->find('all', [
+ 'conditions' => [
+ 'Announcement.active' => true,
+ 'Announcement.expiration <=' => time(),
+ ],
+ ]);
+ }
}
diff --git a/app/Model/AppModel.php b/app/Model/AppModel.php
index b0caff5..ca3e00e 100644
--- a/app/Model/AppModel.php
+++ b/app/Model/AppModel.php
@@ -38,13 +38,12 @@ class AppModel extends Model {
*
* @var int
*/
- public $recursive = -1;
+ public $recursive = -1;
/**
* behaviors used by model
*
* @var array
*/
- public $actsAs = ['Containable'];
-
+ public $actsAs = ['Containable'];
}
diff --git a/app/Model/Attachment.php b/app/Model/Attachment.php
index 31fdf82..930a0ae 100644
--- a/app/Model/Attachment.php
+++ b/app/Model/Attachment.php
@@ -6,5 +6,5 @@
*
*/
class Attachment extends AppModel {
-
+
}
diff --git a/app/Model/Config.php b/app/Model/Config.php
index 74a1a3e..1bb156b 100644
--- a/app/Model/Config.php
+++ b/app/Model/Config.php
@@ -6,64 +6,65 @@
*
*/
class Config extends AppModel {
- /**
- * Override the table for this model.
- * Otherwise, CakePHP would use "configs"
- */
- public $useTable = 'config';
- /**
- * Cache key template
- */
- const CACHE_KEY = 'Config.%s';
+ /**
+ * Override the table for this model.
+ * Otherwise, CakePHP would use "configs"
+ */
+ public $useTable = 'config';
- /**
- * After Save Model Hook
- *
- * This will clear the cache of the updated
- * item when a save is completed.
- */
- public function afterSave($created, $options=[]) {
- if ( !$created ) {
- Cache::delete(sprintf(self::CACHE_KEY, $this->data['Config']['key']));
- }
- }
+ /**
+ * Cache key template
+ */
+ const CACHE_KEY = 'Config.%s';
- /**
- * Get Config Key
- *
- * Will attempt to use the cache first, then
- * query the database.
- *
- * @param $key The config key to get
- * @return mixed The value
- */
- public function getKey($key) {
- $data = Cache::read(sprintf(self::CACHE_KEY, $key));
+ /**
+ * After Save Model Hook
+ *
+ * This will clear the cache of the updated
+ * item when a save is completed.
+ */
+ public function afterSave($created, $options = []) {
+ if (!$created) {
+ Cache::delete(sprintf(self::CACHE_KEY, $this->data['Config']['key']));
+ }
+ }
- if ( $data === false ) {
- $data = $this->find('first', [
- 'conditions' => [
- 'key' => $key,
- ],
- ]);
+ /**
+ * Get Config Key
+ *
+ * Will attempt to use the cache first, then
+ * query the database.
+ *
+ * @param $key The config key to get
+ * @return mixed The value
+ */
+ public function getKey($key) {
+ $data = Cache::read(sprintf(self::CACHE_KEY, $key));
- Cache::write(sprintf(self::CACHE_KEY, $key), $data);
- }
+ if ($data === false) {
+ $data = $this->find('first', [
+ 'conditions' => [
+ 'key' => $key,
+ ],
+ ]);
- return empty($data) ? '' : $data['Config']['value'];
- }
+ Cache::write(sprintf(self::CACHE_KEY, $key), $data);
+ }
- /**
- * Get Inject Types
- *
- * This is basically a proxy function to get the key
- * 'engine.inject_types'. It wraps json_decode around it
- * too, so the data is actually useful.
- *
- * @return array The configured inject types
- */
- public function getInjectTypes() {
- return json_decode($this->getKey('engine.inject_types'));
- }
+ return empty($data) ? '' : $data['Config']['value'];
+ }
+
+ /**
+ * Get Inject Types
+ *
+ * This is basically a proxy function to get the key
+ * 'engine.inject_types'. It wraps json_decode around it
+ * too, so the data is actually useful.
+ *
+ * @return array The configured inject types
+ */
+ public function getInjectTypes() {
+ return json_decode($this->getKey('engine.inject_types'));
+ }
}
diff --git a/app/Model/Group.php b/app/Model/Group.php
index 2548af7..39246ca 100644
--- a/app/Model/Group.php
+++ b/app/Model/Group.php
@@ -6,53 +6,55 @@
*
*/
class Group extends AppModel {
- public $actsAs = ['Tree'];
- public $hasMany = ['User'];
-
- /**
- * Gets an array of the groups
- *
- * @param $id The ID of the group you are getting groups for
- * @return array An array containing the group, and all higher groups
- */
- public function getGroups($id) {
- $groups = [];
- foreach ( $this->getPath($id) AS $p ) {
- $groups[] = $p['Group']['id'];
- }
-
- return $groups;
- }
-
- /**
- * Gets the children of a group
- *
- * @param $id The ID of the group you are getting children for
- * @return array An array containing the children
- */
- public function getChildren($id) {
- $children = [];
- foreach ( $this->children($id) AS $c ) {
- $children[] = $c['Group']['id'];
- }
-
- return $children;
- }
-
- /**
- * Gets the 'pretty' version of the group
- * Example: Staff/White Team
- *
- * @param $id The ID of the group you are getting the path for
- * @param $separator The separator you wish to use. Defaults to "/"
- * @return string The pretty path
- */
- public function getGroupPath($id, $separator='/') {
- $path = [];
- foreach ( $this->getPath($id) AS $p ) {
- $path[] = $p['Group']['name'];
- }
-
- return implode($separator, $path);
- }
+
+ public $actsAs = ['Tree'];
+
+ public $hasMany = ['User'];
+
+ /**
+ * Gets an array of the groups
+ *
+ * @param $id The ID of the group you are getting groups for
+ * @return array An array containing the group, and all higher groups
+ */
+ public function getGroups($id) {
+ $groups = [];
+ foreach ($this->getPath($id) as $p) {
+ $groups[] = $p['Group']['id'];
+ }
+
+ return $groups;
+ }
+
+ /**
+ * Gets the children of a group
+ *
+ * @param $id The ID of the group you are getting children for
+ * @return array An array containing the children
+ */
+ public function getChildren($id) {
+ $children = [];
+ foreach ($this->children($id) as $c) {
+ $children[] = $c['Group']['id'];
+ }
+
+ return $children;
+ }
+
+ /**
+ * Gets the 'pretty' version of the group
+ * Example: Staff/White Team
+ *
+ * @param $id The ID of the group you are getting the path for
+ * @param $separator The separator you wish to use. Defaults to "/"
+ * @return string The pretty path
+ */
+ public function getGroupPath($id, $separator = '/') {
+ $path = [];
+ foreach ($this->getPath($id) as $p) {
+ $path[] = $p['Group']['name'];
+ }
+
+ return implode($separator, $path);
+ }
}
diff --git a/app/Model/Hint.php b/app/Model/Hint.php
index 0d7a2e6..58b9554 100644
--- a/app/Model/Hint.php
+++ b/app/Model/Hint.php
@@ -6,51 +6,55 @@
*
*/
class Hint extends AppModel {
- public $belongsTo = ['Inject'];
- public $recursive = 1;
-
- /**
- * All the hints (and which are unlocked)
- *
- * @param $inject_id Inject ID you are getting hints for
- * @param $group_id The Group ID you are getting hints for
- * @return array An array containing the hints
- */
- public function getHints($inject_id, $group_id) {
- $data = $this->find('all', [
- 'fields' => [
- 'Hint.id', 'Hint.title', 'Hint.content', 'Hint.parent_id',
- 'Hint.time_wait', 'Hint.cost', 'UsedHint.time'
- ],
- 'joins' => [
- [
- 'table' => 'used_hints',
- 'alias' => 'UsedHint',
- 'type' => 'left',
- 'conditions' => [
- 'UsedHint.hint_id = Hint.id',
- 'UsedHint.group_id' => $group_id
- ]
- ]
- ],
- 'conditions' => [
- 'Hint.inject_id' => $inject_id,
- ]
- ]);
-
- // Unlocked hints lookup table
- $unlockedHints = [];
- foreach ( $data AS $d ) {
- $unlockedHints[$d['Hint']['id']] = (!empty($d['UsedHint']['time']));
- }
-
- // Add some helper data like if it's unlocked,
- // or a dependency is met
- foreach ( $data AS &$d ) {
- $d['Hint']['unlocked'] = $unlockedHints[$d['Hint']['id']];
- $d['Hint']['dependency_met'] = ($d['Hint']['parent_id'] != NULL) ? $unlockedHints[$d['Hint']['parent_id']] : true;
- }
-
- return $data;
- }
+
+ public $belongsTo = ['Inject'];
+
+ public $recursive = 1;
+
+ /**
+ * All the hints (and which are unlocked)
+ *
+ * @param $inject_id Inject ID you are getting hints for
+ * @param $group_id The Group ID you are getting hints for
+ * @return array An array containing the hints
+ */
+ public function getHints($inject_id, $group_id) {
+ $data = $this->find('all', [
+ 'fields' => [
+ 'Hint.id', 'Hint.title', 'Hint.content', 'Hint.parent_id',
+ 'Hint.time_wait', 'Hint.cost', 'UsedHint.time'
+ ],
+ 'joins' => [
+ [
+ 'table' => 'used_hints',
+ 'alias' => 'UsedHint',
+ 'type' => 'left',
+ 'conditions' => [
+ 'UsedHint.hint_id = Hint.id',
+ 'UsedHint.group_id' => $group_id
+ ]
+ ]
+ ],
+ 'conditions' => [
+ 'Hint.inject_id' => $inject_id,
+ ]
+ ]);
+
+ // Unlocked hints lookup table
+ $unlockedHints = [];
+ foreach ($data as $d) {
+ $unlockedHints[$d['Hint']['id']] = (!empty($d['UsedHint']['time']));
+ }
+
+ // Add some helper data like if it's unlocked,
+ // or a dependency is met
+ foreach ($data as &$d) {
+ $dependency_met = ($d['Hint']['parent_id'] != null) ? $unlockedHints[$d['Hint']['parent_id']] : true;
+
+ $d['Hint']['unlocked'] = $unlockedHints[$d['Hint']['id']];
+ $d['Hint']['dependency_met'] = $dependency_met;
+ }
+
+ return $data;
+ }
}
diff --git a/app/Model/Inject.php b/app/Model/Inject.php
index 1372ef1..56b62da 100644
--- a/app/Model/Inject.php
+++ b/app/Model/Inject.php
@@ -6,6 +6,8 @@
*
*/
class Inject extends AppModel {
- public $hasMany = ['Attachment'];
- public $recursive = 1;
+
+ public $hasMany = ['Attachment'];
+
+ public $recursive = 1;
}
diff --git a/app/Model/Log.php b/app/Model/Log.php
index 48f1bf2..7ead536 100644
--- a/app/Model/Log.php
+++ b/app/Model/Log.php
@@ -6,6 +6,8 @@
*
*/
class Log extends AppModel {
- public $belongsTo = ['User'];
- public $recursive = 2;
+
+ public $belongsTo = ['User'];
+
+ public $recursive = 2;
}
diff --git a/app/Model/Schedule.php b/app/Model/Schedule.php
index 963e178..c053017 100644
--- a/app/Model/Schedule.php
+++ b/app/Model/Schedule.php
@@ -7,303 +7,306 @@
*
*/
class Schedule extends AppModel {
- public $belongsTo = ['Inject'];
- public $recursive = 2;
-
- /**
- * Get Active Injects (RAW)
- *
- * Okay, this is the monster in the room.
- * I'm sorry. It'll grab injects based on
- * if they're active, AND their start time
- * has passed
- *
- * @param $groups The groups to check for injects in
- * @param $onlyActive Only include injects that are active
- * @return array All the active injects
- */
- public function getInjectsRaw($groups, $onlyActive=true) {
- $now = time();
- $conditions = ['Schedule.group_id' => $groups];
-
- if ( $onlyActive ) {
- $conditions += [
- 'Schedule.active' => true,
- 'OR' => [
- [
- 'Schedule.fuzzy' => false,
- 'Schedule.start <=' => $now,
- ],
- [
- 'Schedule.fuzzy' => true,
- 'Schedule.start <=' => ($now - COMPETITION_START)
- ],
- [
- 'Schedule.start' => 0,
- ],
- ],
- ];
- }
-
- $injects = $this->find('all', [
- 'conditions' => $conditions,
-
- // Ordering is hard. Sorry.
- // We'll do base ordering on the order.
- // Following that, sequence number,
- // and then end times that aren't
- // forever.
- 'order' => [
- 'Schedule.order ASC',
- 'Inject.sequence ASC',
- '(Schedule.end > 0) DESC',
- 'Schedule.end ASC',
- ],
- ]);
-
- // Now remove any duplicates
- $cache = [];
- foreach ( $injects AS $k => $v ) {
- $injectID = $v['Inject']['id'];
- $newEnd = $v['Schedule']['end'];
-
- if ( !isset($cache[$injectID]) ) {
- $cache[$injectID] = [
- 'end' => $newEnd,
- 'key' => $k,
- ];
-
- continue;
- }
-
- $oldEnd = $cache[$injectID]['end'];
- $oldKey = $cache[$injectID]['key'];
-
- // So we're going to prefer an inject
- // with the latest end time
- if ( ($newEnd == 0 && $oldEnd > 0) || ($oldEnd > 0 && $newEnd > $oldEnd) ) {
- unset($injects[$oldKey]);
-
- $cache[$injectID] = [
- 'end' => $newEnd,
- 'key' => $k,
- ];
- } else {
- unset($injects[$k]);
- }
- }
-
- return $injects;
- }
-
- /**
- * Get (an) Inject (RAW)
- *
- * A little nicer than getInjects...but still we have dragons :(
- *
- * @param $id The schedule ID of the inject
- * @param $groups The groups the current user is in
- * @param $show_expired [Optional] Still return the inject, even
- * if it's expired
- * @return array The inject (if it's active/exists)
- */
- public function getInjectRaw($id, $groups, $show_expired=false) {
- $conditions = [
- 'Schedule.id' => $id,
- 'Schedule.group_id' => $groups,
- 'Schedule.active' => true,
- ];
-
- if ( !$show_expired ) {
- $now = time();
-
- $conditions['OR'] = [
- [
- 'Schedule.fuzzy' => false,
- 'Schedule.start <=' => $now,
- ],
- [
- 'Schedule.fuzzy' => true,
- 'Schedule.start <=' => ($now - COMPETITION_START)
- ],
- [
- 'Schedule.start' => 0,
- ]
- ];
- }
-
- return $this->find('first', [
- 'conditions' => $conditions,
- ]);
- }
-
- /**
- * Get Injects (and wrap them)
- *
- * This function uses the raw data from
- * `getInjectsRaw` and wraps every inject
- * inside an InjectAbstraction class
- *
- * @param $groups The groups to check for injects in
- * @param $onlyActive Only include injects that are active
- * @return array All the active injects
- */
- public function getInjects($groups, $onlyActive=true) {
- $rtn = [];
-
- foreach ( $this->getInjectsRaw($groups, $onlyActive) AS $inject ) {
- $submissionCount = ClassRegistry::init('Submission')->getCount($inject['Inject']['id'], $groups);
- $rtn[] = new InjectAbstraction($inject, $submissionCount);
- }
-
- return $rtn;
- }
-
- /**
- * Get (an) Inject (and wrap it)
- *
- * This function uses the raw data from
- * `getInjectRaw` and wraps the inject
- * inside an InjectAbstraction class
- *
- * @param $id The schedule ID of the inject
- * @param $groups The groups the current user is in
- * @param $show_expired [Optional] Still return the inject, even
- * if it's expired
- * @return array The inject (if it's active/exists)
- */
- public function getInject($id, $groups, $show_expired=false) {
- $inject = $this->getInjectRaw($id, $groups, $show_expired);
-
- if ( !empty($inject) ) {
- $submissionCount = ClassRegistry::init('Submission')->getCount($inject['Inject']['id'], $groups);
- $inject = new InjectAbstraction($inject, $submissionCount);
- }
-
- return $inject;
- }
-
- /**
- * Get recently expired injects
- *
- * This function uses the raw data from
- * `getInjectsRaw` and wraps every inject
- * inside an InjectAbstraction class
- *
- * @param $groups The groups to check for injects in
- * @param $howRecent How recent the injects have expired
- * @return array All the active injects
- */
- public function getRecentExpired($groups, $howRecent=(90 * 60)) {
- $now = time();
- $nowCS = ($now - COMPETITION_START);
-
- $data = $this->find('all', [
- 'conditions' => [
- 'Schedule.active' => true,
- 'Schedule.group_id' => $groups,
- 'Schedule.end !=' => 0,
- 'OR' => [
- [
- 'Schedule.fuzzy' => true,
- 'Schedule.end <' => $nowCS,
- 'Schedule.end >=' => ($nowCS - $howRecent),
- ],
- [
- 'Schedule.fuzzy' => false,
- 'Schedule.end <' => $now,
- 'Schedule.end >=' => ($now - $howRecent),
- ]
- ],
- ],
- ]);
-
- $rtn = [];
- foreach ( $data AS $d ) {
- $rtn[] = new InjectAbstraction($d, 0);
- }
-
- return $rtn;
- }
-
- /**
- * Get _ALL_ Schedules
- *
- * @param $activeOnly [Optional] Only show active
- * @return array All the [active] schedules
- */
- public function getAllSchedules($activeOnly=true) {
- $this->bindModel([
- 'belongsTo' => ['Group'],
- ]);
-
- $data = $this->find('all', [
- 'conditions' => [
- 'Schedule.active' => ($activeOnly ? true : [true,false]),
- ],
- ]);
-
- $rtn = [];
- foreach ( $data AS $d ) {
- $rtn[] = new InjectAbstraction($d, 0);
- }
-
- return $rtn;
- }
-
- /**
- * Get Schedule Bounds
- *
- * Returns an array containing the min and
- * max times for the schedule list
- *
- * @param $round Should we round the times
- * @return array The min/max times
- */
- public function getScheduleBounds($round=true) {
- $this->virtualFields['min'] = 'IF(Schedule.fuzzy = 1, Schedule.start + '.COMPETITION_START.', Schedule.start)';
- $this->virtualFields['max'] = 'IF(Schedule.fuzzy = 1 AND Schedule.end > 0, Schedule.end + '.COMPETITION_START.', Schedule.end)';
-
- $min = $this->find('first', [
- 'fields' => [
- 'Schedule.min'
- ],
- 'conditions' => [
- 'Schedule.active' => true,
- ],
- 'order' => [
- 'Schedule.min ASC',
- ],
- ]);
-
- $max = $this->find('first', [
- 'fields' => [
- 'Schedule.max'
- ],
- 'conditions' => [
- 'Schedule.active' => true,
- ],
- 'order' => [
- 'Schedule.max DESC',
- ],
- ]);
-
- $bounds = [
- 'min' => $min['Schedule']['min'],
- 'max' => $max['Schedule']['max'],
- ];
-
- // Now round them
- if ( $round ) {
- $min = DateTime::createFromFormat('Y-m-d H:00:00', date('Y-m-d H:00:00', $bounds['min']));
- $max = DateTime::createFromFormat('Y-m-d H:00:00', date('Y-m-d H:00:00', $bounds['max']));
- $min->modify('-1 hour');
- $max->modify('+1 hour');
-
- $bounds['min'] = $min->getTimestamp();
- $bounds['max'] = $max->getTimestamp();
- }
-
- return $bounds;
- }
+
+ public $belongsTo = ['Inject'];
+
+ public $recursive = 2;
+
+ /**
+ * Get Active Injects (RAW)
+ *
+ * Okay, this is the monster in the room.
+ * I'm sorry. It'll grab injects based on
+ * if they're active, AND their start time
+ * has passed
+ *
+ * @param $groups The groups to check for injects in
+ * @param $onlyActive Only include injects that are active
+ * @return array All the active injects
+ */
+ public function getInjectsRaw($groups, $onlyActive = true) {
+ $now = time();
+ $conditions = ['Schedule.group_id' => $groups];
+
+ if ($onlyActive) {
+ $conditions += [
+ 'Schedule.active' => true,
+ 'OR' => [
+ [
+ 'Schedule.fuzzy' => false,
+ 'Schedule.start <=' => $now,
+ ],
+ [
+ 'Schedule.fuzzy' => true,
+ 'Schedule.start <=' => ($now - COMPETITION_START)
+ ],
+ [
+ 'Schedule.start' => 0,
+ ],
+ ],
+ ];
+ }
+
+ $injects = $this->find('all', [
+ 'conditions' => $conditions,
+
+ // Ordering is hard. Sorry.
+ // We'll do base ordering on the order.
+ // Following that, sequence number,
+ // and then end times that aren't
+ // forever.
+ 'order' => [
+ 'Schedule.order ASC',
+ 'Inject.sequence ASC',
+ '(Schedule.end > 0) DESC',
+ 'Schedule.end ASC',
+ ],
+ ]);
+
+ // Now remove any duplicates
+ $cache = [];
+ foreach ($injects as $k => $v) {
+ $injectID = $v['Inject']['id'];
+ $newEnd = $v['Schedule']['end'];
+
+ if (!isset($cache[$injectID])) {
+ $cache[$injectID] = [
+ 'end' => $newEnd,
+ 'key' => $k,
+ ];
+
+ continue;
+ }
+
+ $oldEnd = $cache[$injectID]['end'];
+ $oldKey = $cache[$injectID]['key'];
+
+ // So we're going to prefer an inject
+ // with the latest end time
+ if (($newEnd == 0 && $oldEnd > 0) || ($oldEnd > 0 && $newEnd > $oldEnd)) {
+ unset($injects[$oldKey]);
+
+ $cache[$injectID] = [
+ 'end' => $newEnd,
+ 'key' => $k,
+ ];
+ } else {
+ unset($injects[$k]);
+ }
+ }
+
+ return $injects;
+ }
+
+ /**
+ * Get (an) Inject (RAW)
+ *
+ * A little nicer than getInjects...but still we have dragons :(
+ *
+ * @param $id The schedule ID of the inject
+ * @param $groups The groups the current user is in
+ * @param $show_expired [Optional] Still return the inject, even
+ * if it's expired
+ * @return array The inject (if it's active/exists)
+ */
+ public function getInjectRaw($id, $groups, $show_expired = false) {
+ $conditions = [
+ 'Schedule.id' => $id,
+ 'Schedule.group_id' => $groups,
+ 'Schedule.active' => true,
+ ];
+
+ if (!$show_expired) {
+ $now = time();
+
+ $conditions['OR'] = [
+ [
+ 'Schedule.fuzzy' => false,
+ 'Schedule.start <=' => $now,
+ ],
+ [
+ 'Schedule.fuzzy' => true,
+ 'Schedule.start <=' => ($now - COMPETITION_START)
+ ],
+ [
+ 'Schedule.start' => 0,
+ ]
+ ];
+ }
+
+ return $this->find('first', [
+ 'conditions' => $conditions,
+ ]);
+ }
+
+ /**
+ * Get Injects (and wrap them)
+ *
+ * This function uses the raw data from
+ * `getInjectsRaw` and wraps every inject
+ * inside an InjectAbstraction class
+ *
+ * @param $groups The groups to check for injects in
+ * @param $onlyActive Only include injects that are active
+ * @return array All the active injects
+ */
+ public function getInjects($groups, $onlyActive = true) {
+ $rtn = [];
+
+ foreach ($this->getInjectsRaw($groups, $onlyActive) as $inject) {
+ $submissionCount = ClassRegistry::init('Submission')->getCount($inject['Inject']['id'], $groups);
+ $rtn[] = new InjectAbstraction($inject, $submissionCount);
+ }
+
+ return $rtn;
+ }
+
+ /**
+ * Get (an) Inject (and wrap it)
+ *
+ * This function uses the raw data from
+ * `getInjectRaw` and wraps the inject
+ * inside an InjectAbstraction class
+ *
+ * @param $id The schedule ID of the inject
+ * @param $groups The groups the current user is in
+ * @param $show_expired [Optional] Still return the inject, even
+ * if it's expired
+ * @return array The inject (if it's active/exists)
+ */
+ public function getInject($id, $groups, $show_expired = false) {
+ $inject = $this->getInjectRaw($id, $groups, $show_expired);
+
+ if (!empty($inject)) {
+ $submissionCount = ClassRegistry::init('Submission')->getCount($inject['Inject']['id'], $groups);
+ $inject = new InjectAbstraction($inject, $submissionCount);
+ }
+
+ return $inject;
+ }
+
+ /**
+ * Get recently expired injects
+ *
+ * This function uses the raw data from
+ * `getInjectsRaw` and wraps every inject
+ * inside an InjectAbstraction class
+ *
+ * @param $groups The groups to check for injects in
+ * @param $howRecent How recent the injects have expired
+ * @return array All the active injects
+ */
+ public function getRecentExpired($groups, $howRecent = (90 * 60)) {
+ $now = time();
+ $nowCS = ($now - COMPETITION_START);
+
+ $data = $this->find('all', [
+ 'conditions' => [
+ 'Schedule.active' => true,
+ 'Schedule.group_id' => $groups,
+ 'Schedule.end !=' => 0,
+ 'OR' => [
+ [
+ 'Schedule.fuzzy' => true,
+ 'Schedule.end <' => $nowCS,
+ 'Schedule.end >=' => ($nowCS - $howRecent),
+ ],
+ [
+ 'Schedule.fuzzy' => false,
+ 'Schedule.end <' => $now,
+ 'Schedule.end >=' => ($now - $howRecent),
+ ]
+ ],
+ ],
+ ]);
+
+ $rtn = [];
+ foreach ($data as $d) {
+ $rtn[] = new InjectAbstraction($d, 0);
+ }
+
+ return $rtn;
+ }
+
+ /**
+ * Get _ALL_ Schedules
+ *
+ * @param $activeOnly [Optional] Only show active
+ * @return array All the [active] schedules
+ */
+ public function getAllSchedules($activeOnly = true) {
+ $this->bindModel([
+ 'belongsTo' => ['Group'],
+ ]);
+
+ $data = $this->find('all', [
+ 'conditions' => [
+ 'Schedule.active' => ($activeOnly ? true : [true,false]),
+ ],
+ ]);
+
+ $rtn = [];
+ foreach ($data as $d) {
+ $rtn[] = new InjectAbstraction($d, 0);
+ }
+
+ return $rtn;
+ }
+
+ /**
+ * Get Schedule Bounds
+ *
+ * Returns an array containing the min and
+ * max times for the schedule list
+ *
+ * @param $round Should we round the times
+ * @return array The min/max times
+ */
+ public function getScheduleBounds($round = true) {
+ $this->virtualFields['min'] = 'IF(Schedule.fuzzy = 1, Schedule.start + '.COMPETITION_START.', Schedule.start)';
+ $this->virtualFields['max'] = 'IF(Schedule.fuzzy = 1 AND Schedule.end > 0, '.
+ 'Schedule.end + '.COMPETITION_START.', Schedule.end)';
+
+ $min = $this->find('first', [
+ 'fields' => [
+ 'Schedule.min'
+ ],
+ 'conditions' => [
+ 'Schedule.active' => true,
+ ],
+ 'order' => [
+ 'Schedule.min ASC',
+ ],
+ ]);
+
+ $max = $this->find('first', [
+ 'fields' => [
+ 'Schedule.max'
+ ],
+ 'conditions' => [
+ 'Schedule.active' => true,
+ ],
+ 'order' => [
+ 'Schedule.max DESC',
+ ],
+ ]);
+
+ $bounds = [
+ 'min' => $min['Schedule']['min'],
+ 'max' => $max['Schedule']['max'],
+ ];
+
+ // Now round them
+ if ($round) {
+ $min = DateTime::createFromFormat('Y-m-d H:00:00', date('Y-m-d H:00:00', $bounds['min']));
+ $max = DateTime::createFromFormat('Y-m-d H:00:00', date('Y-m-d H:00:00', $bounds['max']));
+ $min->modify('-1 hour');
+ $max->modify('+1 hour');
+
+ $bounds['min'] = $min->getTimestamp();
+ $bounds['max'] = $max->getTimestamp();
+ }
+
+ return $bounds;
+ }
}
diff --git a/app/Model/Submission.php b/app/Model/Submission.php
index 99987fe..0aac564 100644
--- a/app/Model/Submission.php
+++ b/app/Model/Submission.php
@@ -6,207 +6,210 @@
*
*/
class Submission extends AppModel {
- public $belongsTo = ['Inject', 'User', 'Group'];
- public $hasOne = ['Grade'];
- public $recursive = 1;
-
- /**
- * Get All Ungraded-Submissions
- *
- * This retrieves the submissions done by
- * a group that is ungraded.
- *
- * @return array The submissions that are ungraded.
- */
- public function getAllUngradedSubmissions() {
- return $this->find('all', [
- 'fields' => [
- 'Submission.id', 'Submission.created', 'Submission.deleted',
- 'Inject.id', 'Inject.title', 'Inject.sequence', 'Inject.type',
- 'User.username', 'Group.name', 'Group.team_number',
- 'Grade.created', 'Grade.grade', 'Grade.comments',
- 'Grader.username',
- ],
-
- 'joins' => [
- [
- 'table' => 'users',
- 'alias' => 'Grader',
- 'type' => 'LEFT',
- 'conditions' => [
- 'Grader.id = Grade.grader_id',
- ],
- ]
- ],
-
- 'conditions' => [
- 'Grade.created IS NULL',
- 'Submission.deleted' => false,
- ],
-
- 'order' => [
- 'Grade.created DESC',
- 'Submission.created DESC',
- ],
- ]);
- }
-
- /**
- * Get All Submissions
- *
- * This retrieves the submissions done by
- * a group.
- *
- * @param $group The group ID
- * @param $noDeleted Discard deleted submissions
- * @return array The submissions done by this group
- */
- public function getAllSubmissions($group=false, $noDeleted=false) {
- $conditions = [];
-
- if ( $group !== false ) {
- $conditions['Group.id'] = $group;
- }
- if ( $noDeleted ) {
- $conditions['Submission.deleted'] = false;
- }
-
- return $this->find('all', [
- 'fields' => [
- 'Submission.id', 'Submission.created', 'Submission.deleted',
- 'Inject.id', 'Inject.title', 'Inject.sequence', 'Inject.type',
- 'User.username', 'Group.id', 'Group.name', 'Group.team_number',
- 'Grade.created', 'Grade.grade', 'Grade.comments',
- 'Grader.username',
- ],
-
- 'joins' => [
- [
- 'table' => 'users',
- 'alias' => 'Grader',
- 'type' => 'LEFT',
- 'conditions' => [
- 'Grader.id = Grade.grader_id',
- ],
- ]
- ],
-
- 'conditions' => $conditions,
-
- 'order' => [
- 'Grade.created DESC',
- 'Submission.created DESC',
- ],
- ]);
- }
-
- /**
- * Get Submission
- *
- * This retrieves the submission done by
- * a group.
- *
- * @param $sid The submission ID
- * @return array The submissions done by this group
- */
- public function getSubmission($sid, $group=false, $noDeleted=false) {
- $conditions = [
- 'Submission.id' => $sid,
- ];
-
- if ( $group !== false ) {
- $conditions['Group.id'] = $group;
- }
- if ( $noDeleted ) {
- $conditions['Submission.deleted'] = false;
- }
-
- return $this->find('first', [
- 'fields' => [
- 'Submission.*', 'Inject.*', 'User.*',
- 'Group.*', 'Grade.*', 'Grader.*',
- ],
-
- 'joins' => [
- [
- 'table' => 'users',
- 'alias' => 'Grader',
- 'type' => 'LEFT',
- 'conditions' => [
- 'Grader.id = Grade.grader_id',
- ],
- ]
- ],
-
- 'conditions' => $conditions,
- ]);
- }
-
- /**
- * Get Submissions
- *
- * This retrieves the the submissions for
- * a specific inject done by a group. This
- * will filter out deleted submissions, too.
- *
- * @param $id The inject ID
- * @param $group The group ID
- * @return array The submissions done by this group
- * for this inject
- */
- public function getSubmissions($id, $group) {
- return $this->find('all', [
- 'conditions' => [
- 'Inject.id' => $id,
- 'Group.id' => $group,
- 'Submission.deleted' => false,
- ],
- ]);
- }
-
- /**
- * Get Submissions Count
- *
- * Basically `getSubmissions`
- *
- * @param $id The inject ID
- * @param $group The group ID
- * @return int The number of the submissions done by
- * this group for this inject
- */
- public function getCount($id, $group) {
- return $this->find('count', [
- 'conditions' => [
- 'Inject.id' => $id,
- 'Group.id' => $group,
- 'Submission.deleted' => false,
- ],
- ]);
- }
-
- /**
- * Get Grade Totals
- *
- * @param $groups The groups you wish to get grades for
- * @return array The grades for all the groups
- */
- public function getGrades($groups) {
- $this->virtualFields['total_grade'] = 'SUM(Grade.grade)';
-
- return $this->find('all', [
- 'fields' => [
- 'Submission.total_grade', 'Group.name', 'Group.team_number',
- ],
- 'conditions' => [
- 'Group.id' => $groups,
- 'Submission.deleted' => false,
- ],
- 'group' => [
- 'Group.id'
- ],
- 'order' => [
- 'Submission.total_grade DESC',
- ],
- ]);
- }
+
+ public $belongsTo = ['Inject', 'User', 'Group'];
+
+ public $hasOne = ['Grade'];
+
+ public $recursive = 1;
+
+ /**
+ * Get All Ungraded-Submissions
+ *
+ * This retrieves the submissions done by
+ * a group that is ungraded.
+ *
+ * @return array The submissions that are ungraded.
+ */
+ public function getAllUngradedSubmissions() {
+ return $this->find('all', [
+ 'fields' => [
+ 'Submission.id', 'Submission.created', 'Submission.deleted',
+ 'Inject.id', 'Inject.title', 'Inject.sequence', 'Inject.type',
+ 'User.username', 'Group.name', 'Group.team_number',
+ 'Grade.created', 'Grade.grade', 'Grade.comments',
+ 'Grader.username',
+ ],
+
+ 'joins' => [
+ [
+ 'table' => 'users',
+ 'alias' => 'Grader',
+ 'type' => 'LEFT',
+ 'conditions' => [
+ 'Grader.id = Grade.grader_id',
+ ],
+ ]
+ ],
+
+ 'conditions' => [
+ 'Grade.created IS NULL',
+ 'Submission.deleted' => false,
+ ],
+
+ 'order' => [
+ 'Grade.created DESC',
+ 'Submission.created DESC',
+ ],
+ ]);
+ }
+
+ /**
+ * Get All Submissions
+ *
+ * This retrieves the submissions done by
+ * a group.
+ *
+ * @param $group The group ID
+ * @param $noDeleted Discard deleted submissions
+ * @return array The submissions done by this group
+ */
+ public function getAllSubmissions($group = false, $noDeleted = false) {
+ $conditions = [];
+
+ if ($group !== false) {
+ $conditions['Group.id'] = $group;
+ }
+ if ($noDeleted) {
+ $conditions['Submission.deleted'] = false;
+ }
+
+ return $this->find('all', [
+ 'fields' => [
+ 'Submission.id', 'Submission.created', 'Submission.deleted',
+ 'Inject.id', 'Inject.title', 'Inject.sequence', 'Inject.type',
+ 'User.username', 'Group.id', 'Group.name', 'Group.team_number',
+ 'Grade.created', 'Grade.grade', 'Grade.comments',
+ 'Grader.username',
+ ],
+
+ 'joins' => [
+ [
+ 'table' => 'users',
+ 'alias' => 'Grader',
+ 'type' => 'LEFT',
+ 'conditions' => [
+ 'Grader.id = Grade.grader_id',
+ ],
+ ]
+ ],
+
+ 'conditions' => $conditions,
+
+ 'order' => [
+ 'Grade.created DESC',
+ 'Submission.created DESC',
+ ],
+ ]);
+ }
+
+ /**
+ * Get Submission
+ *
+ * This retrieves the submission done by
+ * a group.
+ *
+ * @param $sid The submission ID
+ * @return array The submissions done by this group
+ */
+ public function getSubmission($sid, $group = false, $noDeleted = false) {
+ $conditions = [
+ 'Submission.id' => $sid,
+ ];
+
+ if ($group !== false) {
+ $conditions['Group.id'] = $group;
+ }
+ if ($noDeleted) {
+ $conditions['Submission.deleted'] = false;
+ }
+
+ return $this->find('first', [
+ 'fields' => [
+ 'Submission.*', 'Inject.*', 'User.*',
+ 'Group.*', 'Grade.*', 'Grader.*',
+ ],
+
+ 'joins' => [
+ [
+ 'table' => 'users',
+ 'alias' => 'Grader',
+ 'type' => 'LEFT',
+ 'conditions' => [
+ 'Grader.id = Grade.grader_id',
+ ],
+ ]
+ ],
+
+ 'conditions' => $conditions,
+ ]);
+ }
+
+ /**
+ * Get Submissions
+ *
+ * This retrieves the the submissions for
+ * a specific inject done by a group. This
+ * will filter out deleted submissions, too.
+ *
+ * @param $id The inject ID
+ * @param $group The group ID
+ * @return array The submissions done by this group
+ * for this inject
+ */
+ public function getSubmissions($id, $group) {
+ return $this->find('all', [
+ 'conditions' => [
+ 'Inject.id' => $id,
+ 'Group.id' => $group,
+ 'Submission.deleted' => false,
+ ],
+ ]);
+ }
+
+ /**
+ * Get Submissions Count
+ *
+ * Basically `getSubmissions`
+ *
+ * @param $id The inject ID
+ * @param $group The group ID
+ * @return int The number of the submissions done by
+ * this group for this inject
+ */
+ public function getCount($id, $group) {
+ return $this->find('count', [
+ 'conditions' => [
+ 'Inject.id' => $id,
+ 'Group.id' => $group,
+ 'Submission.deleted' => false,
+ ],
+ ]);
+ }
+
+ /**
+ * Get Grade Totals
+ *
+ * @param $groups The groups you wish to get grades for
+ * @return array The grades for all the groups
+ */
+ public function getGrades($groups) {
+ $this->virtualFields['total_grade'] = 'SUM(Grade.grade)';
+
+ return $this->find('all', [
+ 'fields' => [
+ 'Submission.total_grade', 'Group.name', 'Group.team_number',
+ ],
+ 'conditions' => [
+ 'Group.id' => $groups,
+ 'Submission.deleted' => false,
+ ],
+ 'group' => [
+ 'Group.id'
+ ],
+ 'order' => [
+ 'Submission.total_grade DESC',
+ ],
+ ]);
+ }
}
diff --git a/app/Model/UsedHint.php b/app/Model/UsedHint.php
index 144caa7..8ae3434 100644
--- a/app/Model/UsedHint.php
+++ b/app/Model/UsedHint.php
@@ -6,6 +6,8 @@
*
*/
class UsedHint extends AppModel {
- public $belongsTo = ['Hint'];
- public $recursive = 1;
+
+ public $belongsTo = ['Hint'];
+
+ public $recursive = 1;
}
diff --git a/app/Model/User.php b/app/Model/User.php
index 13ae4d0..709510c 100644
--- a/app/Model/User.php
+++ b/app/Model/User.php
@@ -7,21 +7,23 @@
*
*/
class User extends AppModel {
- public $belongsTo = ['Group'];
- public $recursive = 1;
- /**
- * Before Save Hook
- *
- * Ensures if the "password" key is set, we hash it correctly (using bcrypt)
- * @param $options Unknown
- * @return boolean If the operation we're doing worked
- */
- public function beforeSave($options = array()) {
- if ( !empty($this->data['User']['password']) ) {
- $this->data['User']['password'] = Security::hash($this->data['User']['password'], 'blowfish');
- }
+ public $belongsTo = ['Group'];
- return true;
- }
+ public $recursive = 1;
+
+ /**
+ * Before Save Hook
+ *
+ * Ensures if the "password" key is set, we hash it correctly (using bcrypt)
+ * @param $options Unknown
+ * @return boolean If the operation we're doing worked
+ */
+ public function beforeSave($options = []) {
+ if (!empty($this->data['User']['password'])) {
+ $this->data['User']['password'] = Security::hash($this->data['User']['password'], 'blowfish');
+ }
+
+ return true;
+ }
}
diff --git a/app/Plugin/Admin/Controller/AdminAppController.php b/app/Plugin/Admin/Controller/AdminAppController.php
index 2f265a2..8f0b459 100644
--- a/app/Plugin/Admin/Controller/AdminAppController.php
+++ b/app/Plugin/Admin/Controller/AdminAppController.php
@@ -2,13 +2,13 @@
App::uses('AppController', 'Controller');
class AdminAppController extends AppController {
- public function beforeFilter() {
- parent::beforeFilter();
+ public function beforeFilter() {
+ parent::beforeFilter();
- // We're doing a backend request, require backend access
- $this->Auth->protect(env('GROUP_ADMINS'));
+ // We're doing a backend request, require backend access
+ $this->Auth->protect(env('GROUP_ADMINS'));
- // Set the active menu item
- $this->set('at_backend', true);
- }
-}
\ No newline at end of file
+ // Set the active menu item
+ $this->set('at_backend', true);
+ }
+}
diff --git a/app/Plugin/Admin/Controller/GroupsController.php b/app/Plugin/Admin/Controller/GroupsController.php
index e067623..576b1e5 100644
--- a/app/Plugin/Admin/Controller/GroupsController.php
+++ b/app/Plugin/Admin/Controller/GroupsController.php
@@ -3,143 +3,146 @@
use Respect\Validation\Rules;
class GroupsController extends AdminAppController {
- public $uses = ['Group'];
-
- public function beforeFilter() {
- parent::beforeFilter();
-
- $this->validators = [
- 'name' => new Rules\AllOf(
- new Rules\Alnum('-_'),
- new Rules\NotEmpty()
- ),
- 'team_number' => new Rules\Optional(
- new Rules\Digit()
- ),
- 'parent_id' => new Rules\Optional(
- new Rules\Digit()
- ),
- ];
- }
-
- /**
- * Group List Page
- *
- * @url /admin/group
- * @url /admin/group/index
- */
- public function index() {
- $mappings = [];
- foreach ( $this->Group->find('all') AS $g ) {
- if ( $g['Group']['team_number'] === NULL ) continue;
-
- $mappings[$g['Group']['id']] = $g['Group']['team_number'];
- }
-
- $this->set('mappings', $mappings);
- $this->set('groups', $this->Group->generateTreeList(null, null, null, '-- '));
- }
-
- /**
- * Create Group
- *
- * @url /admin/group/create
- */
- public function create() {
- if ( $this->request->is('post') ) {
- // Validate the input
- $res = $this->_validate();
-
- if ( empty($res['errors']) ) {
- $this->Group->create();
- $this->Group->save($res['data']);
-
- $this->logMessage(
- 'groups',
- sprintf('Created group "%s"', $created['name']),
- [],
- $this->Group->id
- );
-
- $this->Flash->success('The group has been created!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'groups', 'action' => 'index']);
- } else {
- $this->_errorFlash($res['errors']);
- }
- }
-
- $this->set('groups', $this->Group->generateTreeList(null, null, null, '-- '));
- }
-
- /**
- * Edit Group
- *
- * @url /admin/group/edit/
- */
- public function edit($gid=false) {
- $group = $this->Group->findById($gid);
- if ( empty($group) ) {
- throw new NotFoundException('Unknown group');
- }
-
- if ( $this->request->is('post') ) {
- // Validate the input
- $res = $this->_validate();
-
- if ( empty($res['errors']) ) {
- $this->Group->id = $gid;
- $this->Group->save($res['data']);
-
- $this->logMessage(
- 'groups',
- sprintf('Updated group "%s"', $group['Group']['name']),
- [
- 'old_group' => $group['Group'],
- 'new_group' => $res['data'],
- ],
- $uid
- );
-
- $this->Flash->success('The user has been updated!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'groups', 'action' => 'index']);
- } else {
- $this->_errorFlash($res['errors']);
- }
- }
-
- $this->set('group', $group);
- $this->set('groups', $this->Group->generateTreeList(null, null, null, '-- '));
- }
-
- /**
- * Delete group
- *
- * @url /admin/group/delete/
- */
- public function delete($gid=false) {
- $group = $this->Group->findById($gid);
- if ( empty($group) ) {
- throw new NotFoundException('Unknown group');
- }
-
- if ( $this->request->is('post') ) {
- $this->Group->delete($gid);
-
- $msg = sprintf('Deleted group "%s" (#%d)', $group['Group']['name'], $gid);
-
- $this->logMessage(
- 'groups',
- $msg,
- [
- 'group' => $group['Group'],
- ],
- $gid
- );
-
- $this->Flash->success($msg);
- return $this->redirect(['plugin' => 'admin', 'controller' => 'groups', 'action' => 'index']);
- }
-
- $this->set('group', $group);
- }
+
+ public $uses = ['Group'];
+
+ public function beforeFilter() {
+ parent::beforeFilter();
+
+ $this->validators = [
+ 'name' => new Rules\AllOf(
+ new Rules\Alnum('-_'),
+ new Rules\NotEmpty()
+ ),
+ 'team_number' => new Rules\Optional(
+ new Rules\Digit()
+ ),
+ 'parent_id' => new Rules\Optional(
+ new Rules\Digit()
+ ),
+ ];
+ }
+
+ /**
+ * Group List Page
+ *
+ * @url /admin/group
+ * @url /admin/group/index
+ */
+ public function index() {
+ $mappings = [];
+ foreach ($this->Group->find('all') as $g) {
+ if ($g['Group']['team_number'] === null) {
+ continue;
+ }
+
+ $mappings[$g['Group']['id']] = $g['Group']['team_number'];
+ }
+
+ $this->set('mappings', $mappings);
+ $this->set('groups', $this->Group->generateTreeList(null, null, null, '-- '));
+ }
+
+ /**
+ * Create Group
+ *
+ * @url /admin/group/create
+ */
+ public function create() {
+ if ($this->request->is('post')) {
+ // Validate the input
+ $res = $this->validate();
+
+ if (empty($res['errors'])) {
+ $this->Group->create();
+ $this->Group->save($res['data']);
+
+ $this->logMessage(
+ 'groups',
+ sprintf('Created group "%s"', $created['name']),
+ [],
+ $this->Group->id
+ );
+
+ $this->Flash->success('The group has been created!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'groups', 'action' => 'index']);
+ } else {
+ $this->errorFlash($res['errors']);
+ }
+ }
+
+ $this->set('groups', $this->Group->generateTreeList(null, null, null, '-- '));
+ }
+
+ /**
+ * Edit Group
+ *
+ * @url /admin/group/edit/
+ */
+ public function edit($gid = false) {
+ $group = $this->Group->findById($gid);
+ if (empty($group)) {
+ throw new NotFoundException('Unknown group');
+ }
+
+ if ($this->request->is('post')) {
+ // Validate the input
+ $res = $this->validate();
+
+ if (empty($res['errors'])) {
+ $this->Group->id = $gid;
+ $this->Group->save($res['data']);
+
+ $this->logMessage(
+ 'groups',
+ sprintf('Updated group "%s"', $group['Group']['name']),
+ [
+ 'old_group' => $group['Group'],
+ 'new_group' => $res['data'],
+ ],
+ $uid
+ );
+
+ $this->Flash->success('The user has been updated!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'groups', 'action' => 'index']);
+ } else {
+ $this->errorFlash($res['errors']);
+ }
+ }
+
+ $this->set('group', $group);
+ $this->set('groups', $this->Group->generateTreeList(null, null, null, '-- '));
+ }
+
+ /**
+ * Delete group
+ *
+ * @url /admin/group/delete/
+ */
+ public function delete($gid = false) {
+ $group = $this->Group->findById($gid);
+ if (empty($group)) {
+ throw new NotFoundException('Unknown group');
+ }
+
+ if ($this->request->is('post')) {
+ $this->Group->delete($gid);
+
+ $msg = sprintf('Deleted group "%s" (#%d)', $group['Group']['name'], $gid);
+
+ $this->logMessage(
+ 'groups',
+ $msg,
+ [
+ 'group' => $group['Group'],
+ ],
+ $gid
+ );
+
+ $this->Flash->success($msg);
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'groups', 'action' => 'index']);
+ }
+
+ $this->set('group', $group);
+ }
}
diff --git a/app/Plugin/Admin/Controller/HintsController.php b/app/Plugin/Admin/Controller/HintsController.php
index 9700bd6..3863d1c 100644
--- a/app/Plugin/Admin/Controller/HintsController.php
+++ b/app/Plugin/Admin/Controller/HintsController.php
@@ -3,156 +3,157 @@
use Respect\Validation\Rules;
class HintsController extends AdminAppController {
- public $uses = ['Hint', 'Inject'];
-
- public function beforeFilter() {
- parent::beforeFilter();
-
- // Setup the validators
- $this->validators = [
- 'inject_id' => new Rules\AllOf(
- new Rules\Digit()
- ),
- 'parent_id' => new Rules\Optional(
- new Rules\Digit()
- ),
- 'title' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- 'content' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- 'time_wait' => new Rules\AllOf(
- new Rules\Digit()
- ),
- 'cost' => new Rules\AllOf(
- new Rules\Digit()
- ),
- ];
- }
-
- /**
- * Hint List Page
- *
- * @url /admin/hints
- * @url /admin/hints/index
- */
- public function index() {
- $this->set('hints', $this->Hint->find('all'));
- }
-
- /**
- * Create Hint
- *
- * @url /admin/hints/create
- */
- public function create() {
- if ( $this->request->is('post') ) {
- // Validate the input
- $res = $this->_validate();
-
- if ( empty($res['errors']) ) {
- $this->Hint->create();
- $this->Hint->save($res['data']);
-
- $this->logMessage(
- 'hints',
- sprintf('Created hint "%s"', $res['data']['title']),
- [],
- $id
- );
-
- $this->Flash->success('The hint has been created!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'hints', 'action' => 'index']);
- } else {
- $this->_errorFlash($res['errors']);
- }
- }
-
- $this->set('hints', $this->Hint->find('all'));
- $this->set('injects', $this->Inject->find('all'));
- }
-
- /**
- * Edit Hint
- *
- * @url /admin/hints/edit/
- */
- public function edit($id=false) {
- $hint = $this->Hint->findById($id);
- if ( empty($hint) ) {
- throw new NotFoundException('Unknown hint');
- }
-
- if ( $this->request->is('post') ) {
- // Validate the input
- $res = $this->_validate();
-
- if ( empty($res['errors']) ) {
- // Fix parent_id
- if ( $res['data']['parent_id'] == 0 ) {
- $res['data']['parent_id'] = NULL;
- }
-
- $this->Hint->id = $id;
- $this->Hint->save($res['data']);
-
- $this->logMessage(
- 'hints',
- sprintf('Updated hint "%s"', $hint['Hint']['title']),
- [
- 'old_hint' => $hint['Hint'],
- 'new_hint' => $res['data'],
- ],
- $id
- );
-
- $this->Flash->success('The hint has been updated!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'hints', 'action' => 'index']);
- } else {
- $this->_errorFlash($res['errors']);
- }
- }
-
- $this->set('hints', $this->Hint->find('all'));
- $this->set('injects', $this->Inject->find('all'));
- $this->set('hint', $hint);
- }
-
- /**
- * Delete Hint
- *
- * @url /admin/hints/delete/
- */
- public function delete($id=false) {
- $hint = $this->Hint->findById($id);
- if ( empty($hint) ) {
- throw new NotFoundException('Unknown hint');
- }
-
- if ( $this->request->is('post') ) {
- $this->Hint->delete($id);
-
- $msg = sprintf('Deleted hint "%s"', $hint['Hint']['title']);
- $this->logMessage('hints', $msg, ['hint' => $hint], $id);
- $this->Flash->success($msg.'!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'hints', 'action' => 'index']);
- }
-
- $this->set('hint', $hint);
- }
-
- /**
- * View Hint
- *
- * @url /admin/hints/view/
- */
- public function view($id=false) {
- $log = $this->Log->findById($id);
- if ( empty($log) ) {
- throw new NotFoundException('Unknown Log ID');
- }
-
- $this->set('log', $log);
- }
+
+ public $uses = ['Hint', 'Inject'];
+
+ public function beforeFilter() {
+ parent::beforeFilter();
+
+ // Setup the validators
+ $this->validators = [
+ 'inject_id' => new Rules\AllOf(
+ new Rules\Digit()
+ ),
+ 'parent_id' => new Rules\Optional(
+ new Rules\Digit()
+ ),
+ 'title' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ 'content' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ 'time_wait' => new Rules\AllOf(
+ new Rules\Digit()
+ ),
+ 'cost' => new Rules\AllOf(
+ new Rules\Digit()
+ ),
+ ];
+ }
+
+ /**
+ * Hint List Page
+ *
+ * @url /admin/hints
+ * @url /admin/hints/index
+ */
+ public function index() {
+ $this->set('hints', $this->Hint->find('all'));
+ }
+
+ /**
+ * Create Hint
+ *
+ * @url /admin/hints/create
+ */
+ public function create() {
+ if ($this->request->is('post')) {
+ // Validate the input
+ $res = $this->validate();
+
+ if (empty($res['errors'])) {
+ $this->Hint->create();
+ $this->Hint->save($res['data']);
+
+ $this->logMessage(
+ 'hints',
+ sprintf('Created hint "%s"', $res['data']['title']),
+ [],
+ $id
+ );
+
+ $this->Flash->success('The hint has been created!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'hints', 'action' => 'index']);
+ } else {
+ $this->errorFlash($res['errors']);
+ }
+ }
+
+ $this->set('hints', $this->Hint->find('all'));
+ $this->set('injects', $this->Inject->find('all'));
+ }
+
+ /**
+ * Edit Hint
+ *
+ * @url /admin/hints/edit/
+ */
+ public function edit($id = false) {
+ $hint = $this->Hint->findById($id);
+ if (empty($hint)) {
+ throw new NotFoundException('Unknown hint');
+ }
+
+ if ($this->request->is('post')) {
+ // Validate the input
+ $res = $this->validate();
+
+ if (empty($res['errors'])) {
+ // Fix parent_id
+ if ($res['data']['parent_id'] == 0) {
+ $res['data']['parent_id'] = null;
+ }
+
+ $this->Hint->id = $id;
+ $this->Hint->save($res['data']);
+
+ $this->logMessage(
+ 'hints',
+ sprintf('Updated hint "%s"', $hint['Hint']['title']),
+ [
+ 'old_hint' => $hint['Hint'],
+ 'new_hint' => $res['data'],
+ ],
+ $id
+ );
+
+ $this->Flash->success('The hint has been updated!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'hints', 'action' => 'index']);
+ } else {
+ $this->errorFlash($res['errors']);
+ }
+ }
+
+ $this->set('hints', $this->Hint->find('all'));
+ $this->set('injects', $this->Inject->find('all'));
+ $this->set('hint', $hint);
+ }
+
+ /**
+ * Delete Hint
+ *
+ * @url /admin/hints/delete/
+ */
+ public function delete($id = false) {
+ $hint = $this->Hint->findById($id);
+ if (empty($hint)) {
+ throw new NotFoundException('Unknown hint');
+ }
+
+ if ($this->request->is('post')) {
+ $this->Hint->delete($id);
+
+ $msg = sprintf('Deleted hint "%s"', $hint['Hint']['title']);
+ $this->logMessage('hints', $msg, ['hint' => $hint], $id);
+ $this->Flash->success($msg.'!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'hints', 'action' => 'index']);
+ }
+
+ $this->set('hint', $hint);
+ }
+
+ /**
+ * View Hint
+ *
+ * @url /admin/hints/view/
+ */
+ public function view($id = false) {
+ $log = $this->Log->findById($id);
+ if (empty($log)) {
+ throw new NotFoundException('Unknown Log ID');
+ }
+
+ $this->set('log', $log);
+ }
}
diff --git a/app/Plugin/Admin/Controller/InjectsController.php b/app/Plugin/Admin/Controller/InjectsController.php
index ca19a7b..af72884 100644
--- a/app/Plugin/Admin/Controller/InjectsController.php
+++ b/app/Plugin/Admin/Controller/InjectsController.php
@@ -3,205 +3,206 @@
use Respect\Validation\Rules;
class InjectsController extends AdminAppController {
- public $uses = ['Attachment', 'Config', 'Inject', 'Schedule'];
-
- public function beforeFilter() {
- parent::beforeFilter();
-
- // Load + setup the InjectStyler helper
- $this->helpers[] = 'InjectStyler';
- $this->helpers['InjectStyler'] = [
- 'types' => $this->Config->getInjectTypes(),
- 'inject' => new stdClass(), // Nothing...for now
- ];
-
- // Setup the validators
- $this->validators = [
- 'sequence' => new Rules\AllOf(
- new Rules\Digit()
- ),
- 'title' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- 'content' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- 'from_name' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- 'from_email' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- 'grading_guide' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- 'max_points' => new Rules\AllOf(
- new Rules\Digit(),
- new Rules\NotEmpty()
- ),
- 'max_submissions' => new Rules\AllOf(
- new Rules\Digit(),
- new Rules\NotEmpty()
- ),
- 'type' => new Rules\AllOf(
- new Rules\Alnum('-_'),
- new Rules\NotEmpty()
- ),
- ];
- }
-
- /**
- * Inject List Page
- *
- * @url /admin/injects
- * @url /admin/injects/index
- */
- public function index() {
- $this->set('injects', $this->Inject->find('all'));
- }
-
- /**
- * Create Inject
- *
- * @url /admin/injects/create
- */
- public function create() {
- if ( $this->request->is('post') ) {
- // Validate the input
- $res = $this->_validate();
-
- if ( empty($res['errors']) ) {
- // Upload the new attachments
- if ( isset($this->request->data['new_attachments'])) {
- foreach ( $this->request->data['new_attachments'] AS $new ) {
- $contents = file_get_contents($new['tmp_name']);
- $data = json_encode([
- 'extension' => pathinfo($new['name'], PATHINFO_EXTENSION),
- 'hash' => md5($contents),
- 'data' => base64_encode($contents)
- ]);
-
- $this->Attachment->create();
- $this->Attachment->save([
- 'inject_id' => $inject['Inject']['id'],
- 'name' => $new['name'],
- 'data' => $data,
- ]);
- }
- }
-
- $this->Inject->create();
- $this->Inject->save($res['data']);
-
- $this->logMessage(
- 'injects',
- sprintf('Created inject "%s"', $res['data']['title']),
- [],
- $this->Inject->id
- );
-
- $this->Flash->success('The inject has been created!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'injects', 'action' => 'index']);
- } else {
- $this->_errorFlash($res['errors']);
- }
- }
- }
-
- /**
- * Edit Inject
- *
- * @url /admin/injects/edit/
- */
- public function edit($id=false) {
- $inject = $this->Inject->findById($id);
- if ( empty($inject) ) {
- throw new NotFoundException('Unknown inject');
- }
-
- if ( $this->request->is('post') ) {
- // Validate the input
- $res = $this->_validate();
-
- if ( empty($res['errors']) ) {
- // Figure out if we deleted any attachments
- foreach ( $inject['Attachment'] AS $i => $a ) {
- if ( !isset($this->request->data['attachments'][$a['id']]) ) {
- $this->Attachment->delete($a['id']);
-
- unset($inject['Attachment'][$i]);
- }
- }
-
- // Upload the new attachments
- if ( isset($this->request->data['new_attachments'])) {
- foreach ( $this->request->data['new_attachments'] AS $new ) {
- $contents = file_get_contents($new['tmp_name']);
- $data = json_encode([
- 'extension' => pathinfo($new['name'], PATHINFO_EXTENSION),
- 'hash' => md5($contents),
- 'data' => base64_encode($contents)
- ]);
-
- $this->Attachment->create();
- $this->Attachment->save([
- 'inject_id' => $inject['Inject']['id'],
- 'name' => $new['name'],
- 'data' => $data,
- ]);
- }
- }
-
- $this->Inject->id = $id;
- $this->Inject->save($res['data']);
-
- $this->logMessage(
- 'injects',
- sprintf('Updated inject "%s"', $inject['Inject']['title']),
- [
- 'old_inject' => $inject['Inject'],
- 'new_inject' => $res['data'],
- ],
- $id
- );
-
- $this->Flash->success('The inject has been updated!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'injects', 'action' => 'index']);
- } else {
- $this->_errorFlash($res['errors']);
- }
- }
-
- $this->set('inject', $inject);
- }
-
- /**
- * Delete Inject
- *
- * @url /admin/injects/delete/
- */
- public function delete($id=false) {
- $inject = $this->Inject->findById($id);
- if ( empty($inject) ) {
- throw new NotFoundException('Unknown inject');
- }
-
- if ( $this->request->is('post') ) {
- $this->Inject->delete($id);
-
- // Delete all associated schedules
- $schedules = [];
- foreach ( $this->Schedule->findByInjectId($id) AS $s ) {
- $schedules[] = $s['Schedule']['id'];
- }
- $this->Schedule->delete($schedules);
-
- $msg = sprintf('Deleted inject "%s"', $inject['Inject']['title']);
- $this->logMessage('injects', $msg, ['inject' => $inject], $id);
- $this->Flash->success($msg.'!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'injects', 'action' => 'index']);
- }
-
- $this->set('inject', $inject);
- }
+
+ public $uses = ['Attachment', 'Config', 'Inject', 'Schedule'];
+
+ public function beforeFilter() {
+ parent::beforeFilter();
+
+ // Load + setup the InjectStyler helper
+ $this->helpers[] = 'InjectStyler';
+ $this->helpers['InjectStyler'] = [
+ 'types' => $this->Config->getInjectTypes(),
+ 'inject' => new stdClass(), // Nothing...for now
+ ];
+
+ // Setup the validators
+ $this->validators = [
+ 'sequence' => new Rules\AllOf(
+ new Rules\Digit()
+ ),
+ 'title' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ 'content' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ 'from_name' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ 'from_email' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ 'grading_guide' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ 'max_points' => new Rules\AllOf(
+ new Rules\Digit(),
+ new Rules\NotEmpty()
+ ),
+ 'max_submissions' => new Rules\AllOf(
+ new Rules\Digit(),
+ new Rules\NotEmpty()
+ ),
+ 'type' => new Rules\AllOf(
+ new Rules\Alnum('-_'),
+ new Rules\NotEmpty()
+ ),
+ ];
+ }
+
+ /**
+ * Inject List Page
+ *
+ * @url /admin/injects
+ * @url /admin/injects/index
+ */
+ public function index() {
+ $this->set('injects', $this->Inject->find('all'));
+ }
+
+ /**
+ * Create Inject
+ *
+ * @url /admin/injects/create
+ */
+ public function create() {
+ if ($this->request->is('post')) {
+ // Validate the input
+ $res = $this->validate();
+
+ if (empty($res['errors'])) {
+ // Upload the new attachments
+ if (isset($this->request->data['new_attachments'])) {
+ foreach ($this->request->data['new_attachments'] as $new) {
+ $contents = file_get_contents($new['tmp_name']);
+ $data = json_encode([
+ 'extension' => pathinfo($new['name'], PATHINFO_EXTENSION),
+ 'hash' => md5($contents),
+ 'data' => base64_encode($contents)
+ ]);
+
+ $this->Attachment->create();
+ $this->Attachment->save([
+ 'inject_id' => $inject['Inject']['id'],
+ 'name' => $new['name'],
+ 'data' => $data,
+ ]);
+ }
+ }
+
+ $this->Inject->create();
+ $this->Inject->save($res['data']);
+
+ $this->logMessage(
+ 'injects',
+ sprintf('Created inject "%s"', $res['data']['title']),
+ [],
+ $this->Inject->id
+ );
+
+ $this->Flash->success('The inject has been created!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'injects', 'action' => 'index']);
+ } else {
+ $this->errorFlash($res['errors']);
+ }
+ }
+ }
+
+ /**
+ * Edit Inject
+ *
+ * @url /admin/injects/edit/
+ */
+ public function edit($id = false) {
+ $inject = $this->Inject->findById($id);
+ if (empty($inject)) {
+ throw new NotFoundException('Unknown inject');
+ }
+
+ if ($this->request->is('post')) {
+ // Validate the input
+ $res = $this->validate();
+
+ if (empty($res['errors'])) {
+ // Figure out if we deleted any attachments
+ foreach ($inject['Attachment'] as $i => $a) {
+ if (!isset($this->request->data['attachments'][$a['id']])) {
+ $this->Attachment->delete($a['id']);
+
+ unset($inject['Attachment'][$i]);
+ }
+ }
+
+ // Upload the new attachments
+ if (isset($this->request->data['new_attachments'])) {
+ foreach ($this->request->data['new_attachments'] as $new) {
+ $contents = file_get_contents($new['tmp_name']);
+ $data = json_encode([
+ 'extension' => pathinfo($new['name'], PATHINFO_EXTENSION),
+ 'hash' => md5($contents),
+ 'data' => base64_encode($contents)
+ ]);
+
+ $this->Attachment->create();
+ $this->Attachment->save([
+ 'inject_id' => $inject['Inject']['id'],
+ 'name' => $new['name'],
+ 'data' => $data,
+ ]);
+ }
+ }
+
+ $this->Inject->id = $id;
+ $this->Inject->save($res['data']);
+
+ $this->logMessage(
+ 'injects',
+ sprintf('Updated inject "%s"', $inject['Inject']['title']),
+ [
+ 'old_inject' => $inject['Inject'],
+ 'new_inject' => $res['data'],
+ ],
+ $id
+ );
+
+ $this->Flash->success('The inject has been updated!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'injects', 'action' => 'index']);
+ } else {
+ $this->errorFlash($res['errors']);
+ }
+ }
+
+ $this->set('inject', $inject);
+ }
+
+ /**
+ * Delete Inject
+ *
+ * @url /admin/injects/delete/
+ */
+ public function delete($id = false) {
+ $inject = $this->Inject->findById($id);
+ if (empty($inject)) {
+ throw new NotFoundException('Unknown inject');
+ }
+
+ if ($this->request->is('post')) {
+ $this->Inject->delete($id);
+
+ // Delete all associated schedules
+ $schedules = [];
+ foreach ($this->Schedule->findByInjectId($id) as $s) {
+ $schedules[] = $s['Schedule']['id'];
+ }
+ $this->Schedule->delete($schedules);
+
+ $msg = sprintf('Deleted inject "%s"', $inject['Inject']['title']);
+ $this->logMessage('injects', $msg, ['inject' => $inject], $id);
+ $this->Flash->success($msg.'!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'injects', 'action' => 'index']);
+ }
+
+ $this->set('inject', $inject);
+ }
}
diff --git a/app/Plugin/Admin/Controller/LogsController.php b/app/Plugin/Admin/Controller/LogsController.php
index 5574e91..071e9b6 100644
--- a/app/Plugin/Admin/Controller/LogsController.php
+++ b/app/Plugin/Admin/Controller/LogsController.php
@@ -2,45 +2,46 @@
App::uses('AdminAppController', 'Admin.Controller');
class LogsController extends AdminAppController {
- public $uses = ['Log'];
- public $paginate = [
- 'fields' => [
- 'Log.id', 'Log.time', 'Log.type', 'Log.data',
- 'Log.ip', 'Log.message', 'User.username', 'User.group_id',
- ],
- 'contain' => [
- 'User' => [
- 'Group.name',
- ]
- ],
- 'order' => [
- 'Log.id' => 'DESC'
- ],
- ];
+ public $uses = ['Log'];
- /**
- * Log List Page
- *
- * @url /admin/logs
- * @url /admin/logs/index
- */
- public function index() {
- $this->Paginator->settings += $this->paginate;
- $this->set('recent_logs', $this->Paginator->paginate('Log'));
- }
+ public $paginate = [
+ 'fields' => [
+ 'Log.id', 'Log.time', 'Log.type', 'Log.data',
+ 'Log.ip', 'Log.message', 'User.username', 'User.group_id',
+ ],
+ 'contain' => [
+ 'User' => [
+ 'Group.name',
+ ]
+ ],
+ 'order' => [
+ 'Log.id' => 'DESC'
+ ],
+ ];
- /**
- * View Log
- *
- * @url /admin/logs/view/
- */
- public function view($id=false) {
- $log = $this->Log->findById($id);
- if ( empty($log) ) {
- throw new NotFoundException('Unknown Log ID');
- }
+ /**
+ * Log List Page
+ *
+ * @url /admin/logs
+ * @url /admin/logs/index
+ */
+ public function index() {
+ $this->Paginator->settings += $this->paginate;
+ $this->set('recent_logs', $this->Paginator->paginate('Log'));
+ }
- $this->set('log', $log);
- }
+ /**
+ * View Log
+ *
+ * @url /admin/logs/view/
+ */
+ public function view($id = false) {
+ $log = $this->Log->findById($id);
+ if (empty($log)) {
+ throw new NotFoundException('Unknown Log ID');
+ }
+
+ $this->set('log', $log);
+ }
}
diff --git a/app/Plugin/Admin/Controller/ScheduleController.php b/app/Plugin/Admin/Controller/ScheduleController.php
index c231a46..6f7d1d1 100644
--- a/app/Plugin/Admin/Controller/ScheduleController.php
+++ b/app/Plugin/Admin/Controller/ScheduleController.php
@@ -3,300 +3,314 @@
App::uses('InjectAbstraction', 'Lib');
class ScheduleController extends AppController {
- public $uses = ['Config', 'Inject', 'Group', 'Schedule'];
-
- /**
- * Before Filter Hook
- *
- * Set's the active tab to be staff
- */
- public function beforeFilter() {
- parent::beforeFilter();
-
- if ( in_array($this->request->action, ['index', 'api']) ) {
- $this->Auth->protect(env('GROUP_STAFF'));
- $this->set('at_staff', true);
- } else {
- $this->Auth->protect(env('GROUP_ADMINS'));
- $this->set('at_backend', true);
- }
- }
-
- /**
- * Overview Page
- *
- * @url /admin/schedule
- * @url /admin/schedule/index
- */
- public function index() {
- $bounds = $this->Schedule->getScheduleBounds();
-
- $this->set('start', $bounds['min']);
- $this->set('end', $bounds['max']);
- }
-
- /**
- * Overview API Page
- *
- * @url /admin/schedule/api
- */
- public function api() {
- if (
- $this->request->is('post') &&
- isset($this->request->data['changes']) &&
- is_array($this->request->data['changes'])
- ) {
- foreach ( $this->request->data['changes'] AS $c ) {
- $schedule = $this->Schedule->findById($c['id']);
- if ( empty($schedule) ) continue;
-
- $start = ($schedule['Schedule']['fuzzy'] ? $c['start'] - COMPETITION_START : $c['start']);
- $end = ($schedule['Schedule']['fuzzy'] ? $c['end'] - COMPETITION_START : $c['end']);
-
- // Bad time - we don't want negatives
- if ( 0 > $start || 0 > $end ) continue;
-
- $this->Schedule->id = $c['id'];
- $this->Schedule->save([
- 'start' => $start,
- 'end' => $end,
- ]);
- }
-
- return $this->ajaxResponse(true);
- }
- $out = ['data' => []];
-
- $schedules = $this->Schedule->getAllSchedules();
- $bounds = $this->Schedule->getScheduleBounds();
-
- foreach ( $schedules AS $s ) {
- $out['data'][] = [
- 'id' => $s->getScheduleId(),
- 'inject_id' => $s->getInjectId(),
- 'text' => $s->getTitle().' ('.$s->getGroupName().')',
- 'group' => $s->getGroupName(),
- 'start_date' => date('d-m-Y G:i:s', $s->getStart() > 0 ? $s->getStart() : $bounds['min']),
- 'start_ts' => $s->getStart(),
- 'end_date' => date('d-m-Y G:i:s', $s->getEnd() > 0 ? $s->getEnd() : $bounds['max']),
- 'end_ts' => $s->getEnd(),
- ];
- }
-
- return $this->ajaxResponse($out);
- }
-
- /**
- * Manager Page
- *
- * @url /admin/schedule/manager
- */
- public function manager() {
- $this->set('injects', $this->Schedule->getAllSchedules(false));
- }
-
- /**
- * Create a schedule.
- *
- * @url /admin/schedule/create
- * @url /admin/schedule/create/
- */
- public function create($sid=false) {
- if ( $this->request->is('post') ) {
- $create = [];
- $missing = [];
- foreach ( array_keys($this->Schedule->schema()) AS $key ) {
- if ( in_array($key, ['id']) ) continue;
-
- if ( !isset($this->request->data[$key]) ) {
- $missing[] = $key;
- continue;
- }
-
- // Fix dependency_id to be NULL if the ID is 0
- if ( $key == 'dependency_id' && $this->request->data['dependency_id'] == 0 ) {
- $this->request->data['dependency_id'] = NULL;
- }
-
- $create[$key] = $this->request->data[$key];
- }
-
- if ( empty($missing) ) {
- $this->Schedule->create();
- $this->Schedule->save($create);
-
- $msg = sprintf('Created schedule #%d', $this->Schedule->id);
-
- $this->logMessage(
- 'schedule',
- $msg,
- [
- 'schedule' => $create,
- ],
- $sid
- );
-
- $this->Flash->success($msg.'!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'schedule', 'action' => 'manager']);
- } else {
- $this->Flash->danger(sprintf('You are missing %s!', implode(', ', $missing)));
- return $this->redirect(['plugin' => 'admin', 'controller' => 'schedule', 'action' => 'create']);
- }
- }
-
- $this->set('injects', $this->Inject->find('all'));
- $this->set('groups', $this->Group->generateTreeList(null, null, null, '--'));
-
- if ( $sid !== false && is_numeric($sid) ) {
- $schedule = $this->Schedule->findById($sid);
- if ( empty($schedule) ) {
- throw new NotFoundException('Unknown Schedule ID');
- }
-
- // Load + setup the InjectStyler helper
- $this->helpers[] = 'InjectStyler';
- $this->helpers['InjectStyler'] = [
- 'types' => $this->Config->getInjectTypes(),
- 'inject' => new stdClass(), // Nothing...for now
- ];
-
- $this->set('schedule', $schedule);
- }
- }
-
- /**
- * Flip the status of a schedule
- *
- * @url /admin/schedule/flip/
- */
- public function flip($sid=false) {
- $schedule = $this->Schedule->findById($sid);
-
- if ( !empty($schedule) ) {
- $this->Schedule->id = $sid;
- $this->Schedule->save([
- 'active' => !($schedule['Schedule']['active']),
- ]);
-
- $msg = sprintf('%sctivated inject "%s"', ($schedule['Schedule']['active'] ? 'Dea' : 'A'), $schedule['Inject']['title']);
-
- $this->logMessage(
- 'schedule',
- $msg,
- [
- 'old_status' => $schedule['Schedule']['active'],
- 'new_status' => !$schedule['Schedule']['active'],
- ],
- $sid
- );
-
- $this->Flash->success($msg.'!');
- } else {
- $this->Flash->danger('Unknown Schedule ID');
- }
-
- return $this->redirect(['plugin' => 'admin', 'controller' => 'schedule', 'action' => 'manager']);
- }
-
- /**
- * Edit a schedule.
- *
- * @url /admin/schedule/edit/
- */
- public function edit($sid) {
- $schedule = $this->Schedule->findById($sid);
- if ( empty($schedule) ) {
- throw new NotFoundException('Unknown Schedule ID');
- }
-
- if ( $this->request->is('post') ) {
- $this->Schedule->id = $sid;
-
- // Fix dependency_id to be NULL if the ID is 0
- if ( isset($this->request->data['dependency_id']) && $this->request->data['dependency_id'] == 0 ) {
- $this->request->data['dependency_id'] = NULL;
- }
-
- $update = [];
- foreach ( $schedule['Schedule'] AS $k => $v ) {
- if ( !isset($this->request->data[$k]) ) continue;
- if ( $this->request->data[$k] == $v ) continue;
-
- $update[$k] = $this->request->data[$k];
- }
-
- if ( !empty($update) ) {
- $this->Schedule->save($update);
-
- $msg = sprintf('Edited schedule #%d', $sid);
-
- $this->logMessage(
- 'schedule',
- $msg,
- [
- 'old_schedule' => $schedule['Schedule'],
- 'new_schedule' => $this->request->data,
- 'delta' => $update,
- ],
- $sid
- );
-
- $this->Flash->success($msg.'!');
- } else {
- $this->Flash->danger('There are no changes to save');
- }
-
- return $this->redirect(['plugin' => 'admin', 'controller' => 'schedule', 'action' => 'manager']);
- }
-
- // Load + setup the InjectStyler helper
- $this->helpers[] = 'InjectStyler';
- $this->helpers['InjectStyler'] = [
- 'types' => $this->Config->getInjectTypes(),
- 'inject' => new stdClass(), // Nothing...for now
- ];
-
- $this->set('injects', $this->Inject->find('all'));
- $this->set('groups', $this->Group->generateTreeList(null, null, null, '--'));
- $this->set('schedule', $schedule);
- }
-
- /**
- * Delete a schedule. SPOOKY
- *
- * @url /admin/schedule/delete/
- */
- public function delete($sid) {
- $schedule = $this->Schedule->findById($sid);
- if ( empty($schedule) ) {
- throw new NotFoundException('Unknown Schedule ID');
- }
-
- if ( $this->request->is('post') ) {
- $this->Schedule->delete($sid);
-
- $msg = sprintf('Deleted schedule #%d', $sid);
-
- $this->logMessage(
- 'schedule',
- $msg,
- [
- 'schedule' => $schedule['Schedule'],
- ],
- $sid
- );
-
- $this->Flash->success($msg);
- return $this->redirect(['plugin' => 'admin', 'controller' => 'schedule', 'action' => 'manager']);
- }
-
- // Load + setup the InjectStyler helper
- $this->helpers[] = 'InjectStyler';
- $this->helpers['InjectStyler'] = [
- 'types' => $this->Config->getInjectTypes(),
- 'inject' => new stdClass(), // Nothing...for now
- ];
-
- $this->set('schedule', new InjectAbstraction($schedule, 0));
- }
+
+ public $uses = ['Config', 'Inject', 'Group', 'Schedule'];
+
+ /**
+ * Before Filter Hook
+ *
+ * Set's the active tab to be staff
+ */
+ public function beforeFilter() {
+ parent::beforeFilter();
+
+ if (in_array($this->request->action, ['index', 'api'])) {
+ $this->Auth->protect(env('GROUP_STAFF'));
+ $this->set('at_staff', true);
+ } else {
+ $this->Auth->protect(env('GROUP_ADMINS'));
+ $this->set('at_backend', true);
+ }
+ }
+
+ /**
+ * Overview Page
+ *
+ * @url /admin/schedule
+ * @url /admin/schedule/index
+ */
+ public function index() {
+ $bounds = $this->Schedule->getScheduleBounds();
+
+ $this->set('start', $bounds['min']);
+ $this->set('end', $bounds['max']);
+ }
+
+ /**
+ * Overview API Page
+ *
+ * @url /admin/schedule/api
+ */
+ public function api() {
+ if ($this->request->is('post')
+ && isset($this->request->data['changes'])
+ && is_array($this->request->data['changes'])
+ ) {
+ foreach ($this->request->data['changes'] as $c) {
+ $schedule = $this->Schedule->findById($c['id']);
+ if (empty($schedule)) {
+ continue;
+ }
+
+ $start = ($schedule['Schedule']['fuzzy'] ? $c['start'] - COMPETITION_START : $c['start']);
+ $end = ($schedule['Schedule']['fuzzy'] ? $c['end'] - COMPETITION_START : $c['end']);
+
+ // Bad time - we don't want negatives
+ if (0 > $start || 0 > $end) {
+ continue;
+ }
+
+ $this->Schedule->id = $c['id'];
+ $this->Schedule->save([
+ 'start' => $start,
+ 'end' => $end,
+ ]);
+ }
+
+ return $this->ajaxResponse(true);
+ }
+ $out = ['data' => []];
+
+ $schedules = $this->Schedule->getAllSchedules();
+ $bounds = $this->Schedule->getScheduleBounds();
+
+ foreach ($schedules as $s) {
+ $out['data'][] = [
+ 'id' => $s->getScheduleId(),
+ 'inject_id' => $s->getInjectId(),
+ 'text' => $s->getTitle().' ('.$s->getGroupName().')',
+ 'group' => $s->getGroupName(),
+ 'start_date' => date('d-m-Y G:i:s', $s->getStart() > 0 ? $s->getStart() : $bounds['min']),
+ 'start_ts' => $s->getStart(),
+ 'end_date' => date('d-m-Y G:i:s', $s->getEnd() > 0 ? $s->getEnd() : $bounds['max']),
+ 'end_ts' => $s->getEnd(),
+ ];
+ }
+
+ return $this->ajaxResponse($out);
+ }
+
+ /**
+ * Manager Page
+ *
+ * @url /admin/schedule/manager
+ */
+ public function manager() {
+ $this->set('injects', $this->Schedule->getAllSchedules(false));
+ }
+
+ /**
+ * Create a schedule.
+ *
+ * @url /admin/schedule/create
+ * @url /admin/schedule/create/
+ */
+ public function create($sid = false) {
+ if ($this->request->is('post')) {
+ $create = [];
+ $missing = [];
+ foreach (array_keys($this->Schedule->schema()) as $key) {
+ if (in_array($key, ['id'])) {
+ continue;
+ }
+
+ if (!isset($this->request->data[$key])) {
+ $missing[] = $key;
+ continue;
+ }
+
+ // Fix dependency_id to be NULL if the ID is 0
+ if ($key == 'dependency_id' && $this->request->data['dependency_id'] == 0) {
+ $this->request->data['dependency_id'] = null;
+ }
+
+ $create[$key] = $this->request->data[$key];
+ }
+
+ if (empty($missing)) {
+ $this->Schedule->create();
+ $this->Schedule->save($create);
+
+ $msg = sprintf('Created schedule #%d', $this->Schedule->id);
+
+ $this->logMessage(
+ 'schedule',
+ $msg,
+ [
+ 'schedule' => $create,
+ ],
+ $sid
+ );
+
+ $this->Flash->success($msg.'!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'schedule', 'action' => 'manager']);
+ } else {
+ $this->Flash->danger(sprintf('You are missing %s!', implode(', ', $missing)));
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'schedule', 'action' => 'create']);
+ }
+ }
+
+ $this->set('injects', $this->Inject->find('all'));
+ $this->set('groups', $this->Group->generateTreeList(null, null, null, '--'));
+
+ if ($sid !== false && is_numeric($sid)) {
+ $schedule = $this->Schedule->findById($sid);
+ if (empty($schedule)) {
+ throw new NotFoundException('Unknown Schedule ID');
+ }
+
+ // Load + setup the InjectStyler helper
+ $this->helpers[] = 'InjectStyler';
+ $this->helpers['InjectStyler'] = [
+ 'types' => $this->Config->getInjectTypes(),
+ 'inject' => new stdClass(), // Nothing...for now
+ ];
+
+ $this->set('schedule', $schedule);
+ }
+ }
+
+ /**
+ * Flip the status of a schedule
+ *
+ * @url /admin/schedule/flip/
+ */
+ public function flip($sid = false) {
+ $schedule = $this->Schedule->findById($sid);
+
+ if (!empty($schedule)) {
+ $this->Schedule->id = $sid;
+ $this->Schedule->save([
+ 'active' => !($schedule['Schedule']['active']),
+ ]);
+
+ $msg = sprintf(
+ '%sctivated inject "%s"',
+ ($schedule['Schedule']['active'] ? 'Dea' : 'A'),
+ $schedule['Inject']['title']
+ );
+
+ $this->logMessage(
+ 'schedule',
+ $msg,
+ [
+ 'old_status' => $schedule['Schedule']['active'],
+ 'new_status' => !$schedule['Schedule']['active'],
+ ],
+ $sid
+ );
+
+ $this->Flash->success($msg.'!');
+ } else {
+ $this->Flash->danger('Unknown Schedule ID');
+ }
+
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'schedule', 'action' => 'manager']);
+ }
+
+ /**
+ * Edit a schedule.
+ *
+ * @url /admin/schedule/edit/
+ */
+ public function edit($sid) {
+ $schedule = $this->Schedule->findById($sid);
+ if (empty($schedule)) {
+ throw new NotFoundException('Unknown Schedule ID');
+ }
+
+ if ($this->request->is('post')) {
+ $this->Schedule->id = $sid;
+
+ // Fix dependency_id to be NULL if the ID is 0
+ if (isset($this->request->data['dependency_id']) && $this->request->data['dependency_id'] == 0) {
+ $this->request->data['dependency_id'] = null;
+ }
+
+ $update = [];
+ foreach ($schedule['Schedule'] as $k => $v) {
+ if (!isset($this->request->data[$k])) {
+ continue;
+ }
+ if ($this->request->data[$k] == $v) {
+ continue;
+ }
+
+ $update[$k] = $this->request->data[$k];
+ }
+
+ if (!empty($update)) {
+ $this->Schedule->save($update);
+
+ $msg = sprintf('Edited schedule #%d', $sid);
+
+ $this->logMessage(
+ 'schedule',
+ $msg,
+ [
+ 'old_schedule' => $schedule['Schedule'],
+ 'new_schedule' => $this->request->data,
+ 'delta' => $update,
+ ],
+ $sid
+ );
+
+ $this->Flash->success($msg.'!');
+ } else {
+ $this->Flash->danger('There are no changes to save');
+ }
+
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'schedule', 'action' => 'manager']);
+ }
+
+ // Load + setup the InjectStyler helper
+ $this->helpers[] = 'InjectStyler';
+ $this->helpers['InjectStyler'] = [
+ 'types' => $this->Config->getInjectTypes(),
+ 'inject' => new stdClass(), // Nothing...for now
+ ];
+
+ $this->set('injects', $this->Inject->find('all'));
+ $this->set('groups', $this->Group->generateTreeList(null, null, null, '--'));
+ $this->set('schedule', $schedule);
+ }
+
+ /**
+ * Delete a schedule. SPOOKY
+ *
+ * @url /admin/schedule/delete/
+ */
+ public function delete($sid) {
+ $schedule = $this->Schedule->findById($sid);
+ if (empty($schedule)) {
+ throw new NotFoundException('Unknown Schedule ID');
+ }
+
+ if ($this->request->is('post')) {
+ $this->Schedule->delete($sid);
+
+ $msg = sprintf('Deleted schedule #%d', $sid);
+
+ $this->logMessage(
+ 'schedule',
+ $msg,
+ [
+ 'schedule' => $schedule['Schedule'],
+ ],
+ $sid
+ );
+
+ $this->Flash->success($msg);
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'schedule', 'action' => 'manager']);
+ }
+
+ // Load + setup the InjectStyler helper
+ $this->helpers[] = 'InjectStyler';
+ $this->helpers['InjectStyler'] = [
+ 'types' => $this->Config->getInjectTypes(),
+ 'inject' => new stdClass(), // Nothing...for now
+ ];
+
+ $this->set('schedule', new InjectAbstraction($schedule, 0));
+ }
}
diff --git a/app/Plugin/Admin/Controller/SiteController.php b/app/Plugin/Admin/Controller/SiteController.php
index 14c5e1d..b470ff0 100644
--- a/app/Plugin/Admin/Controller/SiteController.php
+++ b/app/Plugin/Admin/Controller/SiteController.php
@@ -3,198 +3,206 @@
use Respect\Validation\Rules;
class SiteController extends AdminAppController {
- public $uses = ['Announcement', 'Config'];
-
- /**
- * Config Index Page
- *
- * @url /admin/site
- * @url /admin/site/index
- */
- public function index() {
- $this->set('announce', $this->Announcement->find('all'));
- $this->set('config', $this->Config->find('all'));
- }
-
- /**
- * Config API Page
- *
- * @url /admin/site/api//
- */
- public function api($type='announcement', $id=false) {
- switch ( $type ) {
- case 'config':
- $config = $this->Config->findById($id);
- if ( empty($config) ) {
- throw new NotFoundException('Unknown config');
- }
-
- $data = $config['Config'];
- break;
-
- case 'announcement':
- $announcement = $this->Announcement->findById($id);
- if ( empty($announcement) ) {
- throw new NotFoundException('Unknown announcement');
- }
-
- $data = $announcement['Announcement'];
- break;
-
- default:
- throw new MethodNotAllowedException();
- break;
- }
-
- return $this->ajaxResponse($data);
- }
-
- /**
- * Config Edit/Create URL
- *
- * @url /admin/site/api
- */
- public function config() {
- if ( !$this->request->is('post') ) {
- throw new MethodNotAllowedException();
- }
-
- // Validate the input
- $this->validators = [
- 'id' => new Rules\AllOf(
- new Rules\Digit()
- ),
- 'key' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- 'value' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- ];
- $res = $this->_validate();
-
- if ( !empty($res['errors']) ) {
- $this->_errorFlash($res['errors']);
-
- return $this->redirect(['plugin' => 'admin', 'controller' => 'site', 'action' => 'index']);
- }
-
- if ( $res['data']['id'] > 0 ) {
- $config = $this->Config->findById($res['data']['id']);
- if ( empty($config) ) {
- throw new NotFoundException('Unknown config');
- }
-
- $this->Config->id = $res['data']['id'];
- $this->Config->save($res['data']);
-
- $msg = sprintf('Edited config value "%s"', $config['Config']['key']);
-
- $this->logMessage('config', $msg, ['old_config' => $config['Config'], 'new_config' => $res['data']], $config['Config']['id']);
- $this->Flash->success($msg.'!');
- } else {
- // Fix the data
- unset($res['data']['id']);
-
- $this->Config->create();
- $this->Config->save($res['data']);
-
- $msg = sprintf('Created config value "%s"', $res['data']['key']);
- $this->logMessage('config', $msg, [], $this->Config->id);
- $this->Flash->success($msg.'!');
- }
-
- return $this->redirect(['plugin' => 'admin', 'controller' => 'site', 'action' => 'index']);
- }
-
- /**
- * Announcement Edit/Create URL
- *
- * @url /admin/site/announcement
- */
- public function announcement() {
- if ( !$this->request->is('post') ) {
- throw new MethodNotAllowedException();
- }
-
- // Validate the input
- $this->validators = [
- 'id' => new Rules\AllOf(
- new Rules\Digit()
- ),
- 'content' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- 'active' => new Rules\AllOf(
- new Rules\Digit()
- ),
- 'expiration' => new Rules\AllOf(
- new Rules\Digit()
- ),
- ];
- $res = $this->_validate();
-
- if ( !empty($res['errors']) ) {
- $this->_errorFlash($res['errors']);
-
- return $this->redirect(['plugin' => 'admin', 'controller' => 'site', 'action' => 'index']);
- }
-
- if ( $res['data']['id'] > 0 ) {
- $announcement = $this->Announcement->findById($res['data']['id']);
- if ( empty($announcement) ) {
- throw new NotFoundException('Unknown announcement');
- }
-
- $this->Announcement->id = $res['data']['id'];
- $this->Announcement->save($res['data']);
-
- $msg = sprintf('Edited announcement #%d', $announcement['Announcement']['id']);
-
- $this->logMessage('announcement', $msg, [
- 'old_announcement' => $announcement['Announcement'],
- 'new_announcement' => $res['data']
- ], $announcement['Announcement']['id']);
- $this->Flash->success($msg.'!');
- } else {
- // Fix the data
- unset($res['data']['id']);
-
- $this->Announcement->create();
- $this->Announcement->save($res['data']);
-
- $msg = sprintf('Created announcement #%d', $this->Announcement->id);
- $this->logMessage('announcement', $msg, [], $this->Announcement->id);
- $this->Flash->success($msg.'!');
- }
-
- return $this->redirect(['plugin' => 'admin', 'controller' => 'site', 'action' => 'index']);
- }
-
- /**
- * Config Delete
- *
- * @url /admin/site/delete//
- */
- public function delete($type='announcement', $id=false) {
- $modal = ($type == 'announcement' ? $this->Announcement : $this->Config);
- $msgType = ($type == 'announcement' ? 'Announcement' : 'Config');
- $logType = ($type == 'announcement' ? 'announcement' : 'config');
-
- $data = $modal->findById($id);
- if ( empty($data) ) {
- throw new NotFoundException('Unknown '.$msgType);
- }
-
- if ( $this->request->is('post') ) {
- $modal->delete($id);
-
- $msg = sprintf('Deleted %s #%d', $msgType, $data[$msgType]['id']);
- $this->logMessage($logType, $msg, [$logType => $data], $id);
- $this->Flash->success($msg.'!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'site', 'action' => 'index']);
- }
-
- $this->set('data', $data);
- }
+
+ public $uses = ['Announcement', 'Config'];
+
+ /**
+ * Config Index Page
+ *
+ * @url /admin/site
+ * @url /admin/site/index
+ */
+ public function index() {
+ $this->set('announce', $this->Announcement->find('all'));
+ $this->set('config', $this->Config->find('all'));
+ }
+
+ /**
+ * Config API Page
+ *
+ * @url /admin/site/api//
+ */
+ public function api($type = 'announcement', $id = false) {
+ switch ($type) {
+ case 'config':
+ $config = $this->Config->findById($id);
+ if (empty($config)) {
+ throw new NotFoundException('Unknown config');
+ }
+
+ $data = $config['Config'];
+ break;
+
+ case 'announcement':
+ $announcement = $this->Announcement->findById($id);
+ if (empty($announcement)) {
+ throw new NotFoundException('Unknown announcement');
+ }
+
+ $data = $announcement['Announcement'];
+ break;
+
+ default:
+ throw new MethodNotAllowedException();
+ }
+
+ return $this->ajaxResponse($data);
+ }
+
+ /**
+ * Config Edit/Create URL
+ *
+ * @url /admin/site/api
+ */
+ public function config() {
+ if (!$this->request->is('post')) {
+ throw new MethodNotAllowedException();
+ }
+
+ // Validate the input
+ $this->validators = [
+ 'id' => new Rules\AllOf(
+ new Rules\Digit()
+ ),
+ 'key' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ 'value' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ ];
+ $res = $this->validate();
+
+ if (!empty($res['errors'])) {
+ $this->errorFlash($res['errors']);
+
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'site', 'action' => 'index']);
+ }
+
+ if ($res['data']['id'] > 0) {
+ $config = $this->Config->findById($res['data']['id']);
+ if (empty($config)) {
+ throw new NotFoundException('Unknown config');
+ }
+
+ $this->Config->id = $res['data']['id'];
+ $this->Config->save($res['data']);
+
+ $msg = sprintf('Edited config value "%s"', $config['Config']['key']);
+
+ $this->logMessage(
+ 'config',
+ $msg,
+ [
+ 'old_config' => $config['Config'],
+ 'new_config' => $res['data']
+ ],
+ $config['Config']['id']
+ );
+ $this->Flash->success($msg.'!');
+ } else {
+ // Fix the data
+ unset($res['data']['id']);
+
+ $this->Config->create();
+ $this->Config->save($res['data']);
+
+ $msg = sprintf('Created config value "%s"', $res['data']['key']);
+ $this->logMessage('config', $msg, [], $this->Config->id);
+ $this->Flash->success($msg.'!');
+ }
+
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'site', 'action' => 'index']);
+ }
+
+ /**
+ * Announcement Edit/Create URL
+ *
+ * @url /admin/site/announcement
+ */
+ public function announcement() {
+ if (!$this->request->is('post')) {
+ throw new MethodNotAllowedException();
+ }
+
+ // Validate the input
+ $this->validators = [
+ 'id' => new Rules\AllOf(
+ new Rules\Digit()
+ ),
+ 'content' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ 'active' => new Rules\AllOf(
+ new Rules\Digit()
+ ),
+ 'expiration' => new Rules\AllOf(
+ new Rules\Digit()
+ ),
+ ];
+ $res = $this->validate();
+
+ if (!empty($res['errors'])) {
+ $this->errorFlash($res['errors']);
+
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'site', 'action' => 'index']);
+ }
+
+ if ($res['data']['id'] > 0) {
+ $announcement = $this->Announcement->findById($res['data']['id']);
+ if (empty($announcement)) {
+ throw new NotFoundException('Unknown announcement');
+ }
+
+ $this->Announcement->id = $res['data']['id'];
+ $this->Announcement->save($res['data']);
+
+ $msg = sprintf('Edited announcement #%d', $announcement['Announcement']['id']);
+
+ $this->logMessage('announcement', $msg, [
+ 'old_announcement' => $announcement['Announcement'],
+ 'new_announcement' => $res['data']
+ ], $announcement['Announcement']['id']);
+ $this->Flash->success($msg.'!');
+ } else {
+ // Fix the data
+ unset($res['data']['id']);
+
+ $this->Announcement->create();
+ $this->Announcement->save($res['data']);
+
+ $msg = sprintf('Created announcement #%d', $this->Announcement->id);
+ $this->logMessage('announcement', $msg, [], $this->Announcement->id);
+ $this->Flash->success($msg.'!');
+ }
+
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'site', 'action' => 'index']);
+ }
+
+ /**
+ * Config Delete
+ *
+ * @url /admin/site/delete//
+ */
+ public function delete($type = 'announcement', $id = false) {
+ $modal = ($type == 'announcement' ? $this->Announcement : $this->Config);
+ $msgType = ($type == 'announcement' ? 'Announcement' : 'Config');
+ $logType = ($type == 'announcement' ? 'announcement' : 'config');
+
+ $data = $modal->findById($id);
+ if (empty($data)) {
+ throw new NotFoundException('Unknown '.$msgType);
+ }
+
+ if ($this->request->is('post')) {
+ $modal->delete($id);
+
+ $msg = sprintf('Deleted %s #%d', $msgType, $data[$msgType]['id']);
+ $this->logMessage($logType, $msg, [$logType => $data], $id);
+ $this->Flash->success($msg.'!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'site', 'action' => 'index']);
+ }
+
+ $this->set('data', $data);
+ }
}
diff --git a/app/Plugin/Admin/Controller/UsersController.php b/app/Plugin/Admin/Controller/UsersController.php
index 8a963c3..1bc1753 100644
--- a/app/Plugin/Admin/Controller/UsersController.php
+++ b/app/Plugin/Admin/Controller/UsersController.php
@@ -3,210 +3,215 @@
use Respect\Validation\Rules;
class UsersController extends AdminAppController {
- public $uses = ['User', 'Group'];
-
- public function beforeFilter() {
- parent::beforeFilter();
-
- $this->validators = [
- 'username' => new Rules\AllOf(
- new Rules\Alnum('-_'),
- new Rules\NotEmpty(),
- new Rules\NoWhitespace()
- ),
- 'password' => new Rules\AlwaysValid(),
- 'group_id' => new Rules\AllOf(
- new Rules\Digit(),
- new Rules\NotEmpty()
- ),
- 'active' => new Rules\AllOf(
- new Rules\BoolVal()
- ),
- 'expiration' => new Rules\AllOf(
- new Rules\Length(1, 10, true)
- ),
- ];
- }
-
- /**
- * User List Page
- *
- * @url /admin/user
- * @url /admin/user/index
- */
- public function index() {
- $this->set('users', $this->User->find('all', [
- 'fields' => [
- 'User.id', 'User.username', 'User.expiration', 'User.active', 'Group.name'
- ],
- ]));
- }
-
- /**
- * Emulate User
- *
- * @url /admin/user/emulate/
- */
- public function emulate($uidOrUsername=false) {
- try {
- $curUID = $this->Auth->user('id');
-
- $this->Auth->emulate($uidOrUsername);
-
- $msg = sprintf('Emulated user %s', $this->Auth->user('username'));
- $this->logMessage('emulate', $msg, [], $this->Auth->user('id'), $curUID);
- $this->Flash->success($msg.'!');
-
- return $this->redirect('/');
- } catch ( InternalErrorException $e ) {
- throw $e;
- }
- }
-
- /**
- * Create User
- *
- * @url /admin/user/create
- */
- public function create() {
- if ( $this->request->is('post') ) {
- // Validate the input
- $res = $this->_validate();
-
- if ( empty($res['errors']) ) {
- $this->User->create();
- $this->User->save($res['data']);
-
- $this->logMessage(
- 'users',
- sprintf('Created user "%s"', $res['data']['username']),
- [],
- $this->User->id
- );
-
- $this->Flash->success('The user has been created!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'users', 'action' => 'index']);
- } else {
- $this->_errorFlash($res['errors']);
- }
- }
-
- $this->set('groups', $this->Group->generateTreeList(null, null, null, '-- '));
- }
-
- /**
- * Edit User
- *
- * @url /adminuser/edit/
- * @url /admin/user/edit/
- */
- public function edit($uid=false) {
- $user = $this->User->findById($uid);
- if ( empty($user) ) {
- throw new NotFoundException('Unknown user');
- }
-
- if ( $this->request->is('post') ) {
- // Validate the input
- $res = $this->_validate();
-
- if ( empty($res['errors']) ) {
- // Clear out the password, if it's empty
- if ( empty($res['data']['password']) ) {
- unset($res['data']['password']);
- }
-
- $this->User->id = $uid;
- $this->User->save($res['data']);
-
- // Redact the old password
- $user['User']['password'] = '-redacted-';
-
- // ...and the new one
- if ( isset($res['data']['password']) ) {
- $res['data']['password'] = '-redacted-';
- }
-
- $this->logMessage(
- 'users',
- sprintf('Updated user "%s"', $user['User']['username']),
- [
- 'old_user' => $user['User'],
- 'new_user' => $res['data'],
- ],
- $uid
- );
-
- $this->Flash->success('The user has been updated!');
- return $this->redirect(['plugin' => 'admin', 'controller' => 'users', 'action' => 'index']);
- } else {
- $this->_errorFlash($res['errors']);
- }
- }
-
- $this->set('groups', $this->Group->generateTreeList(null, null, null, '-- '));
- $this->set('user', $user);
- }
-
- /**
- * Delete User
- *
- * @url /admin/user/delete/
- */
- public function delete($uid=false) {
- $user = $this->User->findById($uid);
- if ( empty($user) ) {
- throw new NotFoundException('Unknown user');
- }
-
- if ( $this->request->is('post') ) {
- $this->User->delete($uid);
-
- $msg = sprintf('Deleted user "%s" (#%d)', $user['User']['username'], $uid);
-
- $this->logMessage(
- 'users',
- $msg,
- [
- 'user' => $user['User'],
- ],
- $uid
- );
-
- $this->Flash->success($msg);
- return $this->redirect(['plugin' => 'admin', 'controller' => 'users', 'action' => 'index']);
- }
-
- $this->set('user', $user);
- }
-
- /**
- * Toggle User Status
- *
- * @url /admin/user/flip/
- */
- public function flip($uid=false) {
- $user = $this->User->findById($uid);
- if ( empty($user) ) {
- throw new NotFoundException('Unknown user');
- }
-
- $this->User->id = $uid;
- $this->User->save([
- 'active' => !$user['User']['active'],
- ]);
-
- $this->logMessage(
- 'users',
- sprintf('Flipped the status user "%s" to %sactive', $user['User']['username'], $user['User']['active'] ? 'in' : ''),
- [
- 'old_status' => $user['User']['active'],
- 'new_status' => !$user['User']['active'],
- ],
- $uid
- );
-
- $this->Flash->success(sprintf('Toggled status for user %s!', $user['User']['username']));
- return $this->redirect(['plugin' => 'admin', 'controller' => 'users', 'action' => 'index']);
- }
+
+ public $uses = ['User', 'Group'];
+
+ public function beforeFilter() {
+ parent::beforeFilter();
+
+ $this->validators = [
+ 'username' => new Rules\AllOf(
+ new Rules\Alnum('-_'),
+ new Rules\NotEmpty(),
+ new Rules\NoWhitespace()
+ ),
+ 'password' => new Rules\AlwaysValid(),
+ 'group_id' => new Rules\AllOf(
+ new Rules\Digit(),
+ new Rules\NotEmpty()
+ ),
+ 'active' => new Rules\AllOf(
+ new Rules\BoolVal()
+ ),
+ 'expiration' => new Rules\AllOf(
+ new Rules\Length(1, 10, true)
+ ),
+ ];
+ }
+
+ /**
+ * User List Page
+ *
+ * @url /admin/user
+ * @url /admin/user/index
+ */
+ public function index() {
+ $this->set('users', $this->User->find('all', [
+ 'fields' => [
+ 'User.id', 'User.username', 'User.expiration', 'User.active', 'Group.name'
+ ],
+ ]));
+ }
+
+ /**
+ * Emulate User
+ *
+ * @url /admin/user/emulate/
+ */
+ public function emulate($uidOrUsername = false) {
+ try {
+ $curUID = $this->Auth->user('id');
+
+ $this->Auth->emulate($uidOrUsername);
+
+ $msg = sprintf('Emulated user %s', $this->Auth->user('username'));
+ $this->logMessage('emulate', $msg, [], $this->Auth->user('id'), $curUID);
+ $this->Flash->success($msg.'!');
+
+ return $this->redirect('/');
+ } catch (InternalErrorException $e) {
+ throw $e;
+ }
+ }
+
+ /**
+ * Create User
+ *
+ * @url /admin/user/create
+ */
+ public function create() {
+ if ($this->request->is('post')) {
+ // Validate the input
+ $res = $this->validate();
+
+ if (empty($res['errors'])) {
+ $this->User->create();
+ $this->User->save($res['data']);
+
+ $this->logMessage(
+ 'users',
+ sprintf('Created user "%s"', $res['data']['username']),
+ [],
+ $this->User->id
+ );
+
+ $this->Flash->success('The user has been created!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'users', 'action' => 'index']);
+ } else {
+ $this->errorFlash($res['errors']);
+ }
+ }
+
+ $this->set('groups', $this->Group->generateTreeList(null, null, null, '-- '));
+ }
+
+ /**
+ * Edit User
+ *
+ * @url /adminuser/edit/
+ * @url /admin/user/edit/
+ */
+ public function edit($uid = false) {
+ $user = $this->User->findById($uid);
+ if (empty($user)) {
+ throw new NotFoundException('Unknown user');
+ }
+
+ if ($this->request->is('post')) {
+ // Validate the input
+ $res = $this->validate();
+
+ if (empty($res['errors'])) {
+ // Clear out the password, if it's empty
+ if (empty($res['data']['password'])) {
+ unset($res['data']['password']);
+ }
+
+ $this->User->id = $uid;
+ $this->User->save($res['data']);
+
+ // Redact the old password
+ $user['User']['password'] = '-redacted-';
+
+ // ...and the new one
+ if (isset($res['data']['password'])) {
+ $res['data']['password'] = '-redacted-';
+ }
+
+ $this->logMessage(
+ 'users',
+ sprintf('Updated user "%s"', $user['User']['username']),
+ [
+ 'old_user' => $user['User'],
+ 'new_user' => $res['data'],
+ ],
+ $uid
+ );
+
+ $this->Flash->success('The user has been updated!');
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'users', 'action' => 'index']);
+ } else {
+ $this->errorFlash($res['errors']);
+ }
+ }
+
+ $this->set('groups', $this->Group->generateTreeList(null, null, null, '-- '));
+ $this->set('user', $user);
+ }
+
+ /**
+ * Delete User
+ *
+ * @url /admin/user/delete/
+ */
+ public function delete($uid = false) {
+ $user = $this->User->findById($uid);
+ if (empty($user)) {
+ throw new NotFoundException('Unknown user');
+ }
+
+ if ($this->request->is('post')) {
+ $this->User->delete($uid);
+
+ $msg = sprintf('Deleted user "%s" (#%d)', $user['User']['username'], $uid);
+
+ $this->logMessage(
+ 'users',
+ $msg,
+ [
+ 'user' => $user['User'],
+ ],
+ $uid
+ );
+
+ $this->Flash->success($msg);
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'users', 'action' => 'index']);
+ }
+
+ $this->set('user', $user);
+ }
+
+ /**
+ * Toggle User Status
+ *
+ * @url /admin/user/flip/
+ */
+ public function flip($uid = false) {
+ $user = $this->User->findById($uid);
+ if (empty($user)) {
+ throw new NotFoundException('Unknown user');
+ }
+
+ $this->User->id = $uid;
+ $this->User->save([
+ 'active' => !$user['User']['active'],
+ ]);
+
+ $this->logMessage(
+ 'users',
+ sprintf(
+ 'Flipped the status user "%s" to %sactive',
+ $user['User']['username'],
+ $user['User']['active'] ? 'in' : ''
+ ),
+ [
+ 'old_status' => $user['User']['active'],
+ 'new_status' => !$user['User']['active'],
+ ],
+ $uid
+ );
+
+ $this->Flash->success(sprintf('Toggled status for user %s!', $user['User']['username']));
+ return $this->redirect(['plugin' => 'admin', 'controller' => 'users', 'action' => 'index']);
+ }
}
diff --git a/app/Plugin/BankWeb/Config/Schema/schema.php b/app/Plugin/BankWeb/Config/Schema/schema.php
index 9896ba1..a973506 100644
--- a/app/Plugin/BankWeb/Config/Schema/schema.php
+++ b/app/Plugin/BankWeb/Config/Schema/schema.php
@@ -2,54 +2,56 @@
App::uses('ClassRegistry', 'Utility');
class BankWebSchema extends CakeSchema {
- public $account_mappings = [
- 'id' => [
- 'type' => 'integer',
- 'null' => false,
- 'key' => 'primary',
- ],
- 'group_id' => [
- 'type' => 'integer',
- 'null' => false,
- ],
- 'username' => [
- 'type' => 'text',
- ],
- 'password' => [
- 'type' => 'text',
- ],
-
- 'indexes' => [
- 'PRIMARY' => ['column' => 'id', 'unqiue' => true],
- ],
- ];
-
- // ================================
-
- public function before($event = array()) {
- ConnectionManager::getDataSource('default')->cacheSources = false;
-
- return true;
- }
-
- public function after($event = array()) {
- if ( !isset($event['create']) ) return;
-
- switch ( $event['create'] ) {
- case 'account_mappings':
- $this->_create('AccountMapping', [
- 'group_id' => env('GROUP_STAFF'),
- 'username' => 'admin',
- 'password' => 'admin',
- ]);
- break;
- }
- }
-
- private function _create($tbl, $data) {
- $table = ClassRegistry::init($tbl);
-
- $table->create();
- $table->save(array($tbl => $data));
- }
-}
\ No newline at end of file
+
+ public $account_mappings = [
+ 'id' => [
+ 'type' => 'integer',
+ 'null' => false,
+ 'key' => 'primary',
+ ],
+ 'group_id' => [
+ 'type' => 'integer',
+ 'null' => false,
+ ],
+ 'username' => [
+ 'type' => 'text',
+ ],
+ 'password' => [
+ 'type' => 'text',
+ ],
+
+ 'indexes' => [
+ 'PRIMARY' => ['column' => 'id', 'unqiue' => true],
+ ],
+ ];
+
+ // ================================
+
+ public function before($event = []) {
+ ConnectionManager::getDataSource('default')->cacheSources = false;
+
+ return true;
+ }
+
+ public function after($event = []) {
+ if (!isset($event['create'])) { return;
+ }
+
+ switch ($event['create']) {
+ case 'account_mappings':
+ $this->create('AccountMapping', [
+ 'group_id' => env('GROUP_STAFF'),
+ 'username' => 'admin',
+ 'password' => 'admin',
+ ]);
+ break;
+ }
+ }
+
+ private function create($tbl, $data) {
+ $table = ClassRegistry::init($tbl);
+
+ $table->create();
+ $table->save([$tbl => $data]);
+ }
+}
diff --git a/app/Plugin/BankWeb/Config/routes.php b/app/Plugin/BankWeb/Config/routes.php
index 6091cfa..8a1f893 100644
--- a/app/Plugin/BankWeb/Config/routes.php
+++ b/app/Plugin/BankWeb/Config/routes.php
@@ -16,4 +16,3 @@
Router::connect('/bank/:controller', ['plugin' => 'BankWeb']);
Router::connect('/bank/:controller/:action', ['plugin' => 'BankWeb']);
Router::connect('/bank/:controller/:action/**', ['plugin' => 'BankWeb']);
-
diff --git a/app/Plugin/BankWeb/Controller/AccountController.php b/app/Plugin/BankWeb/Controller/AccountController.php
index f64178b..856155c 100644
--- a/app/Plugin/BankWeb/Controller/AccountController.php
+++ b/app/Plugin/BankWeb/Controller/AccountController.php
@@ -3,133 +3,134 @@
class AccountController extends BankWebAppController {
- public function beforeFilter() {
- parent::beforeFilter();
-
- // Set the active menu item
- $this->set('at_team', true);
- }
-
- /**
- * Account List Page
- *
- * @url /bank/account
- * @url /bank/account/index
- */
- public function index() {
- $this->set('accounts', $this->BankApi->accounts());
- }
-
- /**
- * Account Create
- *
- * @url /bank/account/create
- */
- public function create() {
- if ( !$this->request->is('post') || !isset($this->request->data['pin']) || !is_numeric($this->request->data['pin']) ) {
- $this->Flash->danger('Please ensure your PIN is numeric!');
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
- }
-
- try {
- $res = $this->BankApi->newAccount($this->request->data['pin']);
- } catch ( Exception $e ) {
- $this->Flash->danger($e->getMessage());
- }
-
- if ( $res === true ) {
- $this->Flash->success('Created new account!');
- }
-
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
- }
-
- /**
- * Transfer Money
- *
- * @url /bank/account/transfer/
- */
- public function transfer($id=false) {
- if ( $id === false || !is_numeric($id) ) {
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
- }
-
- if (
- $this->request->is('post') &&
- isset($this->request->data['srcAcc']) &&
- is_numeric($this->request->data['srcAcc']) &&
- isset($this->request->data['dstAcc']) &&
- is_numeric($this->request->data['dstAcc']) &&
- isset($this->request->data['amount']) &&
- is_numeric($this->request->data['amount']) &&
- isset($this->request->data['pin']) &&
- is_numeric($this->request->data['pin'])
- ) {
- try {
- $res = $this->BankApi->transfer(
- $this->request->data['srcAcc'],
- $this->request->data['dstAcc'],
- $this->request->data['amount'],
- $this->request->data['pin']
- );
- } catch ( Exception $e ) {
- $this->Flash->danger($e->getMessage());
- }
-
- if ( $res === true ) {
- $this->Flash->success('Successfully transferred money!');
- }
-
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
- }
-
- $this->set('acc', htmlentities($id));
- }
-
- /**
- * Transactions List
- *
- * @url /bank/account/transactions/
- */
- public function transactions($id=false) {
- if ( $id === false || !is_numeric($id) ) {
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
- }
-
- $this->set('account', htmlentities($id));
- $this->set('logs', $this->BankApi->transfers($id));
- }
-
- /**
- * Account PIN Change
- *
- * @url /bank/account/pin/
- */
- public function pin($id=false) {
- if ( $id === false || !is_numeric($id) ) {
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
- }
-
- if (
- $this->request->is('post') &&
- isset($this->request->data['pin']) &&
- is_numeric($this->request->data['pin']) &&
- isset($this->request->data['newpin']) &&
- is_numeric($this->request->data['newpin'])
- ) {
- try {
- $res = $this->BankApi->changePin($id, $this->request->data['pin'], $this->request->data['newpin']);
- } catch ( Exception $e ) {
- $this->Flash->danger($e->getMessage());
- }
-
- if ( $res === true ) {
- $this->Flash->success('Successfully updated pin!');
- }
-
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
- }
-
- $this->set('account', htmlentities($id));
- }
-}
\ No newline at end of file
+ public function beforeFilter() {
+ parent::beforeFilter();
+
+ // Set the active menu item
+ $this->set('at_team', true);
+ }
+
+ /**
+ * Account List Page
+ *
+ * @url /bank/account
+ * @url /bank/account/index
+ */
+ public function index() {
+ $this->set('accounts', $this->BankApi->accounts());
+ }
+
+ /**
+ * Account Create
+ *
+ * @url /bank/account/create
+ */
+ public function create() {
+ if (!$this->request->is('post')
+ || !isset($this->request->data['pin'])
+ || !is_numeric($this->request->data['pin'])
+ ) {
+ $this->Flash->danger('Please ensure your PIN is numeric!');
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
+ }
+
+ try {
+ $res = $this->BankApi->newAccount($this->request->data['pin']);
+ } catch (Exception $e) {
+ $this->Flash->danger($e->getMessage());
+ }
+
+ if ($res === true) {
+ $this->Flash->success('Created new account!');
+ }
+
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
+ }
+
+ /**
+ * Transfer Money
+ *
+ * @url /bank/account/transfer/
+ */
+ public function transfer($id = false) {
+ if ($id === false || !is_numeric($id)) {
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
+ }
+
+ if ($this->request->is('post')
+ && isset($this->request->data['srcAcc'])
+ && is_numeric($this->request->data['srcAcc'])
+ && isset($this->request->data['dstAcc'])
+ && is_numeric($this->request->data['dstAcc'])
+ && isset($this->request->data['amount'])
+ && is_numeric($this->request->data['amount'])
+ && isset($this->request->data['pin'])
+ && is_numeric($this->request->data['pin'])
+ ) {
+ try {
+ $res = $this->BankApi->transfer(
+ $this->request->data['srcAcc'],
+ $this->request->data['dstAcc'],
+ $this->request->data['amount'],
+ $this->request->data['pin']
+ );
+ } catch (Exception $e) {
+ $this->Flash->danger($e->getMessage());
+ }
+
+ if ($res === true) {
+ $this->Flash->success('Successfully transferred money!');
+ }
+
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
+ }
+
+ $this->set('acc', htmlentities($id));
+ }
+
+ /**
+ * Transactions List
+ *
+ * @url /bank/account/transactions/
+ */
+ public function transactions($id = false) {
+ if ($id === false || !is_numeric($id)) {
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
+ }
+
+ $this->set('account', htmlentities($id));
+ $this->set('logs', $this->BankApi->transfers($id));
+ }
+
+ /**
+ * Account PIN Change
+ *
+ * @url /bank/account/pin/
+ */
+ public function pin($id = false) {
+ if ($id === false || !is_numeric($id)) {
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
+ }
+
+ if ($this->request->is('post')
+ && isset($this->request->data['pin'])
+ && is_numeric($this->request->data['pin'])
+ && isset($this->request->data['newpin'])
+ && is_numeric($this->request->data['newpin'])
+ ) {
+ try {
+ $res = $this->BankApi->changePin($id, $this->request->data['pin'], $this->request->data['newpin']);
+ } catch (Exception $e) {
+ $this->Flash->danger($e->getMessage());
+ }
+
+ if ($res === true) {
+ $this->Flash->success('Successfully updated pin!');
+ }
+
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'account', 'action' => 'index']);
+ }
+
+ $this->set('account', htmlentities($id));
+ }
+}
diff --git a/app/Plugin/BankWeb/Controller/BankWebAppController.php b/app/Plugin/BankWeb/Controller/BankWebAppController.php
index fffcd5c..ee45ebe 100644
--- a/app/Plugin/BankWeb/Controller/BankWebAppController.php
+++ b/app/Plugin/BankWeb/Controller/BankWebAppController.php
@@ -2,21 +2,23 @@
App::uses('AppController', 'Controller');
class BankWebAppController extends AppController {
- public $components = ['BankWeb.BankApi'];
- public $uses = ['BankWeb.AccountMapping'];
- public function beforeFilter() {
- parent::beforeFilter();
+ public $components = ['BankWeb.BankApi'];
- // Ensure logins
- $this->Auth->protect();
+ public $uses = ['BankWeb.AccountMapping'];
- // Grab the account + set the credentials for the API
- $account = $this->AccountMapping->getAccount($this->Auth->item('groups'));
-
- if ( empty($account) ) {
- throw new BadRequestException('You do not have a bank account associated with your user/groups');
- }
- $this->BankApi->setCredentials($account['AccountMapping']['username'], $account['AccountMapping']['password']);
- }
-}
\ No newline at end of file
+ public function beforeFilter() {
+ parent::beforeFilter();
+
+ // Ensure logins
+ $this->Auth->protect();
+
+ // Grab the account + set the credentials for the API
+ $account = $this->AccountMapping->getAccount($this->Auth->item('groups'));
+
+ if (empty($account)) {
+ throw new BadRequestException('You do not have a bank account associated with your user/groups');
+ }
+ $this->BankApi->setCredentials($account['AccountMapping']['username'], $account['AccountMapping']['password']);
+ }
+}
diff --git a/app/Plugin/BankWeb/Controller/BankadminController.php b/app/Plugin/BankWeb/Controller/BankadminController.php
index 1086f7f..071b6f5 100644
--- a/app/Plugin/BankWeb/Controller/BankadminController.php
+++ b/app/Plugin/BankWeb/Controller/BankadminController.php
@@ -3,127 +3,136 @@
use Respect\Validation\Rules;
class BankadminController extends BankWebAppController {
- public $uses = ['Group', 'BankWeb.AccountMapping'];
-
- public function beforeFilter() {
- parent::beforeFilter();
-
- // Set the active menu item
- $this->set('at_backend', true);
-
- // Setup validators
- $this->validators = [
- 'id' => new Rules\AllOf(
- new Rules\Digit()
- ),
- 'group_id' => new Rules\AllOf(
- new Rules\Digit()
- ),
- 'username' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- 'password' => new Rules\AllOf(
- new Rules\NotEmpty()
- ),
- ];
- }
-
- /**
- * BankWEB Admin Index Page
- *
- * @url /admin/bank
- * @url /bank_web/admin
- * @url /admin/bank/index
- * @url /bank_web/admin/index
- */
- public function index() {
- $this->set('groups', $this->Group->generateTreeList(null, null, null, '--'));
- $this->set('accounts', $this->AccountMapping->find('all'));
- }
-
- /**
- * BankWEB Admin API
- *
- * @url /admin/bank/api/
- * @url /bank_web/admin/api/
- */
- public function api($id=false) {
- $data = $this->AccountMapping->findById($id);
- if ( empty($data) ) {
- throw new NotFoundException('Unknown account');
- }
-
- return $this->ajaxResponse($data['AccountMapping']);
- }
-
- /**
- * BankWEB Credentials Save
- *
- * @url /admin/bank/save
- * @url /bank_web/admin/save
- */
- public function save() {
- if ( !$this->request->is('post') ) {
- throw new MethodNotAllowedException();
- }
-
- // Validate the input
- $res = $this->_validate();
-
- if ( !empty($res['errors']) ) {
- $this->_errorFlash($res['errors']);
-
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'bankadmin', 'action' => 'index']);
- }
-
- if ( $res['data']['id'] > 0 ) {
- $data = $this->AccountMapping->findById($res['data']['id']);
- if ( empty($data) ) {
- throw new NotFoundException('Unknown account mapping');
- }
-
- $this->AccountMapping->id = $res['data']['id'];
- $this->AccountMapping->save($res['data']);
-
- $msg = sprintf('Edited account mapping for user "%s"', $data['AccountMapping']['username']);
-
- $this->logMessage('bank', $msg, ['old_mapping' => $data['AccountMapping'], 'new_mapping' => $res['data']], $data['AccountMapping']['id']);
- $this->Flash->success($msg.'!');
- } else {
- // Fix the data
- unset($res['data']['id']);
-
- $this->AccountMapping->create();
- $this->AccountMapping->save($res['data']);
-
- $msg = sprintf('Created account mapping on user "%s"', $res['data']['username']);
- $this->logMessage('bank', $msg, [], $this->AccountMapping->id);
- $this->Flash->success($msg.'!');
- }
-
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'bankadmin', 'action' => 'index']);
- }
-
- /**
- * BankWEB Account Mapping Delete
- *
- * @url /admin/bank/delete//
- */
- public function delete($id=false) {
- $data = $this->AccountMapping->findById($id);
- if ( empty($data) ) {
- throw new NotFoundException('Unknown acount');
- }
-
- if ( $this->request->is('post') ) {
- $this->AccountMapping->delete($id);
-
- $msg = sprintf('Deleted account mapping for user "%s"', $data['AccountMapping']['username']);
- $this->logMessage('bank', $msg, ['mapping' => $data], $id);
- $this->Flash->success($msg.'!');
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'bankadmin', 'action' => 'index']);
- }
-
- $this->set('data', $data);
- }
+
+ public $uses = ['Group', 'BankWeb.AccountMapping'];
+
+ public function beforeFilter() {
+ parent::beforeFilter();
+
+ // Set the active menu item
+ $this->set('at_backend', true);
+
+ // Setup validators
+ $this->validators = [
+ 'id' => new Rules\AllOf(
+ new Rules\Digit()
+ ),
+ 'group_id' => new Rules\AllOf(
+ new Rules\Digit()
+ ),
+ 'username' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ 'password' => new Rules\AllOf(
+ new Rules\NotEmpty()
+ ),
+ ];
+ }
+
+ /**
+ * BankWEB Admin Index Page
+ *
+ * @url /admin/bank
+ * @url /bank_web/admin
+ * @url /admin/bank/index
+ * @url /bank_web/admin/index
+ */
+ public function index() {
+ $this->set('groups', $this->Group->generateTreeList(null, null, null, '--'));
+ $this->set('accounts', $this->AccountMapping->find('all'));
+ }
+
+ /**
+ * BankWEB Admin API
+ *
+ * @url /admin/bank/api/
+ * @url /bank_web/admin/api/
+ */
+ public function api($id = false) {
+ $data = $this->AccountMapping->findById($id);
+ if (empty($data)) {
+ throw new NotFoundException('Unknown account');
+ }
+
+ return $this->ajaxResponse($data['AccountMapping']);
+ }
+
+ /**
+ * BankWEB Credentials Save
+ *
+ * @url /admin/bank/save
+ * @url /bank_web/admin/save
+ */
+ public function save() {
+ if (!$this->request->is('post')) {
+ throw new MethodNotAllowedException();
+ }
+
+ // Validate the input
+ $res = $this->validate();
+
+ if (!empty($res['errors'])) {
+ $this->errorFlash($res['errors']);
+
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'bankadmin', 'action' => 'index']);
+ }
+
+ if ($res['data']['id'] > 0) {
+ $data = $this->AccountMapping->findById($res['data']['id']);
+ if (empty($data)) {
+ throw new NotFoundException('Unknown account mapping');
+ }
+
+ $this->AccountMapping->id = $res['data']['id'];
+ $this->AccountMapping->save($res['data']);
+
+ $msg = sprintf('Edited account mapping for user "%s"', $data['AccountMapping']['username']);
+
+ $this->logMessage(
+ 'bank',
+ $msg,
+ [
+ 'old_mapping' => $data['AccountMapping'],
+ 'new_mapping' => $res['data']
+ ],
+ $data['AccountMapping']['id']
+ );
+ $this->Flash->success($msg.'!');
+ } else {
+ // Fix the data
+ unset($res['data']['id']);
+
+ $this->AccountMapping->create();
+ $this->AccountMapping->save($res['data']);
+
+ $msg = sprintf('Created account mapping on user "%s"', $res['data']['username']);
+ $this->logMessage('bank', $msg, [], $this->AccountMapping->id);
+ $this->Flash->success($msg.'!');
+ }
+
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'bankadmin', 'action' => 'index']);
+ }
+
+ /**
+ * BankWEB Account Mapping Delete
+ *
+ * @url /admin/bank/delete//
+ */
+ public function delete($id = false) {
+ $data = $this->AccountMapping->findById($id);
+ if (empty($data)) {
+ throw new NotFoundException('Unknown acount');
+ }
+
+ if ($this->request->is('post')) {
+ $this->AccountMapping->delete($id);
+
+ $msg = sprintf('Deleted account mapping for user "%s"', $data['AccountMapping']['username']);
+ $this->logMessage('bank', $msg, ['mapping' => $data], $id);
+ $this->Flash->success($msg.'!');
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'bankadmin', 'action' => 'index']);
+ }
+
+ $this->set('data', $data);
+ }
}
diff --git a/app/Plugin/BankWeb/Controller/Component/BankApiComponent.php b/app/Plugin/BankWeb/Controller/Component/BankApiComponent.php
index 7221d2c..5c071e8 100644
--- a/app/Plugin/BankWeb/Controller/Component/BankApiComponent.php
+++ b/app/Plugin/BankWeb/Controller/Component/BankApiComponent.php
@@ -2,221 +2,223 @@
App::uses('Component', 'Controller');
class BankApiComponent extends Component {
- private $server;
- private $timeout;
-
- private $username = null;
- private $password = null;
- private $session = null;
-
- /**
- * BankAPI Initialize Hook
- *
- * Sets up a bunch of settings
- */
- public function initialize(Controller $controller) {
- $this->server = env('BANKAPI_SERVER');
- $this->timeout = env('BANKAPI_TIMEOUT');
- }
-
- /**
- * Set Credentials
- *
- * Saves the user/pass for any future
- * requests done by this component
- *
- * @param $user The username
- * @param $pass The password
- * @return void
- */
- public function setCredentials($user, $pass) {
- $this->username = $user;
- $this->password = $pass;
- }
-
- /**
- * Login
- *
- * Attempts a login request
- *
- * @return string/bool True if it worked. A string with
- * the message if it doesn't.
- */
- public function login() {
- $result = $this->request('login', ['username' => $this->username, 'password' => $this->password]);
-
- if ( $result['code'] != 200 ) {
- throw new BankException('Bank Error: '.$result['message']);
- }
-
- $this->session = $result['session'];
- return true;
- }
-
- /**
- * Transfer Money
- *
- * @param $src The source account
- * @param $dst The dest account
- * @param $amt The amount to transfer
- * @param $pin The source account pin
- * @return bool/string True if it worked. A string
- * with the message if it doesn't.
- */
- public function transfer($src, $dst, $amt, $pin) {
- if ( $this->session == null ) {
- $this->login();
- }
-
- $result = $this->request('transfer', [
- 'session' => $this->session,
- 'src' => $src,
- 'dst' => $dst,
- 'amount' => $amt,
- 'pin' => $pin,
- ]);
-
- if ( $result['code'] != 200 ) {
- throw new BankException('Bank Error: '.$result['message']);
- }
- return true;
- }
-
- /**
- * Get All Transfers
- *
- * @param $account The account you wish to view
- * logs for.
- * @return array/string Array of logs if it worked. A string
- * with the message if it doesn't.
- */
- public function transfers($account) {
- if ( $this->session == null ) {
- $this->login();
- }
-
- $result = $this->request('transfers', [
- 'session' => $this->session,
- 'account' => $account,
- ]);
-
- if ( $result['code'] != 200 ) {
- throw new BankException('Bank Error: '.$result['message']);
- }
- return $result['transactions'];
- }
-
- /**
- * Change PIN
- *
- * @param $account The account you wish to change the pin for
- * @param $oldPin The old pin
- * @param $newPin The new pin
- * @return bool/string True if it worked. A string
- * with the message if it doesn't.
- */
- public function changePin($account, $oldPin, $newPin) {
- if ( $this->session == null ) {
- $this->login();
- }
-
- $result = $this->request('changePin', [
- 'session' => $this->session,
- 'account' => $account,
- 'pin' => $oldPin,
- 'newpin' => $newPin,
- ]);
-
- if ( $result['code'] != 200 ) {
- throw new BankException('Bank Error: '.$result['message']);
- }
- return true;
- }
-
- /**
- * Account List
- *
- * @return array/string Array of accounts if it worked. A string
- * with the message if it doesn't.
- */
- public function accounts() {
- if ( $this->session == null ) {
- $this->login();
- }
-
- $result = $this->request('accounts', [
- 'session' => $this->session,
- ]);
-
- if ( $result['code'] != 200 ) {
- throw new BankException('Bank Error: '.$result['message']);
- }
- return $result['accounts'];
- }
-
- /**
- * Create Account
- *
- * @param $pin The pin number
- * @return bool/string True if it worked. A string
- * with the message if it doesn't.
- */
- public function newAccount($pin) {
- if ( $this->session == null ) {
- $this->login();
- }
-
- $result = $this->request('newAccount', [
- 'session' => $this->session,
- 'pin' => $pin,
- ]);
-
- if ( $result['code'] != 200 ) {
- throw new BankException('Bank Error: '.$result['message']);
- }
- return true;
- }
-
-
- /**
- * API Request
- *
- * General function to make an API request
- * to the BankAPI
- *
- * @param $endpoint The endpoint you wish to dall
- * @param $data An array of post data
- * @return An array with a data
- */
- public function request($endpoint, $data) {
- $postData = [];
- foreach ( $data AS $k => $v ) {
- $postData[] = sprintf('%s=%s', urlencode($k), urlencode($v));
- }
-
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, sprintf('%s/%s', $this->server, $endpoint));
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&', $postData));
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-
- // Set the UA to the app version
- list($version_short, $version_long) = Cache::read('version');
- curl_setopt($ch,CURLOPT_USERAGENT, 'ie2/BankWeb @ '.$version_short);
-
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);
- curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
-
- $result = curl_exec($ch);
-
- curl_close($ch);
-
- if ( $result === false ) {
- throw new RuntimeException('Failed to contact the BankAPI Server. Please try again later.');
- }
-
- return json_decode($result, true);
- }
-}
-class BankException extends InternalErrorException { }
\ No newline at end of file
+ private $server;
+
+ private $timeout;
+
+ private $username = null;
+
+ private $password = null;
+
+ private $session = null;
+
+ /**
+ * BankAPI Initialize Hook
+ *
+ * Sets up a bunch of settings
+ */
+ public function initialize(Controller $controller) {
+ $this->server = env('BANKAPI_SERVER');
+ $this->timeout = env('BANKAPI_TIMEOUT');
+ }
+
+ /**
+ * Set Credentials
+ *
+ * Saves the user/pass for any future
+ * requests done by this component
+ *
+ * @param $user The username
+ * @param $pass The password
+ * @return void
+ */
+ public function setCredentials($user, $pass) {
+ $this->username = $user;
+ $this->password = $pass;
+ }
+
+ /**
+ * Login
+ *
+ * Attempts a login request
+ *
+ * @return string/bool True if it worked. A string with
+ * the message if it doesn't.
+ */
+ public function login() {
+ $result = $this->request('login', ['username' => $this->username, 'password' => $this->password]);
+
+ if ($result['code'] != 200) {
+ throw new InternalErrorException('Bank Error: '.$result['message']);
+ }
+
+ $this->session = $result['session'];
+ return true;
+ }
+
+ /**
+ * Transfer Money
+ *
+ * @param $src The source account
+ * @param $dst The dest account
+ * @param $amt The amount to transfer
+ * @param $pin The source account pin
+ * @return bool/string True if it worked. A string
+ * with the message if it doesn't.
+ */
+ public function transfer($src, $dst, $amt, $pin) {
+ if ($this->session == null) {
+ $this->login();
+ }
+
+ $result = $this->request('transfer', [
+ 'session' => $this->session,
+ 'src' => $src,
+ 'dst' => $dst,
+ 'amount' => $amt,
+ 'pin' => $pin,
+ ]);
+
+ if ($result['code'] != 200) {
+ throw new InternalErrorException('Bank Error: '.$result['message']);
+ }
+ return true;
+ }
+
+ /**
+ * Get All Transfers
+ *
+ * @param $account The account you wish to view
+ * logs for.
+ * @return array/string Array of logs if it worked. A string
+ * with the message if it doesn't.
+ */
+ public function transfers($account) {
+ if ($this->session == null) {
+ $this->login();
+ }
+
+ $result = $this->request('transfers', [
+ 'session' => $this->session,
+ 'account' => $account,
+ ]);
+
+ if ($result['code'] != 200) {
+ throw new InternalErrorException('Bank Error: '.$result['message']);
+ }
+ return $result['transactions'];
+ }
+
+ /**
+ * Change PIN
+ *
+ * @param $account The account you wish to change the pin for
+ * @param $oldPin The old pin
+ * @param $newPin The new pin
+ * @return bool/string True if it worked. A string
+ * with the message if it doesn't.
+ */
+ public function changePin($account, $oldPin, $newPin) {
+ if ($this->session == null) {
+ $this->login();
+ }
+
+ $result = $this->request('changePin', [
+ 'session' => $this->session,
+ 'account' => $account,
+ 'pin' => $oldPin,
+ 'newpin' => $newPin,
+ ]);
+
+ if ($result['code'] != 200) {
+ throw new InternalErrorException('Bank Error: '.$result['message']);
+ }
+ return true;
+ }
+
+ /**
+ * Account List
+ *
+ * @return array/string Array of accounts if it worked. A string
+ * with the message if it doesn't.
+ */
+ public function accounts() {
+ if ($this->session == null) {
+ $this->login();
+ }
+
+ $result = $this->request('accounts', [
+ 'session' => $this->session,
+ ]);
+
+ if ($result['code'] != 200) {
+ throw new InternalErrorException('Bank Error: '.$result['message']);
+ }
+ return $result['accounts'];
+ }
+
+ /**
+ * Create Account
+ *
+ * @param $pin The pin number
+ * @return bool/string True if it worked. A string
+ * with the message if it doesn't.
+ */
+ public function newAccount($pin) {
+ if ($this->session == null) {
+ $this->login();
+ }
+
+ $result = $this->request('newAccount', [
+ 'session' => $this->session,
+ 'pin' => $pin,
+ ]);
+
+ if ($result['code'] != 200) {
+ throw new InternalErrorException('Bank Error: '.$result['message']);
+ }
+ return true;
+ }
+
+
+ /**
+ * API Request
+ *
+ * General function to make an API request
+ * to the BankAPI
+ *
+ * @param $endpoint The endpoint you wish to dall
+ * @param $data An array of post data
+ * @return An array with a data
+ */
+ public function request($endpoint, $data) {
+ $postData = [];
+ foreach ($data as $k => $v) {
+ $postData[] = sprintf('%s=%s', urlencode($k), urlencode($v));
+ }
+
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, sprintf('%s/%s', $this->server, $endpoint));
+ curl_setopt($ch, CURLOPT_POST, 1);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, implode('&', $postData));
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+
+ // Set the UA to the app version
+ list($version_short, $version_long) = Cache::read('version');
+ curl_setopt($ch, CURLOPT_USERAGENT, 'ie2/BankWeb @ '.$version_short);
+
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);
+ curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
+
+ $result = curl_exec($ch);
+
+ curl_close($ch);
+
+ if ($result === false) {
+ throw new RuntimeException('Failed to contact the BankAPI Server. Please try again later.');
+ }
+
+ return json_decode($result, true);
+ }
+}
diff --git a/app/Plugin/BankWeb/Controller/InfoController.php b/app/Plugin/BankWeb/Controller/InfoController.php
index d8930e0..52fc6fd 100644
--- a/app/Plugin/BankWeb/Controller/InfoController.php
+++ b/app/Plugin/BankWeb/Controller/InfoController.php
@@ -3,28 +3,28 @@
class InfoController extends BankWebAppController {
- public function beforeFilter() {
- parent::beforeFilter();
+ public function beforeFilter() {
+ parent::beforeFilter();
- // Set the active menu item
- $this->set('at_team', true);
- }
+ // Set the active menu item
+ $this->set('at_team', true);
+ }
- /**
- * Account Information Page
- *
- * @url /bank/info
- * @url /bank/info/index
- */
- public function index() {
- if ( (bool)env('BANKWEB_PUBLIC_APIINFO') == false && !$this->Auth->isAdmin() ) {
- throw new ForbiddenException('This feature is disabled');
- }
+ /**
+ * Account Information Page
+ *
+ * @url /bank/info
+ * @url /bank/info/index
+ */
+ public function index() {
+ if ((bool)env('BANKWEB_PUBLIC_APIINFO') == false && !$this->Auth->isAdmin()) {
+ throw new ForbiddenException('This feature is disabled');
+ }
- $account = $this->AccountMapping->getAccount($this->Auth->item('groups'));
+ $account = $this->AccountMapping->getAccount($this->Auth->item('groups'));
- $this->set('api', parse_url(env('BANKAPI_SERVER')));
- $this->set('username', $account['AccountMapping']['username']);
- $this->set('password', $account['AccountMapping']['password']);
- }
-}
\ No newline at end of file
+ $this->set('api', parse_url(env('BANKAPI_SERVER')));
+ $this->set('username', $account['AccountMapping']['username']);
+ $this->set('password', $account['AccountMapping']['password']);
+ }
+}
diff --git a/app/Plugin/BankWeb/Controller/ProductsController.php b/app/Plugin/BankWeb/Controller/ProductsController.php
index 9285603..53f7c40 100644
--- a/app/Plugin/BankWeb/Controller/ProductsController.php
+++ b/app/Plugin/BankWeb/Controller/ProductsController.php
@@ -2,74 +2,79 @@
App::uses('BankWebAppController', 'BankWeb.Controller');
class ProductsController extends BankWebAppController {
- /**
- * Array of products loaded from the
- * env variable 'BANKWEB_PRODUCTS'
- */
- private $products = [];
- public function beforeFilter() {
- parent::beforeFilter();
+ /**
+ * Array of products loaded from the
+ * env variable 'BANKWEB_PRODUCTS'
+ */
+ private $products = [];
- // Load the products
- $filename = ROOT . DS . env('BANKWEB_PRODUCTS');
- $this->products = json_decode(file_get_contents($filename), true);
+ public function beforeFilter() {
+ parent::beforeFilter();
- // Set the active menu item
- $this->set('at_bank', true);
- }
+ // Load the products
+ $filename = ROOT . DS . env('BANKWEB_PRODUCTS');
+ $this->products = json_decode(file_get_contents($filename), true);
- /**
- * Product List Page
- *
- * @url /bank
- * @url /bank/products
- * @url /bank/products/index
- */
- public function index() {
- $this->set('products', $this->products);
- }
+ // Set the active menu item
+ $this->set('at_bank', true);
+ }
- /**
- * Product Purchase Confirmation
- *
- * @url /bank/products/confirm/
- */
- public function confirm($id=false) {
- if ( $id === false || !isset($this->products[$id]) ) {
- throw new NotFoundException('Unknown product');
- }
+ /**
+ * Product List Page
+ *
+ * @url /bank
+ * @url /bank/products
+ * @url /bank/products/index
+ */
+ public function index() {
+ $this->set('products', $this->products);
+ }
- $product = $this->products[$id];
- if ( !$product['enabled'] ) {
- throw new NotFoundException('Unknown product');
- }
+ /**
+ * Product Purchase Confirmation
+ *
+ * @url /bank/products/confirm/
+ */
+ public function confirm($id = false) {
+ if ($id === false || !isset($this->products[$id])) {
+ throw new NotFoundException('Unknown product');
+ }
- if (
- $this->request->is('post') &&
- isset($this->request->data['srcAcc']) &&
- is_numeric($this->request->data['srcAcc']) &&
- isset($this->request->data['pin']) &&
- is_numeric($this->request->data['pin'])
- ) {
- try {
- $res = $this->BankApi->transfer($_POST['srcAcc'], env('BANKWEB_WHITETEAM_ACCOUNT'), $product['cost'], $_POST['pin']);
- } catch ( Exception $e ) {
- $this->Flash->danger($e->getMessage());
- }
+ $product = $this->products[$id];
+ if (!$product['enabled']) {
+ throw new NotFoundException('Unknown product');
+ }
- if ( $res === true ) {
- $this->Flash->success($product['on_purchase']);
+ if ($this->request->is('post')
+ && isset($this->request->data['srcAcc'])
+ && is_numeric($this->request->data['srcAcc'])
+ && isset($this->request->data['pin'])
+ && is_numeric($this->request->data['pin'])
+ ) {
+ try {
+ $res = $this->BankApi->transfer(
+ $_POST['srcAcc'],
+ env('BANKWEB_WHITETEAM_ACCOUNT'),
+ $product['cost'],
+ $_POST['pin']
+ );
+ } catch (Exception $e) {
+ $this->Flash->danger($e->getMessage());
+ }
- if ( (bool)env('BANKWEB_SLACK_ENABLED') ) {
- $this->_sendSlack($product['slack_message']);
- }
- }
+ if ($res === true) {
+ $this->Flash->success($product['on_purchase']);
- return $this->redirect(['plugin' => 'bank_web', 'controller' => 'products', 'action' => 'index']);
- }
+ if ((bool)env('BANKWEB_SLACK_ENABLED')) {
+ $this->sendSlack($product['slack_message']);
+ }
+ }
- $this->set('item', $product);
- $this->set('accounts', $this->BankApi->accounts());
- }
-}
\ No newline at end of file
+ return $this->redirect(['plugin' => 'bank_web', 'controller' => 'products', 'action' => 'index']);
+ }
+
+ $this->set('item', $product);
+ $this->set('accounts', $this->BankApi->accounts());
+ }
+}
diff --git a/app/Plugin/BankWeb/Model/AccountMapping.php b/app/Plugin/BankWeb/Model/AccountMapping.php
index 3ab058d..bec6752 100644
--- a/app/Plugin/BankWeb/Model/AccountMapping.php
+++ b/app/Plugin/BankWeb/Model/AccountMapping.php
@@ -2,36 +2,38 @@
App::uses('BankWebAppModel', 'BankWeb.Model');
class AccountMapping extends BankWebAppModel {
- public $belongsTo = ['Group'];
- public $recursive = 1;
-
- public function getAccount($groups) {
- // Check groups
- $mapping = $this->find('all', [
- 'conditions' => [
- 'AccountMapping.group_id' => $groups,
- ],
- ]);
-
- // Re-organize the mappings
- $maps = [];
- foreach ( $mapping AS $m ) {
- $maps[$m['AccountMapping']['group_id']] = $m;
- }
-
- // Now let's deal with the groups
- if ( !empty($maps) ) {
- // We're going to assume (I'm sorry), that the last
- // items in $groups is the closest thing being used
- $wanted = array_reverse($groups);
-
- foreach ( $wanted AS $id ) {
- if ( isset($maps[$id]) ) {
- return $maps[$id];
- }
- }
- }
-
- return [];
- }
-}
\ No newline at end of file
+
+ public $belongsTo = ['Group'];
+
+ public $recursive = 1;
+
+ public function getAccount($groups) {
+ // Check groups
+ $mapping = $this->find('all', [
+ 'conditions' => [
+ 'AccountMapping.group_id' => $groups,
+ ],
+ ]);
+
+ // Re-organize the mappings
+ $maps = [];
+ foreach ($mapping as $m) {
+ $maps[$m['AccountMapping']['group_id']] = $m;
+ }
+
+ // Now let's deal with the groups
+ if (!empty($maps)) {
+ // We're going to assume (I'm sorry), that the last
+ // items in $groups is the closest thing being used
+ $wanted = array_reverse($groups);
+
+ foreach ($wanted as $id) {
+ if (isset($maps[$id])) {
+ return $maps[$id];
+ }
+ }
+ }
+
+ return [];
+ }
+}
diff --git a/app/Plugin/BankWeb/Model/BankWebAppModel.php b/app/Plugin/BankWeb/Model/BankWebAppModel.php
index 6603c1f..1caffa8 100644
--- a/app/Plugin/BankWeb/Model/BankWebAppModel.php
+++ b/app/Plugin/BankWeb/Model/BankWebAppModel.php
@@ -2,5 +2,5 @@
App::uses('AppModel', 'Model');
class BankWebAppModel extends AppModel {
-
-}
\ No newline at end of file
+
+}
diff --git a/app/Plugin/BankWeb/webroot/css/products.css b/app/Plugin/BankWeb/webroot/css/products.css
index 769a80e..199c078 100644
--- a/app/Plugin/BankWeb/webroot/css/products.css
+++ b/app/Plugin/BankWeb/webroot/css/products.css
@@ -1,9 +1,9 @@
/*=============================================================
Authour URL: www.designbootstrap.com
-
+
http://www.designbootstrap.com/
- License: MIT
+ License: MIT
======================================================== */
.db-pricing-seven {
diff --git a/app/Plugin/ScoreEngine/Config/routes.php b/app/Plugin/ScoreEngine/Config/routes.php
index 0f981cc..6a7bbb3 100644
--- a/app/Plugin/ScoreEngine/Config/routes.php
+++ b/app/Plugin/ScoreEngine/Config/routes.php
@@ -4,15 +4,44 @@
*/
// Scoreboard mapping
-Router::connect('/scoreboard', ['plugin' => 'ScoreEngine', 'controller' => 'scoreboard', 'action' => 'index']);
-Router::connect('/scoreboard/api', ['plugin' => 'ScoreEngine', 'controller' => 'scoreboard', 'action' => 'api']);
-Router::connect('/scoreboard/overview', ['plugin' => 'ScoreEngine', 'controller' => 'scoreboard', 'action' => 'overview']);
+Router::connect('/scoreboard', [
+ 'plugin' => 'ScoreEngine',
+ 'controller' => 'scoreboard',
+ 'action' => 'index'
+]);
+Router::connect('/scoreboard/api', [
+ 'plugin' => 'ScoreEngine',
+ 'controller' => 'scoreboard',
+ 'action' => 'api'
+]);
+Router::connect('/scoreboard/overview', [
+ 'plugin' => 'ScoreEngine',
+ 'controller' => 'scoreboard',
+ 'action' => 'overview'
+]);
// ScoreEngine admin mapping
-Router::connect('/admin/scoreengine', ['plugin' => 'ScoreEngine', 'controller' => 'scoreadmin', 'action' => 'index']);
-Router::connect('/admin/scoreengine/:action/*', ['plugin' => 'ScoreEngine', 'controller' => 'scoreadmin']);
+Router::connect('/admin/scoreengine', [
+ 'plugin' => 'ScoreEngine',
+ 'controller' => 'scoreadmin',
+ 'action' => 'index'
+]);
+Router::connect('/admin/scoreengine/:action/*', [
+ 'plugin' => 'ScoreEngine',
+ 'controller' => 'scoreadmin'
+]);
// Team Panel mapping
-Router::connect('/team', ['plugin' => 'ScoreEngine', 'controller' => 'team', 'action' => 'index']);
-Router::connect('/team/:action', ['plugin' => 'ScoreEngine', 'controller' => 'team']);
-Router::connect('/team/:action/*', ['plugin' => 'ScoreEngine', 'controller' => 'team']);
+Router::connect('/team', [
+ 'plugin' => 'ScoreEngine',
+ 'controller' => 'team',
+ 'action' => 'index'
+]);
+Router::connect('/team/:action', [
+ 'plugin' => 'ScoreEngine',
+ 'controller' => 'team'
+]);
+Router::connect('/team/:action/*', [
+ 'plugin' => 'ScoreEngine',
+ 'controller' => 'team'
+]);
diff --git a/app/Plugin/ScoreEngine/Controller/ScoreEngineAppController.php b/app/Plugin/ScoreEngine/Controller/ScoreEngineAppController.php
index a96b473..26c5512 100644
--- a/app/Plugin/ScoreEngine/Controller/ScoreEngineAppController.php
+++ b/app/Plugin/ScoreEngine/Controller/ScoreEngineAppController.php
@@ -2,5 +2,5 @@
App::uses('AppController', 'Controller');
class ScoreEngineAppController extends AppController {
-
-}
\ No newline at end of file
+
+}
diff --git a/app/Plugin/ScoreEngine/Controller/ScoreadminController.php b/app/Plugin/ScoreEngine/Controller/ScoreadminController.php
index 5a4723e..8310612 100644
--- a/app/Plugin/ScoreEngine/Controller/ScoreadminController.php
+++ b/app/Plugin/ScoreEngine/Controller/ScoreadminController.php
@@ -2,171 +2,174 @@
App::uses('ScoreEngineAppController', 'ScoreEngine.Controller');
class ScoreadminController extends ScoreEngineAppController {
- public $uses = ['ScoreEngine.Team', 'ScoreEngine.Check','ScoreEngine.Service', 'ScoreEngine.TeamService'];
-
- public function beforeFilter() {
- parent::beforeFilter();
-
- // Enforce staff only
- $this->Auth->protect(env('GROUP_STAFF'));
-
- // Set the active menu item
- $this->set('at_staff', true);
- }
-
- /**
- * ScoreEngine Admin Index Page
- *
- * @url /admin/scoreengine
- * @url /score_engine/admin
- * @url /admin/scoreengine/index
- * @url /score_engine/admin/index
- */
- public function index() {
- $this->set('teams', $this->Team->find('all'));
- }
-
- /**
- * View Team Page
- *
- * @url /admin/scoreengine/team/
- * @url /score_engine/admin/team/
- */
- public function team($id=false) {
- $team = $this->Team->findById($id);
- if ( empty ($team) ) {
- throw new NotFoundException('Unknown team');
- }
-
- $tid = $team['Team']['id'];
- $this->set('team', $team);
- $this->set('data', $this->Check->getTeamChecks($tid, false));
- $this->set('latest', $this->Check->getLastTeamCheck($tid));
- }
-
- /**
- * View Team Service Page
- *
- * @url /admin/scoreengine/service//
- * @url /score_engine/admin/config//
- */
- public function service($tid=false, $sid=false) {
- $team = $this->Team->findById($tid);
- if ( empty($team) ) {
- throw new NotFoundException('Unknown team');
- }
- if ( $sid === false || !is_numeric($sid) ) {
- throw new NotFoundException('Unknown service');
- }
-
- $oldVF = $this->Check->virtualFields;
- $this->Check->virtualFields = [];
-
- $this->set('team', $team);
- $this->set('data', $this->Check->find('all', [
- 'conditions' => [
- 'team_id' => $team['Team']['id'],
- 'service_id' => $sid,
- ],
- 'limit' => 20,
- 'order' => 'time DESC',
- ]));
-
- $this->Check->virtualFields = $oldVF;
- }
-
- /**
- * Team Config Page
- *
- * @url /admin/scoreengine/config/
- * @url /score_engine/admin/config/
- */
- public function config($id=false) {
- $team = $this->Team->findById($id);
- if ( empty($team) ) {
- throw new NotFoundException('Unknown team');
- }
-
- $this->set('team', $team);
- $data = $this->TeamService->getData($team['Team']['id'], false);
-
- $updateOpt = function($id, $value) use(&$data) {
- foreach ( $data AS $group => &$options ) {
- foreach ( $options AS &$opt ) {
- if ( $opt['id'] == $id ) {
- $opt['value'] = $value;
- }
- }
- }
-
- return false;
- };
-
- if ( $this->request->is('post') ) {
- foreach ( $this->request->data AS $opt => $value ) {
- $opt = (int) str_replace('opt', '', $opt);
- if ( $opt < 0 || !is_numeric($opt) ) continue;
-
- // Only USERPASS is an array
- if ( is_array($value) ) {
- $value = $value['user'].'||'.$value['pass'];
- }
-
- $this->TeamService->updateConfig($opt, $value);
- $updateOpt($opt, $value);
- }
-
- // Message
- $this->Flash->success('Updated Score Engine Config!');
- }
-
- $this->set('data', $data);
- }
-
- /**
- * Export Grades
- *
- * @url /admin/scoreengine/export
- * @url /score_engine/admin/export
- */
- public function export() {
- $teams = $this->Team->find('all');
- $services = $this->Service->find('all');
- $out = [];
- $chkOrder = [];
-
- // Helper function to grab the right check
- $grabCheckById = function($checks, $id) {
- foreach ( $checks AS $c ) {
- if ( $c['Service']['id'] == $id ) {
- return $c;
- }
- }
- };
-
- // Build the header
- $header = ['team_number'];
- foreach ( $services AS $s ) {
- $header[] = '"'.$s['Service']['name'].'"';
- $chkOrder[] = $s['Service']['id'];
- }
- $out[] = implode(',', $header);
-
- // Parse team scores
- foreach ( $teams AS $t ) {
- $tid = $t['Team']['id'];
- $line = [$tid];
-
- $checks = $this->Check->getTeamChecks($tid);
-
- foreach ( $chkOrder AS $id ) {
- $chk = $grabCheckById($checks, $id);
- $line[] = isset($chk['Check']['total_passed']) ? $chk['Check']['total_passed'] : 0;
- }
-
- $out[] = implode(',', $line);
- }
-
- return $this->ajaxResponse(implode(PHP_EOL, $out));
- }
+
+ public $uses = ['ScoreEngine.Team', 'ScoreEngine.Check','ScoreEngine.Service', 'ScoreEngine.TeamService'];
+
+ public function beforeFilter() {
+ parent::beforeFilter();
+
+ // Enforce staff only
+ $this->Auth->protect(env('GROUP_STAFF'));
+
+ // Set the active menu item
+ $this->set('at_staff', true);
+ }
+
+ /**
+ * ScoreEngine Admin Index Page
+ *
+ * @url /admin/scoreengine
+ * @url /score_engine/admin
+ * @url /admin/scoreengine/index
+ * @url /score_engine/admin/index
+ */
+ public function index() {
+ $this->set('teams', $this->Team->find('all'));
+ }
+
+ /**
+ * View Team Page
+ *
+ * @url /admin/scoreengine/team/
+ * @url /score_engine/admin/team/
+ */
+ public function team($id = false) {
+ $team = $this->Team->findById($id);
+ if (empty($team)) {
+ throw new NotFoundException('Unknown team');
+ }
+
+ $tid = $team['Team']['id'];
+ $this->set('team', $team);
+ $this->set('data', $this->Check->getTeamChecks($tid, false));
+ $this->set('latest', $this->Check->getLastTeamCheck($tid));
+ }
+
+ /**
+ * View Team Service Page
+ *
+ * @url /admin/scoreengine/service//
+ * @url /score_engine/admin/config//
+ */
+ public function service($tid = false, $sid = false) {
+ $team = $this->Team->findById($tid);
+ if (empty($team)) {
+ throw new NotFoundException('Unknown team');
+ }
+ if ($sid === false || !is_numeric($sid)) {
+ throw new NotFoundException('Unknown service');
+ }
+
+ $oldVF = $this->Check->virtualFields;
+ $this->Check->virtualFields = [];
+
+ $this->set('team', $team);
+ $this->set('data', $this->Check->find('all', [
+ 'conditions' => [
+ 'team_id' => $team['Team']['id'],
+ 'service_id' => $sid,
+ ],
+ 'limit' => 20,
+ 'order' => 'time DESC',
+ ]));
+
+ $this->Check->virtualFields = $oldVF;
+ }
+
+ /**
+ * Team Config Page
+ *
+ * @url /admin/scoreengine/config/
+ * @url /score_engine/admin/config/
+ */
+ public function config($id = false) {
+ $team = $this->Team->findById($id);
+ if (empty($team)) {
+ throw new NotFoundException('Unknown team');
+ }
+
+ $this->set('team', $team);
+ $data = $this->TeamService->getData($team['Team']['id'], false);
+
+ $updateOpt = function ($id, $value) use (&$data) {
+ foreach ($data as $group => &$options) {
+ foreach ($options as &$opt) {
+ if ($opt['id'] == $id) {
+ $opt['value'] = $value;
+ }
+ }
+ }
+
+ return false;
+ };
+
+ if ($this->request->is('post')) {
+ foreach ($this->request->data as $opt => $value) {
+ $opt = (int)str_replace('opt', '', $opt);
+ if ($opt < 0 || !is_numeric($opt)) {
+ continue;
+ }
+
+ // Only USERPASS is an array
+ if (is_array($value)) {
+ $value = $value['user'].'||'.$value['pass'];
+ }
+
+ $this->TeamService->updateConfig($opt, $value);
+ $updateOpt($opt, $value);
+ }
+
+ // Message
+ $this->Flash->success('Updated Score Engine Config!');
+ }
+
+ $this->set('data', $data);
+ }
+
+ /**
+ * Export Grades
+ *
+ * @url /admin/scoreengine/export
+ * @url /score_engine/admin/export
+ */
+ public function export() {
+ $teams = $this->Team->find('all');
+ $services = $this->Service->find('all');
+ $out = [];
+ $chkOrder = [];
+
+ // Helper function to grab the right check
+ $grabCheckById = function ($checks, $id) {
+ foreach ($checks as $c) {
+ if ($c['Service']['id'] == $id) {
+ return $c;
+ }
+ }
+ };
+
+ // Build the header
+ $header = ['team_number'];
+ foreach ($services as $s) {
+ $header[] = '"'.$s['Service']['name'].'"';
+ $chkOrder[] = $s['Service']['id'];
+ }
+ $out[] = implode(',', $header);
+
+ // Parse team scores
+ foreach ($teams as $t) {
+ $tid = $t['Team']['id'];
+ $line = [$tid];
+
+ $checks = $this->Check->getTeamChecks($tid);
+
+ foreach ($chkOrder as $id) {
+ $chk = $grabCheckById($checks, $id);
+ $line[] = isset($chk['Check']['total_passed']) ? $chk['Check']['total_passed'] : 0;
+ }
+
+ $out[] = implode(',', $line);
+ }
+
+ return $this->ajaxResponse(implode(PHP_EOL, $out));
+ }
}
diff --git a/app/Plugin/ScoreEngine/Controller/ScoreboardController.php b/app/Plugin/ScoreEngine/Controller/ScoreboardController.php
index 7d9bfec..071aba7 100644
--- a/app/Plugin/ScoreEngine/Controller/ScoreboardController.php
+++ b/app/Plugin/ScoreEngine/Controller/ScoreboardController.php
@@ -2,100 +2,102 @@
App::uses('ScoreEngineAppController', 'ScoreEngine.Controller');
class ScoreboardController extends ScoreEngineAppController {
- public $uses = [
- 'ScoreEngine.Check', 'ScoreEngine.Service', 'ScoreEngine.Team', 'ScoreEngine.Round',
- 'Config', 'Submission', 'Schedule', 'Group'
- ];
- /**
- * ScoreBoard Overview Page
- *
- * @url /scoreboard
- * @url /score_engine/scoreboard
- * @url /score_engine/scoreboard/index
- */
- public function index() {
- $sponsors = $this->Config->getKey('competition.sponsors');
- if ( !empty($sponsors) ) {
- $sponsors = json_decode($sponsors, true);
- }
+ public $uses = [
+ 'ScoreEngine.Check', 'ScoreEngine.Service', 'ScoreEngine.Team', 'ScoreEngine.Round',
+ 'Config', 'Submission', 'Schedule', 'Group'
+ ];
- $this->set('sponsors', $sponsors);
- $this->set('at_scoreboard', true);
- }
+ /**
+ * ScoreBoard Overview Page
+ *
+ * @url /scoreboard
+ * @url /score_engine/scoreboard
+ * @url /score_engine/scoreboard/index
+ */
+ public function index() {
+ $sponsors = $this->Config->getKey('competition.sponsors');
+ if (!empty($sponsors)) {
+ $sponsors = json_decode($sponsors, true);
+ }
- /**
- * ScoreBoard Overview Page
- *
- * @url /scoreboard/overview
- * @url /score_engine/scoreboard/overview
- */
- public function overview() {
- // Require staff
- $this->Auth->protect(env('GROUP_STAFF'));
+ $this->set('sponsors', $sponsors);
+ $this->set('at_scoreboard', true);
+ }
- // Generate team mappings
- $group_names = $this->Group->find('all', [
- 'conditions' => [
- 'Group.team_number IS NOT NULL',
- ],
- ]);
- $team_mappings = [];
- foreach ( $group_names AS $g ) {
- $team_mappings[$g['Group']['team_number']] = $g['Group']['name'];
- }
+ /**
+ * ScoreBoard Overview Page
+ *
+ * @url /scoreboard/overview
+ * @url /score_engine/scoreboard/overview
+ */
+ public function overview() {
+ // Require staff
+ $this->Auth->protect(env('GROUP_STAFF'));
- // Grab the check overview
- $overview = $this->Check->getMaxCheck(false);
+ // Generate team mappings
+ $group_names = $this->Group->find('all', [
+ 'conditions' => [
+ 'Group.team_number IS NOT NULL',
+ ],
+ ]);
+ $team_mappings = [];
+ foreach ($group_names as $g) {
+ $team_mappings[$g['Group']['team_number']] = $g['Group']['name'];
+ }
- // Grab the grade overview
- $grades = $this->Submission->getGrades($this->Group->getChildren(env('GROUP_BLUE')));
- $grade_team_mappings = [];
- foreach ( $grades AS $g ) {
- $grade_team_mappings[$g['Group']['team_number']] = $g['Submission']['total_grade'];
- }
+ // Grab the check overview
+ $overview = $this->Check->getMaxCheck(false);
- // Grab the max check
- $max_check = $this->Check->getMaxCheck(true);
+ // Grab the grade overview
+ $grades = $this->Submission->getGrades($this->Group->getChildren(env('GROUP_BLUE')));
+ $grade_team_mappings = [];
+ foreach ($grades as $g) {
+ $grade_team_mappings[$g['Group']['team_number']] = $g['Submission']['total_grade'];
+ }
- // Grab the max grade
- $injects = $this->Schedule->getInjects(env('GROUP_BLUE'));
- $max_grade = 0;
- foreach ( $injects AS $i ) {
- $max_grade += $i->getInjectMaxPoints();
- }
+ // Grab the max check
+ $max_check = $this->Check->getMaxCheck(true);
- $this->set('at_staff', true);
- $this->set('round', $this->Round->getLastRound());
- $this->set('overview', $overview);
- $this->set('grades', $grades);
- $this->set('grade_team_mappings', $grade_team_mappings);
- $this->set('team_mappings', $team_mappings);
- $this->set('max_grade', $max_grade);
- $this->set('max_check', $max_check[0]['Check']['total_passed']);
- }
+ // Grab the max grade
+ $injects = $this->Schedule->getInjects(env('GROUP_BLUE'));
+ $max_grade = 0;
+ foreach ($injects as $i) {
+ $max_grade += $i->getInjectMaxPoints();
+ }
- /**
- * ScoreBoard API Content
- *
- * @url /scoreboard/api
- * @url /score_engine/scoreboard/api
- */
- public function api() {
- $this->layout = 'ajax';
+ $this->set('at_staff', true);
+ $this->set('round', $this->Round->getLastRound());
+ $this->set('overview', $overview);
+ $this->set('grades', $grades);
+ $this->set('grade_team_mappings', $grade_team_mappings);
+ $this->set('team_mappings', $team_mappings);
+ $this->set('max_grade', $max_grade);
+ $this->set('max_check', $max_check[0]['Check']['total_passed']);
+ }
- $active_injects = $this->Schedule->getInjects(env('GROUP_BLUE'));
- foreach ( $active_injects AS $i => $inject ) {
- if ( $inject->isExpired() ) unset($active_injects[$i]);
- }
+ /**
+ * ScoreBoard API Content
+ *
+ * @url /scoreboard/api
+ * @url /score_engine/scoreboard/api
+ */
+ public function api() {
+ $this->layout = 'ajax';
- // Setup the ScoreEngine EngineOutputter
- $this->helpers['ScoreEngine.EngineOutputter']['data'] = $this->Check->getChecksTable(
- $this->Team->findAllByEnabledAndCheckTeam(true, false),
- $this->Service->findAllByEnabled(true)
- );
+ $active_injects = $this->Schedule->getInjects(env('GROUP_BLUE'));
+ foreach ($active_injects as $i => $inject) {
+ if ($inject->isExpired()) { unset($active_injects[$i]);
+ }
+ }
- $this->set('active_injects', $active_injects);
- $this->set('round', $this->Round->getLastRound());
- }
-}
\ No newline at end of file
+ // Setup the ScoreEngine EngineOutputter
+ $this->helpers['ScoreEngine.EngineOutputter']['data'] = $this->Check->getChecksTable(
+ $this->Team->findAllByEnabledAndCheckTeam(true, false),
+ $this->Service->findAllByEnabled(true)
+ );
+
+ $this->set('active_injects', $active_injects);
+ $this->set('round', $this->Round->getLastRound());
+ }
+}
diff --git a/app/Plugin/ScoreEngine/Controller/TeamController.php b/app/Plugin/ScoreEngine/Controller/TeamController.php
index 5360f53..b414729 100644
--- a/app/Plugin/ScoreEngine/Controller/TeamController.php
+++ b/app/Plugin/ScoreEngine/Controller/TeamController.php
@@ -2,152 +2,129 @@
App::uses('ScoreEngineAppController', 'ScoreEngine.Controller');
class TeamController extends ScoreEngineAppController {
- public $uses = ['ScoreEngine.Check', 'ScoreEngine.TeamService'];
-
- /**
- * The current user's team number
- */
- private $team;
-
- /**
- * IP Regex
- *
- * Source: http://stackoverflow.com/a/20270082
- */
- const IP_REGEX = "/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/";
-
- /**
- * Before Filter
- *
- * Locks the page to blue teams' group,
- * as well as sets up the user's team number
- */
- public function beforeFilter() {
- parent::beforeFilter();
-
- // Only blue teams may access
- $this->Auth->protect(env('GROUP_BLUE'));
-
- // Set the team number
- $this->team = $this->Auth->group('team_number');
- }
-
- /**
- * Team Overview Page
- *
- * @url /team
- * @url /score_engine/team
- * @url /score_engine/team/index
- */
- public function index() {
- $this->set('data', $this->Check->getTeamChecks($this->team));
- $this->set('latest', $this->Check->getLastTeamCheck($this->team));
- }
-
- /**
- * Service Overview Page
- *
- * @url /team/service/
- * @url /score_engine/team/service/
- */
- public function service($sid=false) {
- if ( $sid === false || !is_numeric($sid) ) {
- throw new NotFoundException('Unknown service');
- }
-
- $this->Check->virtualFields = [];
- $this->set('data', $this->Check->find('all', [
- 'conditions' => [
- 'team_id' => $this->team,
- 'service_id' => $sid,
- 'Service.enabled' => true,
- ],
- 'limit' => 20,
- 'order' => 'time DESC',
- ]));
- }
-
- /**
- * Config Edit Page
- *
- * @url /team/edit
- * @url /score_engine/team/edit
- */
- public function config() {
- $data = $this->TeamService->getData($this->team);
-
- $canEdit = function($id) use($data) {
- foreach ( $data AS $group => $options ) {
- foreach ( $options AS $opt ) {
- if ( $opt['id'] == $id ) {
- return $opt['edit'];
- }
- }
- }
-
- return false;
- };
-
- $getOpt = function($id) use(&$data) {
- foreach ( $data AS $group => &$options ) {
- foreach ( $options AS $opt ) {
- if ( $opt['id'] == $id ) {
- return $opt['value'];
- }
- }
- }
-
- return false;
- };
-
- $updateOpt = function($id, $value) use(&$data) {
- foreach ( $data AS $group => &$options ) {
- foreach ( $options AS &$opt ) {
- if ( $opt['id'] == $id ) {
- $opt['value'] = $value;
- }
- }
- }
-
- return false;
- };
-
- if ( $this->request->is('post') ) {
- foreach ( $this->request->data AS $opt => $value ) {
- $opt = (int) str_replace('opt', '', $opt);
- if ( $opt < 0 || !is_numeric($opt) ) continue;
- if ( !$canEdit($opt) ) continue;
-
- // Only USERPASS is an array
- if ( is_array($value) ) {
- $value = $value['user'].'||'.$value['pass'];
- }
-
- // Do some hacky magic with IPs to check subnets
- $oldVal = $getOpt($opt);
-
- if ( preg_match(self::IP_REGEX, $oldVal, $match) ) {
- $newSubnet = explode('.', $value);
- array_pop($newSubnet);
- $newSubnet = implode('.', $newSubnet);
-
- $oldSubnet = explode('.', $oldVal);
- array_pop($oldSubnet);
- $oldSubnet = implode('.', $oldSubnet);
-
- if ( $newSubnet != $oldSubnet ) {
- continue;
- }
- }
-
- $this->TeamService->updateConfig($opt, $value);
- $updateOpt($opt, $value);
- }
-
- // Message
- $this->Flash->success('Updated Score Engine Config!');
- }
-
- $this->set('data', $data);
- }
-}
\ No newline at end of file
+
+ public $uses = ['ScoreEngine.Check', 'ScoreEngine.TeamService'];
+
+ /**
+ * The current user's team number
+ */
+ private $team;
+
+ /**
+ * IP Regex
+ *
+ * Source: http://stackoverflow.com/a/20270082
+ */
+ const IP_REGEX = "/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/";
+
+ /**
+ * Before Filter
+ *
+ * Locks the page to blue teams' group,
+ * as well as sets up the user's team number
+ */
+ public function beforeFilter() {
+ parent::beforeFilter();
+
+ // Only blue teams may access
+ $this->Auth->protect(env('GROUP_BLUE'));
+
+ // Set the team number
+ $this->team = $this->Auth->group('team_number');
+ }
+
+ /**
+ * Team Overview Page
+ *
+ * @url /team
+ * @url /score_engine/team
+ * @url /score_engine/team/index
+ */
+ public function index() {
+ $this->set('data', $this->Check->getTeamChecks($this->team));
+ $this->set('latest', $this->Check->getLastTeamCheck($this->team));
+ }
+
+ /**
+ * Service Overview Page
+ *
+ * @url /team/service/
+ * @url /score_engine/team/service/
+ */
+ public function service($sid = false) {
+ if ($sid === false || !is_numeric($sid)) {
+ throw new NotFoundException('Unknown service');
+ }
+
+ $this->Check->virtualFields = [];
+ $this->set('data', $this->Check->find('all', [
+ 'conditions' => [
+ 'team_id' => $this->team,
+ 'service_id' => $sid,
+ 'Service.enabled' => true,
+ ],
+ 'limit' => 20,
+ 'order' => 'time DESC',
+ ]));
+ }
+
+ /**
+ * Config Edit Page
+ *
+ * @url /team/edit
+ * @url /score_engine/team/edit
+ */
+ public function config() {
+ $data = $this->TeamService->getData($this->team);
+
+ // Generate mappings
+ $mappings = [];
+ foreach ($data as $group => $options) {
+ foreach ($options as $opt) {
+ $mappings[$opt['id']] = $opt;
+ }
+ }
+
+ if ($this->request->is('post')) {
+ foreach ($this->request->data as $opt => $value) {
+ $opt = (int)str_replace('opt', '', $opt);
+ if ($opt < 0 || !is_numeric($opt)) {
+ continue;
+ }
+ if (!$mappings[$opt]['edit']) {
+ continue;
+ }
+
+ // Only USERPASS is an array
+ if (is_array($value)) {
+ $value = $value['user'].'||'.$value['pass'];
+ }
+
+ // Do some hacky magic with IPs to check subnets
+ $oldVal = $mappings[$opt]['value'];
+
+ if (preg_match(self::IP_REGEX, $oldVal, $match)) {
+ $newSubnet = explode('.', $value);
+ array_pop($newSubnet);
+ $newSubnet = implode('.', $newSubnet);
+
+ $oldSubnet = explode('.', $oldVal);
+ array_pop($oldSubnet);
+ $oldSubnet = implode('.', $oldSubnet);
+
+ if ($newSubnet != $oldSubnet) {
+ continue;
+ }
+ }
+
+ $this->TeamService->updateConfig($opt, $value);
+ }
+
+ // Message
+ $this->Flash->success('Updated Score Engine Config!');
+ $this->redirect(['plugin' => 'ScoreEngine', 'controller' => 'team', 'action' => 'config']);
+ }
+
+ $this->set('data', $data);
+ }
+}
diff --git a/app/Plugin/ScoreEngine/Model/Check.php b/app/Plugin/ScoreEngine/Model/Check.php
index 101add2..f24fbc0 100644
--- a/app/Plugin/ScoreEngine/Model/Check.php
+++ b/app/Plugin/ScoreEngine/Model/Check.php
@@ -2,130 +2,136 @@
App::uses('ScoreEngineAppModel', 'ScoreEngine.Model');
class Check extends ScoreEngineAppModel {
- public $belongsTo = ['ScoreEngine.Service', 'ScoreEngine.Team'];
- public $recursive = 1;
-
- public $virtualFields = [
- 'total_passed' => 'SUM(Check.passed = 1)',
- 'total' => 'COUNT(Check.passed)',
- ];
-
- public function getChecksTable($teams, $services) {
- $rtn = [];
-
- $enabled_services = [];
- foreach ( $services AS $s ) {
- $enabled_services[] = $s['Service']['id'];
- }
-
- foreach ( $teams AS $t ) {
- $team_name = $t['Team']['name'];
-
- $rtn[$team_name] = [];
- foreach ( $services AS $s ) {
- $service_name = $s['Service']['name'];
-
- $rtn[$team_name][$service_name] = null;
- }
- }
-
- $data = $this->find('all', [
- 'fields' => [
- 'Check.passed', 'Team.name', 'Service.name',
- 'Service.id',
- ],
-
- 'conditions' => [
- // We're going to use the highest number minus one
- 'Check.round = (SELECT MAX(number) FROM rounds WHERE completed = 1)',
- ],
-
- 'order' => [
- 'Team.id ASC',
- 'Service.id ASC',
- ],
- ]);
-
- foreach ( $data AS $d ) {
- $team_name = $d['Team']['name'];
- $service_name = $d['Service']['name'];
-
- if ( !in_array($d['Service']['id'], $enabled_services) ) continue;
- if ( !isset($rtn[$team_name]) ) continue;
-
- $rtn[$team_name][$service_name] = ((bool) $d['Check']['passed']);
- }
- return $rtn;
- }
-
- public function getTeamChecks($tid, $onlyEnabled=true) {
- $conditions = [
- 'fields' => [
- 'Check.total_passed', 'Check.total',
- 'Service.name', 'Service.id', 'Service.enabled',
- ],
- 'joins' => [
- [
- 'table' => 'rounds',
- 'alias' => 'Round',
- 'type' => 'left',
- 'conditions' => [
- 'Round.number = Check.round',
- ],
- ]
- ],
- 'conditions' => [
- 'Team.id' => $tid,
- 'Round.completed' => true,
- ],
- 'group' => [
- 'Service.id',
- ],
- ];
-
- if ( $onlyEnabled ) {
- $conditions['conditions']['Service.enabled'] = true;
- }
-
- return $this->find('all', $conditions);
- }
-
- public function getLastTeamCheck($tid) {
- $data = $this->find('all', [
- 'fields' => [
- 'Service.id', 'Service.name', 'Check.passed',
- ],
-
- 'conditions' => [
- 'Team.id' => $tid,
- 'Service.enabled' => true,
- 'Check.round = (SELECT MAX(number) FROM rounds WHERE completed = 1)',
- ],
- ]);
-
- $rtn = [];
- foreach ( $data AS $d ) {
- $rtn[$d['Service']['name']] = $d['Check'];
- }
-
- return $rtn;
- }
-
- public function getMaxCheck($onlyCheckTeam=false) {
- return $this->find('all', [
- 'fields' => [
- 'Check.total_passed', 'Check.total',
- 'Team.id', 'Team.check_team',
- ],
- 'conditions' => [
- 'Team.check_team' => $onlyCheckTeam,
- ],
- 'group' => [
- 'Team.id',
- ],
- 'order' => [
- 'Check.total_passed DESC',
- ],
- ]);
- }
-}
\ No newline at end of file
+
+ public $belongsTo = ['ScoreEngine.Service', 'ScoreEngine.Team'];
+
+ public $recursive = 1;
+
+ public $virtualFields = [
+ 'total_passed' => 'SUM(Check.passed = 1)',
+ 'total' => 'COUNT(Check.passed)',
+ ];
+
+ public function getChecksTable($teams, $services) {
+ $rtn = [];
+
+ $enabled_services = [];
+ foreach ($services as $s) {
+ $enabled_services[] = $s['Service']['id'];
+ }
+
+ foreach ($teams as $t) {
+ $team_name = $t['Team']['name'];
+
+ $rtn[$team_name] = [];
+ foreach ($services as $s) {
+ $service_name = $s['Service']['name'];
+
+ $rtn[$team_name][$service_name] = null;
+ }
+ }
+
+ $data = $this->find('all', [
+ 'fields' => [
+ 'Check.passed', 'Team.name', 'Service.name',
+ 'Service.id',
+ ],
+
+ 'conditions' => [
+ // We're going to use the highest number minus one
+ 'Check.round = (SELECT MAX(number) FROM rounds WHERE completed = 1)',
+ ],
+
+ 'order' => [
+ 'Team.id ASC',
+ 'Service.id ASC',
+ ],
+ ]);
+
+ foreach ($data as $d) {
+ $team_name = $d['Team']['name'];
+ $service_name = $d['Service']['name'];
+
+ if (!in_array($d['Service']['id'], $enabled_services)) {
+ continue;
+ }
+ if (!isset($rtn[$team_name])) {
+ continue;
+ }
+
+ $rtn[$team_name][$service_name] = ((bool)$d['Check']['passed']);
+ }
+ return $rtn;
+ }
+
+ public function getTeamChecks($tid, $onlyEnabled = true) {
+ $conditions = [
+ 'fields' => [
+ 'Check.total_passed', 'Check.total',
+ 'Service.name', 'Service.id', 'Service.enabled',
+ ],
+ 'joins' => [
+ [
+ 'table' => 'rounds',
+ 'alias' => 'Round',
+ 'type' => 'left',
+ 'conditions' => [
+ 'Round.number = Check.round',
+ ],
+ ]
+ ],
+ 'conditions' => [
+ 'Team.id' => $tid,
+ 'Round.completed' => true,
+ ],
+ 'group' => [
+ 'Service.id',
+ ],
+ ];
+
+ if ($onlyEnabled) {
+ $conditions['conditions']['Service.enabled'] = true;
+ }
+
+ return $this->find('all', $conditions);
+ }
+
+ public function getLastTeamCheck($tid) {
+ $data = $this->find('all', [
+ 'fields' => [
+ 'Service.id', 'Service.name', 'Check.passed',
+ ],
+
+ 'conditions' => [
+ 'Team.id' => $tid,
+ 'Service.enabled' => true,
+ 'Check.round = (SELECT MAX(number) FROM rounds WHERE completed = 1)',
+ ],
+ ]);
+
+ $rtn = [];
+ foreach ($data as $d) {
+ $rtn[$d['Service']['name']] = $d['Check'];
+ }
+
+ return $rtn;
+ }
+
+ public function getMaxCheck($onlyCheckTeam = false) {
+ return $this->find('all', [
+ 'fields' => [
+ 'Check.total_passed', 'Check.total',
+ 'Team.id', 'Team.check_team',
+ ],
+ 'conditions' => [
+ 'Team.check_team' => $onlyCheckTeam,
+ ],
+ 'group' => [
+ 'Team.id',
+ ],
+ 'order' => [
+ 'Check.total_passed DESC',
+ ],
+ ]);
+ }
+}
diff --git a/app/Plugin/ScoreEngine/Model/Round.php b/app/Plugin/ScoreEngine/Model/Round.php
index 5f2be50..6914775 100644
--- a/app/Plugin/ScoreEngine/Model/Round.php
+++ b/app/Plugin/ScoreEngine/Model/Round.php
@@ -2,16 +2,16 @@
App::uses('ScoreEngineAppModel', 'ScoreEngine.Model');
class Round extends ScoreEngineAppModel {
- public function getLastRound() {
- $round = $this->find('first', [
- 'fields' => [
- 'MAX(Round.number) AS round'
- ],
- 'conditions' => [
- 'Round.completed' => true,
- ],
- ]);
+ public function getLastRound() {
+ $round = $this->find('first', [
+ 'fields' => [
+ 'MAX(Round.number) AS round'
+ ],
+ 'conditions' => [
+ 'Round.completed' => true,
+ ],
+ ]);
- return empty($round[0]['round']) ? 0 : $round[0]['round'];
- }
-}
\ No newline at end of file
+ return empty($round[0]['round']) ? 0 : $round[0]['round'];
+ }
+}
diff --git a/app/Plugin/ScoreEngine/Model/ScoreEngineAppModel.php b/app/Plugin/ScoreEngine/Model/ScoreEngineAppModel.php
index 514820b..13bd7ba 100644
--- a/app/Plugin/ScoreEngine/Model/ScoreEngineAppModel.php
+++ b/app/Plugin/ScoreEngine/Model/ScoreEngineAppModel.php
@@ -2,5 +2,6 @@
App::uses('AppModel', 'Model');
class ScoreEngineAppModel extends AppModel {
- public $useDbConfig = 'scoreengine';
-}
\ No newline at end of file
+
+ public $useDbConfig = 'scoreengine';
+}
diff --git a/app/Plugin/ScoreEngine/Model/Service.php b/app/Plugin/ScoreEngine/Model/Service.php
index 3ec5d86..ade1760 100644
--- a/app/Plugin/ScoreEngine/Model/Service.php
+++ b/app/Plugin/ScoreEngine/Model/Service.php
@@ -2,5 +2,5 @@
App::uses('ScoreEngineAppModel', 'ScoreEngine.Model');
class Service extends ScoreEngineAppModel {
-
-}
\ No newline at end of file
+
+}
diff --git a/app/Plugin/ScoreEngine/Model/Team.php b/app/Plugin/ScoreEngine/Model/Team.php
index 1e20877..f33918c 100644
--- a/app/Plugin/ScoreEngine/Model/Team.php
+++ b/app/Plugin/ScoreEngine/Model/Team.php
@@ -2,5 +2,5 @@
App::uses('ScoreEngineAppModel', 'ScoreEngine.Model');
class Team extends ScoreEngineAppModel {
-
-}
\ No newline at end of file
+
+}
diff --git a/app/Plugin/ScoreEngine/Model/TeamService.php b/app/Plugin/ScoreEngine/Model/TeamService.php
index a364987..ff0c18b 100644
--- a/app/Plugin/ScoreEngine/Model/TeamService.php
+++ b/app/Plugin/ScoreEngine/Model/TeamService.php
@@ -2,64 +2,67 @@
App::uses('ScoreEngineAppModel', 'ScoreEngine.Model');
class TeamService extends ScoreEngineAppModel {
- public $useTable = 'team_service';
- public $belongsTo = ['ScoreEngine.Team', 'ScoreEngine.Service'];
- public $recursive = 1;
-
- public function getData($tid, $onlyEnabled=true) {
- $conditions = [
- 'fields' => [
- 'TeamService.id', 'TeamService.key', 'TeamService.value',
- 'TeamService.edit', 'TeamService.hidden', 'Service.name', 'Service.id',
- 'Service.enabled',
- ],
-
- 'conditions' => [
- 'Team.id' => $tid,
- ],
- ];
-
- if ( $onlyEnabled ) {
- $conditions['conditions']['Service.enabled'] = true;
- }
-
- $data = $this->find('all', $conditions);
-
- $rtn = [];
- foreach ( $data AS $d ) {
- if ( !$d['Service']['enabled'] ) {
- $d['Service']['name'] .= ' (Disabled)';
- }
-
- if ( !isset($rtn[$d['Service']['name']]) ) {
- $rtn[$d['Service']['name']] = [];
- }
-
- $rtn[$d['Service']['name']][] = $d['TeamService'];
- }
-
- return $rtn;
- }
-
- public function getConfig($tid, $sid, $key=false) {
- $conditions = [
- 'Team.id' => $tid,
- 'Service.id' => $sid,
- ];
-
- if ( $key !== false ) {
- $conditions['TeamService.key'] = $key;
- }
-
- return $this->find('all', [
- 'conditions' => $conditions,
- ]);
- }
-
- public function updateConfig($id, $value) {
- $this->id = $id;
- $this->save([
- 'value' => $value,
- ]);
- }
-}
\ No newline at end of file
+
+ public $useTable = 'team_service';
+
+ public $belongsTo = ['ScoreEngine.Team', 'ScoreEngine.Service'];
+
+ public $recursive = 1;
+
+ public function getData($tid, $onlyEnabled = true) {
+ $conditions = [
+ 'fields' => [
+ 'TeamService.id', 'TeamService.key', 'TeamService.value',
+ 'TeamService.edit', 'TeamService.hidden', 'Service.name', 'Service.id',
+ 'Service.enabled',
+ ],
+
+ 'conditions' => [
+ 'Team.id' => $tid,
+ ],
+ ];
+
+ if ($onlyEnabled) {
+ $conditions['conditions']['Service.enabled'] = true;
+ }
+
+ $data = $this->find('all', $conditions);
+
+ $rtn = [];
+ foreach ($data as $d) {
+ if (!$d['Service']['enabled']) {
+ $d['Service']['name'] .= ' (Disabled)';
+ }
+
+ if (!isset($rtn[$d['Service']['name']])) {
+ $rtn[$d['Service']['name']] = [];
+ }
+
+ $rtn[$d['Service']['name']][] = $d['TeamService'];
+ }
+
+ return $rtn;
+ }
+
+ public function getConfig($tid, $sid, $key = false) {
+ $conditions = [
+ 'Team.id' => $tid,
+ 'Service.id' => $sid,
+ ];
+
+ if ($key !== false) {
+ $conditions['TeamService.key'] = $key;
+ }
+
+ return $this->find('all', [
+ 'conditions' => $conditions,
+ ]);
+ }
+
+ public function updateConfig($id, $value) {
+ $this->id = $id;
+ $this->save([
+ 'value' => $value,
+ ]);
+ }
+}
diff --git a/app/Plugin/ScoreEngine/View/Helper/EngineOutputterHelper.php b/app/Plugin/ScoreEngine/View/Helper/EngineOutputterHelper.php
index 9c6e749..9195fea 100644
--- a/app/Plugin/ScoreEngine/View/Helper/EngineOutputterHelper.php
+++ b/app/Plugin/ScoreEngine/View/Helper/EngineOutputterHelper.php
@@ -3,41 +3,41 @@
class EngineOutputterHelper extends AppHelper {
- public function generateScoreBoard() {
- if ( !isset($this->settings['data']) ) {
- throw new InternalErrorException('ScoreEngine.EngineOutputter not setup correctly');
- }
-
- $out = '
';
- $out .= '
Team
';
-
- // Grab the first element from the data array
- // This is two lines due to a pass-by-reference warning
- $services = array_values($this->settings['data']);
- $services = array_shift($services);
-
- foreach ( $services AS $service_name => $status ) {
- $out.= '
';
- return $out;
- }
-}
\ No newline at end of file
+ public function generateScoreBoard() {
+ if (!isset($this->settings['data'])) {
+ throw new InternalErrorException('ScoreEngine.EngineOutputter not setup correctly');
+ }
+
+ $out = '
';
+ $out .= '
Team
';
+
+ // Grab the first element from the data array
+ // This is two lines due to a pass-by-reference warning
+ $services = array_values($this->settings['data']);
+ $services = array_shift($services);
+
+ foreach ($services as $service_name => $status) {
+ $out .= '
';
+ return $out;
+ }
+}
diff --git a/app/View/Helper/AuthHelper.php b/app/View/Helper/AuthHelper.php
index 4ded408..1fd22c7 100644
--- a/app/View/Helper/AuthHelper.php
+++ b/app/View/Helper/AuthHelper.php
@@ -3,20 +3,20 @@
class AuthHelper extends AppHelper {
- /**
- * Magic bridge to the AuthComponent
- *
- * If a method being called does not exist, but
- * it exists in AuthComponent, this will 'proxy'
- * the method call to it.
- *
- * @param $name The method name being called
- * @param $args An array of arguments
- * @return mixed
- */
- public function __call($name, $args) {
- if ( method_exists($this->settings['auth'], $name) ) {
- return call_user_func_array([$this->settings['auth'], $name], $args);
- }
- }
-}
\ No newline at end of file
+ /**
+ * Magic bridge to the AuthComponent
+ *
+ * If a method being called does not exist, but
+ * it exists in AuthComponent, this will 'proxy'
+ * the method call to it.
+ *
+ * @param $name The method name being called
+ * @param $args An array of arguments
+ * @return mixed
+ */
+ public function __call($name, $args) {
+ if (method_exists($this->settings['auth'], $name)) {
+ return call_user_func_array([$this->settings['auth'], $name], $args);
+ }
+ }
+}
diff --git a/app/View/Helper/InjectStylerHelper.php b/app/View/Helper/InjectStylerHelper.php
index 0a9569f..0b92c4f 100644
--- a/app/View/Helper/InjectStylerHelper.php
+++ b/app/View/Helper/InjectStylerHelper.php
@@ -2,152 +2,153 @@
App::uses('AppHelper', 'View/Helper');
class InjectStylerHelper extends AppHelper {
- /**
- * Instance of \InjectTypes\Manager
- */
- private $typeManager;
-
- /**
- * Instance of InjectAbstraction
- */
- private $inject;
-
- const TYPE_OUTPUT_TPL = '
'.
- '
%s
';
-
- /**
- * Constructor for the InjectHelper
- *
- * Basically initializes the InjectTypes manager
- */
- public function __construct(View $view, $settings = array()) {
- parent::__construct($view, $settings);
-
- if ( !isset($settings['types']) || !isset($settings['inject']) ) {
- throw new InternalErrorException('InjectStyler is missing types/inject settings');
- }
-
- $this->typeManager = new InjectTypes\Manager($settings['types']);
- $this->setInject($settings['inject']);
- }
-
- /**
- * Set the current inject
- *
- * @param $inject The InjectAbstraction object
- * @return void
- */
- public function setInject($inject) {
- $this->inject = $inject;
- }
-
- /**
- * Time output
- *
- * This will be the inject page's "start/end/duration"
- * area.
- *
- * @param $inject The inject
- * @return string The time content
- */
- public function timeOutput($inject) {
- $template = 'Time: %s Due: %s Duration: %s';
-
- return sprintf($template, $inject->getStartString(), $inject->getEndString(), $inject->getDurationString());
- }
-
- /**
- * Content Output
- *
- * Basically replaces some variables
- * with actual content. Woah!
- *
- * @param $data The inject content
- * @param $userdata Current user information
- * @return string The inject content
- */
- public function contentOutput($data, $userdata) {
- if ( $userdata['Group']['team_number'] == null ) {
- $team = 'X';
- $team_pad = 'XX';
- } else {
- $team = $userdata['Group']['team_number'];
- $team_pad = str_pad($team, 2, '0');
- }
-
- $find = ['#TEAM_NUMBER#', '#TEAM_NUMBER_PADDED#'];
- $replace = [$team, $team_pad];
-
- return str_replace($find, $replace, $data);
- }
-
- /**
- * Inject Type Submission Output
- *
- * @param $id Inject Type ID
- * @return string The template
- */
- public function typeOutput($id) {
- $injectType = $this->typeManager->get($id);
-
- if ( $this->inject->isAcceptingSubmissions() ) {
- $tpl = '';
-
- return $tpl;
- }
-
- if ( $this->inject->isExpired() ) {
- return sprintf(self::TYPE_OUTPUT_TPL, 'Submission for this inject has expired.');
- }
-
- if ( $this->inject->getSubmissionCount() >= $this->inject->getMaxSubmissions() ) {
- return ($this->inject->getMaxSubmissions() > 1
- ? sprintf(self::TYPE_OUTPUT_TPL, 'Max submissions reached.')
- : sprintf(self::TYPE_OUTPUT_TPL, 'This inject has already been submitted.'));
- }
-
- return 'Unknown error';
- }
-
- /**
- * Inject Type Submitted Output
- *
- * @param $id Inject Type ID
- * @return string The template
- */
- public function submittedOutput($id, $submissions) {
- return $this->typeManager->get($id)->getSubmittedTemplate($submissions);
- }
-
- /**
- * Inject Type Grader Output
- *
- * @param $id Inject Type ID
- * @return string The template
- */
- public function graderOutput($id, $submission) {
- return $this->typeManager->get($id)->getGraderTemplate($submission);
- }
-
- /**
- * Get Inject Type Name
- *
- * @param $id Inject Type ID
- * @return string The name
- */
- public function getName($id) {
- return $this->typeManager->get($id)->getName();
- }
-
- /**
- * Get All Types
- *
- * @return array The type objects
- */
- public function getAllTypes() {
- return $this->typeManager->getAll();
- }
-}
\ No newline at end of file
+
+ /**
+ * Instance of \InjectTypes\Manager
+ */
+ private $typeManager;
+
+ /**
+ * Instance of InjectAbstraction
+ */
+ private $inject;
+
+ const TYPE_OUTPUT_TPL = '
'.
+ '
%s
';
+
+ /**
+ * Constructor for the InjectHelper
+ *
+ * Basically initializes the InjectTypes manager
+ */
+ public function __construct(View $view, $settings = []) {
+ parent::__construct($view, $settings);
+
+ if (!isset($settings['types']) || !isset($settings['inject'])) {
+ throw new InternalErrorException('InjectStyler is missing types/inject settings');
+ }
+
+ $this->typeManager = new InjectTypes\Manager($settings['types']);
+ $this->setInject($settings['inject']);
+ }
+
+ /**
+ * Set the current inject
+ *
+ * @param $inject The InjectAbstraction object
+ * @return void
+ */
+ public function setInject($inject) {
+ $this->inject = $inject;
+ }
+
+ /**
+ * Time output
+ *
+ * This will be the inject page's "start/end/duration"
+ * area.
+ *
+ * @param $inject The inject
+ * @return string The time content
+ */
+ public function timeOutput($inject) {
+ $template = 'Time: %s Due: %s Duration: %s';
+
+ return sprintf($template, $inject->getStartString(), $inject->getEndString(), $inject->getDurationString());
+ }
+
+ /**
+ * Content Output
+ *
+ * Basically replaces some variables
+ * with actual content. Woah!
+ *
+ * @param $data The inject content
+ * @param $userdata Current user information
+ * @return string The inject content
+ */
+ public function contentOutput($data, $userdata) {
+ if ($userdata['Group']['team_number'] == null) {
+ $team = 'X';
+ $team_pad = 'XX';
+ } else {
+ $team = $userdata['Group']['team_number'];
+ $team_pad = str_pad($team, 2, '0');
+ }
+
+ $find = ['#TEAM_NUMBER#', '#TEAM_NUMBER_PADDED#'];
+ $replace = [$team, $team_pad];
+
+ return str_replace($find, $replace, $data);
+ }
+
+ /**
+ * Inject Type Submission Output
+ *
+ * @param $id Inject Type ID
+ * @return string The template
+ */
+ public function typeOutput($id) {
+ $injectType = $this->typeManager->get($id);
+
+ if ($this->inject->isAcceptingSubmissions()) {
+ $tpl = '';
+
+ return $tpl;
+ }
+
+ if ($this->inject->isExpired()) {
+ return sprintf(self::TYPE_OUTPUT_TPL, 'Submission for this inject has expired.');
+ }
+
+ if ($this->inject->getSubmissionCount() >= $this->inject->getMaxSubmissions()) {
+ $tpl_max = sprintf(self::TYPE_OUTPUT_TPL, 'Max submissions reached.');
+ $tpl_sub = sprintf(self::TYPE_OUTPUT_TPL, 'This inject has already been submitted.');
+ return ($this->inject->getMaxSubmissions() > 1 ? $tpl_max : $tpl_sub);
+ }
+
+ return 'Unknown error';
+ }
+
+ /**
+ * Inject Type Submitted Output
+ *
+ * @param $id Inject Type ID
+ * @return string The template
+ */
+ public function submittedOutput($id, $submissions) {
+ return $this->typeManager->get($id)->getSubmittedTemplate($submissions);
+ }
+
+ /**
+ * Inject Type Grader Output
+ *
+ * @param $id Inject Type ID
+ * @return string The template
+ */
+ public function graderOutput($id, $submission) {
+ return $this->typeManager->get($id)->getGraderTemplate($submission);
+ }
+
+ /**
+ * Get Inject Type Name
+ *
+ * @param $id Inject Type ID
+ * @return string The name
+ */
+ public function getName($id) {
+ return $this->typeManager->get($id)->getName();
+ }
+
+ /**
+ * Get All Types
+ *
+ * @return array The type objects
+ */
+ public function getAllTypes() {
+ return $this->typeManager->getAll();
+ }
+}
diff --git a/app/View/Helper/MiscHelper.php b/app/View/Helper/MiscHelper.php
index 491f1d3..6716676 100644
--- a/app/View/Helper/MiscHelper.php
+++ b/app/View/Helper/MiscHelper.php
@@ -2,25 +2,26 @@
App::uses('AppHelper', 'View/Helper');
class MiscHelper extends AppHelper {
- const NAVBAR_ITEM = '