├── .gitattributes
├── .gitignore
├── LICENSE.md
├── README.md
├── allocate.php
├── backup.php
├── batches.php
├── connect_db.php
├── courses.php
├── create_tables.sql
├── css
├── chosen.css
├── dashboard.css
├── styles.css
└── table.css
├── dean.php
├── depts.php
├── download.php
├── faculty.php
├── fonts
├── candara-webfont.eot
├── candara-webfont.svg
├── candara-webfont.ttf
├── candara-webfont.woff
└── candaraz-webfont.eot
├── functions.php
├── images
├── accbg.png
├── add.png
├── avatar.png
├── base.png
├── bg.jpg
├── box_bottom.png
├── box_center.png
├── box_top.png
├── checkbox.png
├── chosen-sprite.png
├── chosen-sprite@2x.png
├── currentM.png
├── db.png
├── details_icon.png
├── details_icon2.png
├── favicon.png
├── foot.png
├── information.png
├── key.png
├── loader_green.gif
├── logout.png
├── menu_bg.jpg
├── pick_bg.jpg
├── pswd_icon.png
├── pwd_icon.png
├── radio.png
├── remove.png
├── screenshot_allocation.png
├── screenshot_slots.png
├── screenshot_users.png
├── seletedown.png
├── seleteup.png
├── shape.png
├── timetable.png
├── top_bgrepeat.jpg
├── uInfo_icon.png
└── usr_icon.png
├── index.php
├── js
├── capture.js
├── chosen.js
├── form.js
├── grid.js
├── jquery.min.js
├── ui-touch-punch.min.js
└── ui.min.js
├── login.php
├── logout.php
├── manage.php
├── phantomjs
├── phantomjs
└── phantomjs.exe
├── register.php
├── rooms.php
└── setup.php
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Windows image file caches
2 | Thumbs.db
3 | ehthumbs.db
4 |
5 | # Folder config file
6 | Desktop.ini
7 |
8 | # Recycle Bin used on file shares
9 | $RECYCLE.BIN/
10 |
11 | # Windows Installer files
12 | *.cab
13 | *.msi
14 | *.msm
15 | *.msp
16 |
17 | # Windows shortcuts
18 | *.lnk
19 |
20 | # =========================
21 | # Operating System Files
22 | # =========================
23 |
24 | # OSX
25 | # =========================
26 |
27 | .DS_Store
28 | .AppleDouble
29 | .LSOverride
30 |
31 | # Thumbnails
32 | ._*
33 |
34 | # Files that might appear on external disk
35 | .Spotlight-V100
36 | .Trashes
37 |
38 | # Directories potentially created on remote AFP share
39 | .AppleDB
40 | .AppleDesktop
41 | Network Trash Folder
42 | Temporary Items
43 | .apdisk
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | QuickSlots: A web-based timetable management system
2 | ----------
3 |
4 |
5 | --------------------------------------------------------------------------------
6 | Features
7 | --------------------------------------------------------------------------------
8 |
9 | * Light-Weight: The whole application, including all images,scripts and
10 | stylesheets, is only 1.35 MB uncompressed and just 714KB when compressed.
11 |
12 | * Fully automated installer: QuickSlots comes with a fully automated installer,
13 | meaning that the administrator just has to run the installer and does not
14 | have to look into ANY PART OF THE SOURCE CODE AT ALL.
15 |
16 | * One-click total system backup and restore: Backup and restore settings and
17 | databases, even across different servers, just with a single click.
18 |
19 | * Generate ready-to-print timetable image snapshots.
20 |
21 | * Support for LDAP authentication.
22 |
23 | --------------------------------------------------------------------------------
24 | Screenshots
25 | --------------------------------------------------------------------------------
26 | User management:
27 |
28 | 
29 |
30 | Slots Configuration:
31 |
32 | 
33 |
34 | Timetable Allocation:
35 |
36 | 
37 |
38 | --------------------------------------------------------------------------------
39 | Files and Descriptions
40 | --------------------------------------------------------------------------------
41 |
42 | * .\setup.php
43 | -- Initial system setup.
44 | * .\index.php
45 | -- Displays the timetable applying the provided filters, if any.
46 | * .\login.php
47 | -- Provides interface and back end routines that handle user logins.
48 | * .\logout.php
49 | -- Logs out the user when visited
50 | * .\allocate.php
51 | -- Provides interface and back end routines for allocation of courses to
52 | time slots
53 | * .\dean.php
54 | -- Homepage of dean level users, it provides interface and back end
55 | routines to edit and save global settings. Access is restricted to dean
56 | level users.
57 | * .\manage.php
58 | -- Provides interface and back end routines to manage departments, faculty,
59 | batches and rooms. Access is restricted to dean level users.
60 | * .\faculty.php
61 | -- Homepage of HOD and faculty level users, provides interfaces to
62 | add/delete courses. Access requires at least faculty level account.
63 | * .\register.php
64 | -- Contains back end routines for user management. It is invoked by
65 | manage.php and setup.php
66 | * .\connect_db.php
67 | -- Initiates database connections. Required by all files that needs to
68 | perform database operations
69 | * .\functions.php
70 | -- Contains various common helper routines used across most files
71 | * .\courses.php
72 | -- Contains back end routines to add/delete courses. It is invoked by
73 | faculty.php
74 | * .\batches.php
75 | -- Contains back end routines to add/delete batches. It is invoked by
76 | manage.php
77 | * .\depts.php
78 | -- Contains back end routines to add/delete batches. It is invoked by
79 | manage.php
80 | * .\rooms.php
81 | -- Contains back end routines to add/delete batches. It is invoked by
82 | dean.php
83 | * .\backup.php
84 | -- Contains back end routines to generate/restore backups, invoked by
85 | dean.php
86 | * .\download.php
87 | -- Back end routines that call PhantomJS to generate printable timetable
88 | snapshot images.
89 | * .\js\grid.js
90 | -- Client side script to render timetable grids
91 | * .\js\form.js
92 | -- Handles all form submissions and validation that needs to be done via
93 | AJAX
94 | * .\js\capture.js
95 | -- Contains PhantomJS routines for printable table snapshot generation
96 | * .\css\styles.css
97 | -- Defines generic styles shared by the whole QuickSlots UI
98 | * .\css\table.css
99 | -- Defines generic styles for QuickSlots table grids
100 | * .\css\dashboard.css
101 | -- Defines the stylings for various elements of the dashboard
102 |
103 | --------------------------------------------------------------------------------
104 | External Libraries and Programs Used
105 | --------------------------------------------------------------------------------
106 |
107 | * PhantomJS: PhantomJS web stack (for generating screenshots)
108 | (https://phantomjs.org/)
109 |
110 | * jQuery Core: The jQuery Core javascript library (https://jquery.com/)
111 |
112 | * jQuery UI: The jQuery UI library (https://jqueryui.com/)
113 |
114 | * jQuery UI Touch Punch: Touch Event Support for jQuery UI
115 | (http://touchpunch.furf.com/)
116 |
117 | * Chosen.js: Select Box Enhancer for jQuery (http://harvesthq.github.io/chosen/)
118 |
119 | --------------------------------------------------------------------------------
120 | System Requirements
121 | --------------------------------------------------------------------------------
122 |
123 | * Apache Web Server: Version 2.4 or higher recommended
124 |
125 | * MYSQL Database Engine: Version 5.5 or higher recommended
126 |
127 | * PHP Hypertext Preprocessor: Version 5.5 or higher recommended
128 |
129 | --------------------------------------------------------------------------------
130 | Installation Instructions
131 | --------------------------------------------------------------------------------
132 |
133 | * Make sure that the apache user has read/write permissions on the file
134 | "config.php", and the directory "tmp", used respectively for configuration and
135 | backup & screen-shot generation.
136 |
137 | * Visit setup.php through a web browser and provide the required database and
138 | LDAP configurations. Thereafter, set up the first dean/admin account
139 | to complete the setup.
140 |
141 | --------------------------------------------------------------------------------
142 | Usage Instructions
143 | --------------------------------------------------------------------------------
144 |
145 | * Login using the "dean"(admin) account. You will be redirected to the
146 | "Manage Timetables" page.
147 |
148 | * Create a timetable by clicking on the drop-down on top, beside "Configure
149 | Timetable:"
150 |
151 | * Add departments, faculty, courses and rooms.
152 |
153 | * HOD of every department can create courses and allocate timetables for all
154 | faculty of his/her department.
155 |
156 | * Faculty is the account with the least set of privileges: creating courses and
157 | managing, the timetable for his courses. These privileges are shared by the
158 | HOD and dean as well.
159 |
160 | --------------------------------------------------------------------------------
161 | Viewing the timetable
162 | --------------------------------------------------------------------------------
163 |
164 | The timetable can be viewed by two groups of users:
165 |
166 | * Public/guest users (like students):
167 | - Without needing any login, guest users can either visit the application
168 | web-root to view the timetable by applying filters on their own, or by
169 | visiting the links generated by faculty.
170 | - When they visit the web-root, only the current active timetable is displayed
171 | by default. As before, users can further apply the various filters such to
172 | find what they need.
173 | - The system also displays a link based on these filters which can be
174 | saved/bookmarked by them for direct display of the filtered timetable.
175 |
176 | * Authorized users (Faculty/HOD/Dean):
177 | - Once authenticated faculty can view, generate links and download snapshots
178 | for all instances of the timetable, with any set of filters applied.
179 |
180 | --------------------------------------------------------------------------------
181 | Manage Timetable Instructions
182 | --------------------------------------------------------------------------------
183 |
184 | * Multiple instances of timetable can be created. While creating a new
185 | timetable, number of slots, working days and starting time can be configured.
186 |
187 | * In a authenticated users can easily manage timetable with the help of the
188 | intuitive GUI and instructions that accompany.
189 |
190 | * Timetables can be frozen by a dean at any time when a finalized timetable is
191 | needed. It can be used if you want to avoid any accidental changes on the
192 | timetable once finalized. A frozen timetable cannot be edited unless a dean
193 | choses to de-freeze it.
194 |
195 | --------------------------------------------------------------------------------
196 | Backup/Restore
197 | --------------------------------------------------------------------------------
198 |
199 | * The system allows the dean to download a whole backup of the database.
200 |
201 | * System can be restored to the previous state by uploading the backup file
202 | back.
--------------------------------------------------------------------------------
/allocate.php:
--------------------------------------------------------------------------------
1 | prepare('SELECT uName FROM faculty where uName = ? AND dept_code=?');
22 | $query->execute([$_GET['faculty'],$_SESSION['dept']]);
23 | $fac = $query->fetch();
24 | if(!empty($fac['uName']))
25 | $_SESSION['faculty'] = $_GET['faculty'];
26 | }
27 | }
28 | $query = $db->prepare('SELECT * FROM courses where fac_id = ?');
29 | $query->execute([$_SESSION['faculty']]);
30 | $courses = $query->fetchall();
31 | foreach ($courses as $course) {
32 | if($course['allow_conflict'] && $current['allowConflicts'])
33 | continue;
34 | $blocked[$course['course_id']] = [];
35 | $filter = !$current['allowConflicts']?"OR allow_conflict=1":"";
36 | $query = $db->prepare("SELECT course_id,count(*) as batches FROM
37 | (SELECT * FROM allowed where course_id NOT IN
38 | (SELECT course_id FROM courses where fac_id = ? $filter)) other NATURAL JOIN
39 | (SELECT batch_name,batch_dept FROM allowed where course_id=?) batches
40 | group by course_id");
41 |
42 | $query->execute([$_SESSION['faculty'],$course['course_id']]);
43 |
44 | $conflicts = $query->fetchall();
45 |
46 | foreach ($conflicts as $conflict)
47 | {
48 | $query = $db->prepare('SELECT day,slot_num FROM slot_allocs where table_name=? AND course_id=?');
49 | $query->execute([$current['table_name'],$conflict['course_id']]);
50 | $conf_slots=$query->fetchall();
51 | foreach ($conf_slots as $conf_slot)
52 | {
53 | $slotStr = $conf_slot['day']. "_" .$conf_slot['slot_num'];
54 | if(isset($blocked[$course['course_id']][$slotStr]))
55 | $blocked[$course['course_id']][$slotStr] += $conflict['batches'];
56 | else
57 | $blocked[$course['course_id']][$slotStr] = $conflict['batches'];
58 | }
59 | }
60 | }
61 |
62 | if(valueCheck('action','saveSlots'))
63 | {
64 | if($current['frozen'])
65 | postResponse("error","This timetable has been frozen");
66 | foreach ($_POST as $slotStr => $course_room)
67 | {
68 | $course=explode(':', $course_room)[0];
69 | if(!empty($blocked[$course][$slotStr]))
70 | postResponse("redirect","allocate.php?error=conflict");
71 | }
72 | $query = $db->prepare('DELETE FROM slot_allocs where table_name=? AND course_id IN (SELECT course_id FROM courses where fac_id=?)');
73 | $query->execute([$current['table_name'],$_SESSION['faculty']]);
74 | $query = $db->prepare('INSERT INTO slot_allocs values(?,?,?,?,?)');
75 | try
76 | {
77 | foreach ($_POST as $slotStr => $course_room)
78 | {
79 | $course_room = explode(':', $course_room);
80 | $course = $course_room[0];
81 | $room = $course_room[1];
82 | $slot = explode('_', $slotStr);
83 | $query->execute([$current['table_name'],$slot[0],$slot[1],$room,$course]);
84 | }
85 | }
86 | catch(PDOException $e)
87 | {
88 | if($e->errorInfo[0]==23000)
89 | postResponse("error","The selected room has been booked already, rooms list has been refreshed");
90 | else
91 | postResponse("error",$e->errorInfo[2]);
92 | }
93 | postResponse("info","Slots Saved");
94 | die();
95 | }
96 | if(valueCheck('action','queryRooms'))
97 | {
98 | $slot = explode('_', $_POST["slot"]);
99 | $query = $db->prepare('SELECT min(size) FROM allowed NATURAL JOIN batches where course_id=?');
100 | $query->execute([$_POST['course']]);
101 | $minCap = $query->fetch()[0];
102 | $query = $db->prepare('SELECT room_name,capacity FROM rooms
103 | where capacity>=? AND room_name NOT IN
104 | (SELECT room FROM slot_allocs where table_name=? AND day=? AND slot_num=?
105 | AND course_id NOT IN (SELECT course_id FROM courses where fac_id=?)
106 | ) ORDER BY capacity');
107 | $query->execute([$minCap,$current['table_name'],$slot[0],$slot[1],$_SESSION['faculty']]);
108 | $rooms = $query->fetchall(PDO::FETCH_NUM);
109 | die(json_encode($rooms));
110 | }
111 | if(valueCheck('action','queryConflict'))
112 | {
113 | $slot = explode('_', $_POST["slot"]);
114 | $query = $db->prepare('SELECT course_id,course_name,fac_id,fac_name,GROUP_CONCAT(CONCAT(batch_name,\' : \',batch_dept) ORDER BY batch_name SEPARATOR \', \') as batches from allowed NATURAL JOIN courses NATURAL JOIN (SELECT fac_name,uName as fac_id from faculty) faculty where course_id IN (SELECT course_id from slot_allocs where table_name=? AND day=? AND slot_num=?) AND (batch_name,batch_dept) IN (SELECT batch_name,batch_dept FROM allowed where course_id=?) GROUP BY course_id');
115 | $query->execute([$current['table_name'],$slot[0],$slot[1],$_POST['course']]);
116 | $conflicts = $query->fetchall();
117 | $inf_html = "";
118 | foreach ($conflicts as $conflict) {
119 | $fac_info = $conflict['fac_name'];
120 | if(!sessionCheck('level','faculty'))
121 | $fac_info = "{$conflict['fac_name']}";
122 | $inf_html .= <<
124 |
402 |
403 | ● Drag and Drop a course from the right panel to the required slot
404 | ● Double-click on a slot to clear it
405 | ● Conflicting Slots are indicated in red and would contain the number of batches affected
406 | ● A '~' before a course indicates that its conflicts are not considered
407 |
408 |
409 |
410 | prepare("SELECT * FROM slots WHERE table_name=? AND state='disabled'");
412 | $query->execute([$current['table_name']]);
413 | $disabled = $query->fetchall();
414 | foreach ($disabled as $slot)
415 | echo '';
416 | ?>
417 |