diff --git a/.gitignore b/.gitignore index ece92f918d1aa4b7b3cef2b078b4fe9b68c92a1e..fce9dbb845b358e601b76dc08e17996aa376fc40 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ nbproject/ /.project /.idea ~dev_rating/.idea/ +/~dev_rating/modules/unittest/vendor/ \ No newline at end of file diff --git a/db/Sample.sql b/db/Sample.sql deleted file mode 100644 index 310723c98f2c62494ee9df206fc1e0a9d0be2df7..0000000000000000000000000000000000000000 --- a/db/Sample.sql +++ /dev/null @@ -1,306 +0,0 @@ --- phpMyAdmin SQL Dump --- version 4.0.10 --- http://www.phpmyadmin.net --- --- РҐРѕСЃС‚: 127.0.0.1:3306 --- Время создания: РђРІРі 28 2014 Рі., 19:29 --- Версия сервера: 5.5.37-log --- Версия PHP: 5.3.28 - -SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; -SET time_zone = "+00:00"; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; - --- --- База данных: `Sample2` --- - --- --- Дамп данных таблицы `grades` --- -INSERT INTO `grades` (`ID`, `Num`, `Degree`) VALUES -(1, 1, 'bachelor'), -(2, 2, 'bachelor'), -(3, 3, 'bachelor'), -(4, 4, 'bachelor'), -(5, 5, 'specialist'), -(6, 1, 'master'), -(7, 2, 'master'); - --- --- Дамп данных таблицы `job_positions` --- - -INSERT INTO `job_positions` (`ID`, `Name`) VALUES -(1, 'Аспирант'), -(2, 'Ассистент'), -(3, 'Ведущий научный сотрудник'), -(4, 'Главный научный сотрудник'), -(5, 'Докторант'), -(6, 'Доцент'), -(7, 'Младший научный сотрудник'), -(8, 'Научный сотрудник'), -(9, 'Преподаватель'), -(10, 'Профессор'), -(11, 'Старший преподаватель'), -(12, 'Стажер'), -(13, 'Старший научный сотрудник'); - --- --- Дамп данных таблицы `accounts` --- - -INSERT INTO `accounts` (`ID`, `Login`, `Password`, `EMail`, `UserRoleID`, `ActivationCode`, `isEnabled`, `UserAgent`) VALUES -(1, 'student1', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student1@mail.ru', 1, NULL, 1, NULL), -(2, 'student2', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student2@mail.ru', 1, NULL, 1, NULL), -(3, 'student3', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student3@mail.ru', 1, NULL, 1, NULL), -(4, 'student4', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student4@mail.ru', 1, NULL, 1, NULL), -(5, 'student5', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student5@mail.ru', 1, NULL, 1, NULL), -(6, 'student6', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student6@mail.ru', 1, NULL, 1, NULL), -(7, 'student7', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student7@mail.ru', 1, NULL, 1, NULL), -(8, 'student8', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student8@mail.ru', 1, NULL, 1, NULL), -(9, NULL, NULL, NULL, 1, 'code2', 1, NULL), -(10, 'student10', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student10@mail.ru', 1, NULL, 1, NULL), -(11, 'student11', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student11@mail.ru', 1, NULL, 1, NULL), -(12, 'student12', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student12@mail.ru', 1, NULL, 1, NULL), -(13, 'student13', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student13@mail.ru', 1, NULL, 1, NULL), -(14, 'student14', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student14@mail.ru', 1, NULL, 1, NULL), -(15, 'student15', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'student15@mail.ru', 1, NULL, 1, NULL), -(16, 'teacher1', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'teacher1@mail.ru', 2, NULL, 1, NULL), -(17, 'teacher2', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'teacher2@mail.ru', 2, NULL, 1, NULL), -(18, 'teacher3', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'teacher3@mail.ru', 3, NULL, 1, NULL), -(19, 'teacher4', '7b21848ac9af35be0ddb2d6b9fc3851934db8420', 'teacher4@mail.ru', 2, NULL, 1, NULL), -(20, NULL, NULL, NULL, 2, 'code1', 1, NULL); - - --- --- Дамп данных таблицы `faculties` --- - -INSERT INTO `faculties` (`ID`, `Name`, `Abbr`) VALUES -(1, 'Рнститут математики, механики Рё компьютерных наук', 'Мехмат'), -(2, 'Юридический факультет', 'Юрфак'); - - --- --- Дамп данных таблицы `subjects` --- - -INSERT INTO `subjects` (`ID`, `Name`, `Abbr`) VALUES -(1, 'Математический анализ', 'Матан'), -(2, 'Дифференциальные уравнения', 'Диф. СѓСЂ-СЏ'), -(3, 'Рностранный язык', 'РРЅ.СЏР·.'), -(4, 'Операционные системы', 'РћРЎ'), -(5, 'Международное право', 'Меж. РїСЂ-РІРѕ'), -(6, 'Р РёРјСЃРєРѕРµ право', 'Р РёРј. РїСЂ-РІРѕ'); - - --- --- Дамп данных таблицы `subjects_faculties` --- - -INSERT INTO `subjects_faculties` (`ID`, `SubjectID`, `FacultyID`) VALUES -(1, 1, 1), -(2, 2, 1), -(3, 3, 1), -(4, 3, 2), -(5, 4, 1), -(6, 5, 2), -(7, 6, 2); - - - --- --- Дамп данных таблицы `departments` --- - -INSERT INTO `departments` (`ID`, `Name`, `FacultyID`) VALUES -(1, 'Кафедра алгебры Рё дискретной математики', 1), -(2, 'Кафедра высокопроизводительных вычислений Рё информационно-​коммуникационных технологий', 1), -(3, 'Кафедра вычислительной математики Рё математической физики', 1), -(4, 'Кафедра геометрии', 1), -(5, 'Кафедра дифференциальных Рё интегральных уравнений', 1), -(6, 'Кафедра информатики Рё вычислительного эксперимента', 1), -(7, 'Кафедра высшей математики Рё исследования операций ', 1), -(8, 'Кафедра математического анализа', 1), -(9, 'Кафедра математического моделирования', 1), -(10, 'Кафедра прикладной математики Рё программирования', 1), -(11, 'Кафедра теоретической Рё компьютерной гидроаэродинамики', 1), -(12, 'Кафедра теории упругости', 1), -(13, 'Кафедра технологий автоматизации РІ бизнесе', 1), -(14, NULL, 1), -(15, 'Кафедра международного права', 2), -(16, NULL, 2); - --- --- Дамп данных таблицы `semesters` --- - -INSERT INTO `semesters` (`ID`, `Year`, `Num`) VALUES -(1, 2014, 1); - --- --- Дамп данных таблицы `specializations` --- - -INSERT INTO `specializations` (`ID`, `Name`, `Abbr`, `FacultyID`) VALUES -(1, 'Прикладная математика Рё информатика', 'РџРњРёР', 1), -(2, 'Рнформационные технологии', 'РРў', 1), -(3, 'Математика', 'Матем', 1), -(4, 'Механика', 'Механика', 1), -(5, NULL, NULL, 1), -(6, NULL, NULL, 2); - --- --- Дамп данных таблицы `study_groups` --- - -INSERT INTO `study_groups` (`ID`, `GradeID`, `GroupNum`, `SpecializationID`, `Name`) VALUES -(1, 1, 1, 1, NULL), -(2, 1, 2, 5, NULL), -(3, 1, 3, 2, NULL), -(4, 2, 1, 1, NULL); - --- --- Дамп данных таблицы `students` --- - -INSERT INTO `students` (`ID`, `StudyGroupID`, `AccountID`, `LastName`, `FirstName`, `SecondName`) VALUES -(1, 1, 1, 'Началов', 'Сергей', 'Петрович'), -(2, 1, 2, 'РњРёСЂРѕРЅРѕРІР°', 'Людмила', 'Ргоревна'), -(3, 1, 3, 'Гервич', 'Лев', 'Романович'), -(4, 1, 4, 'Кузнецов', 'Валентин', 'Сергеевич'), -(5, 1, 5, 'Трошкина', 'Екатерина', 'Сергеевна'), -(6, 2, 6, 'Пустовалова', 'Жанна', 'Михайловна'), -(7, 2, 7, 'Каменюкин', 'Роман', 'Васильевич'), -(8, 2, 8, 'Сапрыкин', 'Михаил', 'Рванович'), -(9, 2, 9, 'Брагин', 'Николай', 'Карпович'), -(10, 2, 10, 'Поркофьева', 'РСЂРёРЅР°', 'Витальевна'), -(11, 3, 11, 'Кошкина', 'Антонина', 'Михайловна'), -(12, 3, 12, 'РљСѓСЂРґСЋРјРѕРІ', 'Алексей', 'Николаевич'), -(13, 3, 13, 'Шульженко', 'Александр', 'Михайлович'), -(14, 3, 14, 'Мальцева', 'РђРЅРЅР°', 'Юрьевна'), -(15, 3, 15, 'Константинов', 'Антон', 'Витальевич'); - --- --- Дамп данных таблицы `teachers` --- - -INSERT INTO `teachers` (`ID`, `LastName`, `FirstName`, `SecondName`, `JobPositionID`, `DepartmentID`, `AccountID`) VALUES -(1, 'Лобачевский', 'Николай', 'Рванович', 1, 14, 16), -(2, 'Лафонтен', 'РђРЅСЂРё', NULL, 2, 14, 17), -(3, 'Карамзин', 'Николай', 'Михайлович', 3, 14, 18), -(4, 'Пачоли', 'Лука', NULL, 3, 1, 19), -(5, 'Менделеев', 'Дмитрий', 'Рванович', 3, 14, 20); - --- --- Дамп данных таблицы `disciplines` --- - -INSERT INTO `disciplines` (`ID`, `GradeID`, `SubjectID`, `AuthorID`, `ExamType`, `SemesterID`, `PracticeCount`, `LectionCount`, `FacultyID`) VALUES -(1, 1, 1, 1, 'exam', 1, 0, 36, 1), -(2, 1, 5, 2, 'exam', 1, 18, 36, 1), -(3, 1, 2, 1, 'credit', 1, 18, 0, 1), -(4, 1, 4, 1, 'credit', 1, 18, 0, 1); - --- --- Дамп данных таблицы `modules` --- - -INSERT INTO `modules` (`ID`, `Name`, `OrderNum`, `DisciplineID`, `Type`) VALUES -(1, 'Ркзамен', 100, 1, 2), -(2, 'Теория пределов', 2, 1, 1), -(3, 'Дифференцирование', 3, 1, 1), -(4, 'Рнтегрирование', 4, 1, 1), -(5, 'Ркзамен', 100, 2, 2), -(6, 'Модуль 1', 2, 2, 1), -(7, 'Модуль 2', 3, 2, 1), -(8, 'Линейные дифференциальные уравнения', 1, 3, 1), -(9, 'Дифференциальные уравнения второго РїРѕСЂСЏРґРєР°', 2, 3, 1), -(10, 'Устройство операцинных систем', 1, 4, 1), -(11, 'Многопоточность', 2, 4, 1), -(12, 'Добор баллов', 50, 1 , 4), -(13, 'Добор баллов', 50, 2 , 4); - --- --- Дамп данных таблицы `submodules` --- - -INSERT INTO `submodules` (`ID`, `ModuleID`, `Name`, `OrderNum`, `MaxRate`, `Description`, `Type`) VALUES -(1, 2, 'Ответы РЅР° занятиях', 1, 5, '', 'CurrentControl'), -(2, 2, 'Тест', 2, 5, '', 'CurrentControl'), -(3, 2, 'Контрольная работа', 3, 10, '', 'LandmarkControl'), -(4, 3, 'Ответы РЅР° занятиях', 1, 5, '', 'CurrentControl'), -(5, 3, 'Рндивидуальные задания', 2, 5, '', 'CurrentControl'), -(6, 3, 'Контрольная работа', 3, 10, '', 'LandmarkControl'), -(7, 4, 'Ответы РЅР° занятиях', 1, 5, '', 'CurrentControl'), -(8, 4, 'Самостоятельная работа', 2, 5, '', 'CurrentControl'), -(9, 4, 'Контрольная работа', 3, 10, '', 'LandmarkControl'), -(10, 6, 'Ответы РЅР° занятиях', 1, 10, '', 'CurrentControl'), -(11, 6, 'Реферат', 2, 10, '', 'CurrentControl'), -(12, 6, 'Контрольная работа', 3, 10, '', 'LandmarkControl'), -(13, 7, 'Ответы РЅР° занятиях', 1, 10, '', 'CurrentControl'), -(14, 7, 'Доклад', 2, 10, '', 'CurrentControl'), -(15, 7, 'Контрольная работа', 3, 10, '', 'LandmarkControl'), -(16, 8, 'Ответы РЅР° занятиях', 1, 10, '', 'CurrentControl'), -(17, 8, 'Домашние задания', 2, 10, '', 'CurrentControl'), -(18, 8, 'Самостоятельная работа', 3, 10, '', 'CurrentControl'), -(19, 8, 'Контрольный тест', 4, 20, '', 'LandmarkControl'), -(20, 9, 'Ответы РЅР° занятиях', 1, 10, '', 'CurrentControl'), -(21, 9, 'Домашние задания', 2, 10, '', 'CurrentControl'), -(22, 9, 'Рндивидуальное задание', 3, 10, '', 'CurrentControl'), -(23, 9, 'Контрольный тест', 4, 20, '', 'LandmarkControl'), -(24, 10, 'Домашние задания', 1, 10, '', 'CurrentControl'), -(25, 10, 'Рндивидуальное задание', 2, 10, '', 'CurrentControl'), -(26, 10, 'Самостоятельная работа', 3, 10, '', 'CurrentControl'), -(27, 10, 'Коллоквиум', 4, 20, '', 'LandmarkControl'), -(28, 11, 'Домашние задания', 1, 10, '', 'CurrentControl'), -(29, 11, 'Рндивидуальное задание', 2, 10, '', 'CurrentControl'), -(30, 11, 'Контрольный работа', 3, 20, '', 'LandmarkControl'), -(31, 1, '', 1, 40, '', 'LandmarkControl'), -(32, 1, '', 2, 40, '', 'LandmarkControl'), -(33, 1, '', 3, 40, '', 'LandmarkControl'), -(34, 5, '', 1, 40, '', 'LandmarkControl'), -(35, 5, '', 2, 40, '', 'LandmarkControl'), -(36, 5, '', 3, 40, '', 'LandmarkControl'), -(37, 12, '', 1, 38, NULL, 'LandmarkControl'), -(38, 13, '', 1, 38, NULL, 'LandmarkControl'); - --- --- Дамп данных таблицы `disciplines_teachers` --- - -INSERT INTO `disciplines_teachers` (`ID`, `DisciplineID`, `TeacherID`) VALUES -(1, 1, 1), -(2, 1, 3), -(3, 2, 2), -(4, 3, 1), -(5, 4, 1); - --- --- Дамп данных таблицы `disciplines_groups` --- - -INSERT INTO `disciplines_groups` (`ID`, `DisciplineID`, `StudyGroupID`) VALUES -(1, 1, 3), -(2, 2, 1), -(3, 2, 2), -(4, 2, 3), -(5, 3, 1), -(6, 3, 2), -(7, 3, 3), -(8, 4, 1), -(9, 4, 2), -(10, 4, 3); - - - - -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/db/StoredFunctions.sql b/db/StoredFunctions.sql new file mode 100644 index 0000000000000000000000000000000000000000..079107647fb210a16c11699173c6e176f5a30ec5 --- /dev/null +++ b/db/StoredFunctions.sql @@ -0,0 +1,2249 @@ +DELIMITER // + +DROP FUNCTION IF EXISTS GetGradeID// +DROP FUNCTION IF EXISTS SetCurSemesterID// +DROP FUNCTION IF EXISTS SetHashKey// + +drop function if exists InternalIsTeacherBinded// +DROP FUNCTION IF EXISTS GetSemesterID// + +DROP FUNCTION IF EXISTS GetRateForDiscExtra// +DROP FUNCTION IF EXISTS GetRateForDiscBonus// +DROP FUNCTION IF EXISTS GetRateForDiscSemester// +DROP FUNCTION IF EXISTS GetRateForDiscExamNum// +DROP FUNCTION IF EXISTS GetRateForDiscExam// +DROP FUNCTION IF EXISTS InternalNotify// +DROP FUNCTION IF EXISTS GetDisciplineMaxRate// +DROP FUNCTION IF EXISTS OrderModuleTypesForSession// + +DROP FUNCTION IF EXISTS CreateStudyGroup// + + +# ------------------------------------------------------------------------------------------- +# Label: abbreviations +# ------------------------------------------------------------------------------------------- + +# abbreviation: abbr +# specialization: spec +# department: dep + +# ------------------------------------------------------------------------------------------- +# Label: internals +# ------------------------------------------------------------------------------------------- + +# actually check for first scoring, in this case you cannot yet edit discipline +# "SetRate" stored procedure can change isLocked flag +DROP FUNCTION IF EXISTS InternalIsMapLocked// +CREATE FUNCTION `InternalIsMapLocked` + (`pDisciplineID` INT) RETURNS BOOLEAN + NO SQL +BEGIN + RETURN EXISTS( + SELECT * FROM `disciplines` + WHERE disciplines.ID = pDisciplineID AND disciplines.isLocked = 1 + ); +END // + + +# check, that student really take this course +DROP FUNCTION IF EXISTS InternalIsStudentAttached// +CREATE FUNCTION `InternalIsStudentAttached` + (`pStudentID` INT, `pDisciplineID` INT) RETURNS BOOLEAN + NO SQL +BEGIN + RETURN EXISTS( + SELECT * FROM `view_disciplines_students` + WHERE view_disciplines_students.SemesterID = @CurrentSemesterID AND + view_disciplines_students.StudentID = pStudentID AND + view_disciplines_students.DisciplineID = pDisciplineID AND + (view_disciplines_students.AttachType IS NULL OR + view_disciplines_students.AttachType = 'attach') + ); +END // + + +# check, that teacher teach this course +drop function if exists InternalIsTeacherBounded// +CREATE FUNCTION `InternalIsTeacherBounded` + ( `pTeacherID` INT, `pDisciplineID` INT) RETURNS BOOLEAN + NO SQL +BEGIN + RETURN EXISTS (SELECT * FROM `disciplines_teachers` + WHERE disciplines_teachers.TeacherID = pTeacherID AND + disciplines_teachers.DisciplineID = pDisciplineID); +END // + + +DROP FUNCTION IF EXISTS InternalIsTeacherAuthor// +CREATE FUNCTION `InternalIsTeacherAuthor` + ( `pTeacherID` INT, `pDisciplineID` INT) RETURNS BOOLEAN + NO SQL +BEGIN + RETURN EXISTS (SELECT * FROM `disciplines` + WHERE disciplines.ID = pDisciplineID AND disciplines.AuthorID = pTeacherID); +END // + + +DROP FUNCTION IF EXISTS GetRateForDisc// +CREATE FUNCTION `GetRateForDisc` + ( `pStudentID` INT, `pDisciplineID` INT) RETURNS int(11) + NO SQL +BEGIN + DECLARE vRate INT DEFAULT -1; + + SELECT SUM(rating_table.Rate) + INTO vRate + FROM `rating_table` + INNER JOIN `submodules` ON rating_table.SubmoduleID = submodules.ID + INNER JOIN `modules` ON submodules.ModuleID = modules.ID AND + modules.DisciplineID = pDisciplineID + WHERE rating_table.StudentID = pStudentID AND + ( modules.Type != 'exam' OR + submodules.ID = + ( SELECT submodules.ID + FROM `submodules` + INNER JOIN `rating_table` ON rating_table.SubModuleID = submodules.ID + WHERE submodules.ModuleID = modules.ID AND + rating_table.StudentID = pStudentID + ORDER BY submodules.OrderNum DESC + LIMIT 1 + ) + ) + LIMIT 1; + + RETURN vRate; +END // + + +# check, if any module is created +DROP FUNCTION IF EXISTS InternalIsMapCreated// +CREATE FUNCTION `InternalIsMapCreated` + ( `pDisciplineID` INT) RETURNS int(11) + NO SQL +BEGIN + RETURN EXISTS ( + SELECT * FROM `view_disciplines_results` + WHERE view_disciplines_results.DisciplineID = pDisciplineID AND + view_disciplines_results.DisciplineRateMax = 100 + ); +END // + +# ordering helper +DROP FUNCTION IF EXISTS InternalOrderModuleTypesForSession// +CREATE FUNCTION `InternalOrderModuleTypesForSession` + (`pModuleType` INT ) RETURNS INT(3) + NO SQL +BEGIN + DECLARE vRes INT DEFAULT 0; + + CASE pModuleType + WHEN 4 THEN SET vRes = 1; # extra + WHEN 2 THEN SET vRes = 2; # exam + WHEN 3 THEN SET vRes = 3; # bonus + ELSE SET vRes = 4; + END CASE; + + RETURN vRes; +END // + + + + +# ------------------------------------------------------------------------------------------- +# Label: preferences +# Label: magic +# ------------------------------------------------------------------------------------------- + +# set values of record with key \pKey, +# if doesn't exist, then create. +DROP FUNCTION IF EXISTS SetSettings// +CREATE FUNCTION `SetSettings` + (`pKey` VARCHAR(50) CHARSET utf8, `pVal` INT, `pValS` VARCHAR(300) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + INSERT INTO `general_settings` + (Val, ValS, Name) VALUES(pVal, pValS, pKey) + ON DUPLICATE KEY UPDATE + general_settings.Val = pVal, + general_settings.ValS = pValS; + RETURN 0; +END// + + + +DROP FUNCTION IF EXISTS SetBitmaskByPagename// +CREATE FUNCTION `SetBitmaskByPagename` + (`pPagename` TEXT CHARSET utf8, `pMask` INT) RETURNS int(11) + NO SQL +BEGIN + INSERT INTO `page_access` + (Pagename, Bitmask) VALUES(pPagename, pMask) + ON DUPLICATE KEY UPDATE + page_access.Bitmask = pMask; + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS GetBitmaskByPagename// +CREATE FUNCTION `GetBitmaskByPagename` (`pPagename` TEXT CHARSET utf8) RETURNS int(11) + NO SQL +BEGIN + RETURN (SELECT page_access.Bitmask + FROM `page_access` + WHERE page_access.Pagename = pPagename + LIMIT 1); +END // + + + + +# ------------------------------------------------------------------------------------------- +# Label: semesters +# ------------------------------------------------------------------------------------------- + +# set current(for user) semester, life time - db session +DROP FUNCTION IF EXISTS SetSemesterID// +CREATE FUNCTION `SetSemesterID` (`pSemesterID` INT) RETURNS int(11) + NO SQL +BEGIN + SET @CurrentSemesterID := pSemesterID; + RETURN 0; +END // + + + +# ------------------------------------------------------------------------------------------- +# Label: faculties +# ------------------------------------------------------------------------------------------- + +DROP FUNCTION IF EXISTS CreateFaculty // +CREATE FUNCTION CreateFaculty + ( `pFacultyName` VARCHAR(100) CHARSET utf8, + `pFacultyAbbr` VARCHAR(20) CHARSET utf8 + ) RETURNS INT(11) + NO SQL +BEGIN + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + INSERT INTO faculties + (Name, Abbr) + VALUES(pFacultyName, pFacultyAbbr); + RETURN 0; +END // + +# ------------------------------------------------------------------------------------------- +# Label: departments +# ------------------------------------------------------------------------------------------- + +DROP FUNCTION IF EXISTS CreateDepartment // +CREATE FUNCTION CreateDepartment + ( `pName` VARCHAR(200) CHARSET utf8, + `pFacultyID` INT(11) + ) RETURNS INT(11) +NO SQL + BEGIN + DECLARE vChecker INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + SELECT faculties.ID INTO vChecker + FROM `faculties` + WHERE faculties.ID = pFacultyID + LIMIT 1; + + IF vChecker > 0 THEN + INSERT INTO departments + (Name, FacultyID) + VALUES(pName, pFacultyID); + RETURN 0; + END IF; + RETURN -1; + END // + +# ------------------------------------------------------------------------------------------- +# Label: study groups +# ------------------------------------------------------------------------------------------- + +# negative int, if already exists +DROP FUNCTION IF EXISTS CreateGroup// +CREATE FUNCTION `CreateGroup` + ( `pGradeID` INT, `pGroupNum` INT, + `pSpecializationID` INT, `pGroupName` VARCHAR(50) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + # check GradeID, SpecID constraints and (GradeID, GroupNum, SpecID) - unique + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # create discipline + INSERT INTO `study_groups` + (GradeID, GroupNum, SpecializationID, Name) + VALUES (pGradeID, pGroupNum, pSpecializationID, pGroupName); + RETURN 0; +END // + + +# ------------------------------------------------------------------------------------------- +# Label: subjects +# ------------------------------------------------------------------------------------------- + +DROP FUNCTION IF EXISTS CreateSubject// +CREATE FUNCTION `CreateSubject` + ( `pFacultyID` INT, + `pSubjectName` VARCHAR(200) CHARSET utf8, + `pSubjectAbbr` VARCHAR(20) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vSubjectID INT DEFAULT -1; + + # find same subject + SELECT subjects.ID INTO vSubjectID + FROM `subjects` + WHERE subjects.Name = pSubjectName + LIMIT 1; + IF vSubjectID <= 0 THEN + # create new subject + INSERT INTO `subjects` + (Name, Abbr) VALUES(pSubjectName, pSubjectAbbr); + SET vSubjectID = LAST_INSERT_ID(); + END IF; + + BEGIN # handler block + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + # try to attach subject to faculty + INSERT INTO `subjects_faculties` + (SubjectID, FacultyID) + VALUES (vSubjectID, pFacultyID) + ON DUPLICATE KEY UPDATE # just stub + subjects_faculties.FacultyID = subjects_faculties.FacultyID; + END; + RETURN 0; +END // + + +DROP FUNCTION IF EXISTS DeleteSubject // +CREATE FUNCTION DeleteSubject + (`pSubjectID` INT) RETURNS TEXT + NO SQL +BEGIN + DECLARE vChecker INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + SELECT disciplines.ID INTO vChecker + FROM `disciplines` + WHERE disciplines.SubjectID = pSubjectID + LIMIT 1; + IF vChecker > 0 THEN + RETURN -1; # Удаляемый предмет используется РІ disciplines. + END IF; + + DELETE FROM `subjects_faculties` + WHERE subjects_faculties.SubjectID = pSubjectID; + DELETE FROM `subjects` + WHERE subjects.ID = pSubjectID + LIMIT 1; + + RETURN 0; # Успешно удалено; +END // + + +# ------------------------------------------------------------------------------------------- +# Label: accounts +# ------------------------------------------------------------------------------------------- + +# TODO: rename +DROP FUNCTION IF EXISTS GetAccCountByCode// +CREATE FUNCTION `GetAccCountByCode` (`pCode` VARCHAR(40) CHARSET utf8) RETURNS int(11) + NO SQL +BEGIN + RETURN EXISTS(SELECT * FROM `accounts` WHERE accounts.ActivationCode = pCode); +END // + + +DROP FUNCTION IF EXISTS GetAccCountByMail // +CREATE FUNCTION `GetAccCountByMail` (`pEMail` VARCHAR(50) CHARSET utf8) RETURNS int(11) + NO SQL +BEGIN + RETURN EXISTS(SELECT * FROM `accounts` WHERE accounts.EMail = pEMail); +END // + + +DROP FUNCTION IF EXISTS GetAccCountByLogin// +CREATE FUNCTION `GetAccCountByLogin` (`pLogin` VARCHAR(50) CHARSET utf8) RETURNS int(11) + NO SQL +BEGIN + RETURN EXISTS(SELECT * FROM `accounts` WHERE accounts.Login = pLogin); +END // + + + + +DROP FUNCTION IF EXISTS ActivateAccount// +CREATE FUNCTION `ActivateAccount` + ( `pCode` VARCHAR(40) CHARSET utf8, + `pLogin` VARCHAR(50) CHARSET utf8, + `pEMail` VARCHAR(50) CHARSET utf8, + `pPassword` VARCHAR(255) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + # check for matching with existing accounts (note: Login & E-Mail are unique) + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # activate account + UPDATE `accounts` + SET accounts.Login = pLogin, + accounts.Password = pPassword, + accounts.EMail = pEMail, + accounts.ActivationCode = NULL + WHERE accounts.ActivationCode = pCode AND + (@vAccountID := accounts.ID) > 0 # save accountID + LIMIT 1; + + IF (ROW_COUNT() = 0) THEN + RETURN -2; # account with this Code not found + END IF; + RETURN @vAccountID; +END // + + + +DROP FUNCTION IF EXISTS ChangePassword// +CREATE FUNCTION `ChangePassword` + ( `pUserID` INT, `pPassword` VARCHAR(255) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # set new password + UPDATE `accounts` + SET accounts.Password = pPassword + WHERE accounts.ID = pUserID + LIMIT 1; + RETURN ROW_COUNT()-1; # -1 if account doesn't exists, otherwise 0 +END // + + + +DROP FUNCTION IF EXISTS ChangeLogin// +CREATE FUNCTION `ChangeLogin` + ( `pUserID` INT, `pLogin` VARCHAR(50) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + # check set login: login - unique + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # set new login + UPDATE `accounts` + SET accounts.Login = pLogin + WHERE accounts.ID = pUserID + LIMIT 1; + RETURN ROW_COUNT()-1; # -1 if account doesn't exists, otherwise 0 +END // + + + +DROP FUNCTION IF EXISTS ChangeMail// +CREATE FUNCTION `ChangeMail` + (`pUserID` INT, `pEMail` VARCHAR(50) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + # check set login: login - unique + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # set new e-mail + UPDATE `accounts` + SET accounts.EMail = pEMail + WHERE accounts.ID = pUserID + LIMIT 1; + RETURN ROW_COUNT()-1; # -1 if account doesn't exists, otherwise 0 +END // + + + +DROP FUNCTION IF EXISTS SignIn// +CREATE FUNCTION `SignIn` + ( `pLoginOrMail` VARCHAR(255) CHARSET utf8, + `pPassword` VARCHAR(64) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vAccountID INT DEFAULT -1; + + #check account existence + SELECT accounts.ID + INTO vAccountID + FROM `accounts` + WHERE accounts.Password = pPassword AND + (accounts.Login = pLoginOrMail OR accounts.EMail = pLoginOrMail) + LIMIT 1; + IF vAccountID <= 0 THEN + RETURN -1; + END IF; + + # logging + INSERT INTO `logs_signin` + (AccountID) VALUES (vAccountID); + RETURN vAccountID; +END // + + + + +# ------------------------------------------------------------------------------------------- +# Label: teachers +# ------------------------------------------------------------------------------------------- + +DROP FUNCTION IF EXISTS ChangeTeacherInfo// +CREATE FUNCTION `ChangeTeacherInfo` + ( `pTeacherID` INT, + `pLastName` VARCHAR(30) CHARSET utf8, + `pFirstName` VARCHAR(30) CHARSET utf8, + `pSecondName` VARCHAR(30) CHARSET utf8, + `pJobPositionID` INT, + `pDepartmentID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # set new info + UPDATE `teachers` + SET teachers.LastName = pLastName, + teachers.FirstName = pFirstName, + teachers.SecondName = pSecondName, + teachers.JobPositionID = pJobPositionID, + teachers.DepartmentID = pDepartmentID + WHERE teachers.ID = pTeacherID + LIMIT 1; + RETURN ROW_COUNT()-1; # -1 if teacher doesn't exists, otherwise 0 +END // + + + +DROP FUNCTION IF EXISTS CreateTeacher// +CREATE FUNCTION `CreateTeacher` + ( `pLastName` VARCHAR(30) CHARSET utf8, + `pFirstName` VARCHAR(30) CHARSET utf8, + `pSecondName` VARCHAR(30) CHARSET utf8, + `pJobPositionID` INT, + `pDepartmentID` INT, + `pActivationCode` VARCHAR(40) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vAccountID INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + +# user role 2 - common teacher +# add new account + INSERT INTO `accounts` + (Login , Password , EMail, UserRoleID, ActivationCode ) + VALUES ( NULL, NULL, NULL, 2, pActivationCode); + SET vAccountID = LAST_INSERT_ID(); + +# add new teacher + INSERT INTO `teachers` + (AccountID, LastName, FirstName, SecondName, JobPositionID, DepartmentID) + VALUES (vAccountID, pLastName, pFirstName, pSecondName, pJobPositionID, pDepartmentID); + RETURN ROW_COUNT()-1; +END // + + + +DROP FUNCTION IF EXISTS CreateTeacherByDepName// +CREATE FUNCTION `CreateTeacherByDepName` + ( `pLastName` VARCHAR(30) CHARSET utf8, + `pFirstName` VARCHAR(30) CHARSET utf8, + `pSecondName` VARCHAR(30) CHARSET utf8, + `pDepartmentName` VARCHAR(200) CHARSET utf8, + `pFacultyID` INT, + `pActivationCode` VARCHAR(40) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vAccountID, vChecker, vRoleID, vDepID INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + IF pDepartmentName = '' THEN + RETURN -1; + END IF; + + # try to find a department with pDepartmentName + SELECT departments.ID + INTO vDepID + FROM `departments` + WHERE (departments.Name = pDepartmentName AND departments.FacultyID = pFacultyID) + LIMIT 1; + + IF vDepID <= 0 THEN + # pDepartmentName is not empty now + SET vChecker = CreateDepartment(pDepartmentName, pFacultyID); + IF vChecker < 0 THEN + RETURN -1; + END IF; + SET vDepID = LAST_INSERT_ID(); + END IF; + + INSERT INTO `accounts` + (Login , Password , EMail, UserRoleID, ActivationCode ) + VALUES ( NULL, NULL, NULL, 2, pActivationCode); + SET vAccountID = LAST_INSERT_ID(); + + INSERT INTO `teachers` + (AccountID, LastName, FirstName, SecondName, JobPositionID, DepartmentID) + VALUES (vAccountID, pLastName, pFirstName, pSecondName, 12, vDepID); + RETURN 0; +END // + + +-- -1 - РЅРµ сотрудник деканата Рё РЅРµ преподаватель дисциплины +-- 0 - только чтение +-- 1 - редактирование +DROP FUNCTION IF EXISTS GetEditRightsForTeacher// +CREATE FUNCTION `GetEditRightsForTeacher` + ( `pTeacherID` INT, + `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vUserRole, vDiscTeacherID INT DEFAULT -1; + + SELECT disciplines_teachers.ID INTO vDiscTeacherID + FROM `disciplines_teachers` + WHERE disciplines_teachers.DisciplineID = pDisciplineID AND + disciplines_teachers.TeacherID = pTeacherID; + + IF vDiscTeacherID > 0 THEN + RETURN 1; + END IF; + + SELECT accounts.UserRoleID INTO vUserRole + FROM `teachers` + INNER JOIN `accounts` ON teachers.AccountID=accounts.ID + WHERE teachers.ID = pTeacherID; + IF vUserRole = 4 THEN # 4 - сотрудник деканата + RETURN 0; + END IF; + + RETURN -1; +END // + + + +# ------------------------------------------------------------------------------------------- +# Label: students +# ------------------------------------------------------------------------------------------- + +DROP FUNCTION IF EXISTS CreateStudent// +CREATE FUNCTION `CreateStudent` + ( `pLastName` VARCHAR(30) CHARSET utf8, + `pFirstName` VARCHAR(30) CHARSET utf8, + `pSecondName` VARCHAR(30) CHARSET utf8, + `pGradeID` INT, `pGroupNum` INT, `pFacultyID` INT, + `pActivationCode` VARCHAR(40) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vAccountID, vGroupID, vStudentID INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # find group + SELECT view_groups.GroupID INTO vGroupID + FROM `view_groups` + WHERE view_groups.FacultyID = pFacultyID AND + view_groups.GradeID = pGradeID AND + view_groups.GroupNum = pGroupNum + LIMIT 1; + IF vGroupID <= 0 THEN + RETURN -1; + END IF; + + # create new account + INSERT INTO `accounts` + (Login , Password , EMail, UserRoleID, ActivationCode ) + VALUES ( NULL, NULL, NULL, 1, pActivationCode); + SET vAccountID = LAST_INSERT_ID(); + + # create student + INSERT INTO `students` + (AccountID, LastName, FirstName, SecondName) + VALUES (vAccountID, pLastName, pFirstName, pSecondName); + + # bind group in current semester + INSERT INTO `students_groups` + (StudentID, GroupID, SemesterID) + VALUES (LAST_INSERT_ID(), vGroupID, @CurrentSemesterID); + + RETURN 0; +END // + + +# unlike fn CreateStudent, this can create all missing records (group, grade, specialization) +DROP FUNCTION IF EXISTS CreateStudentEx// +CREATE FUNCTION `CreateStudentEx` + ( `pLastName` VARCHAR(30) CHARSET utf8, + `pFirstName` VARCHAR(30) CHARSET utf8, + `pSecondName` VARCHAR(30) CHARSET utf8, + `pGradeNum` INT, + `pGroupNum` INT, + `pDegree` VARCHAR(20) CHARSET utf8, + `pSpecName` VARCHAR(50) CHARSET utf8, + `pFacultyID` INT, + `pActivationCode` VARCHAR(40) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vAccountID, vGradeID, vSpecID, vGroupID INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # try to find grade + SELECT grades.ID INTO vGradeID + FROM `grades` + WHERE grades.Num = pGradeNum AND grades.Degree = pDegree + LIMIT 1; + # such grade doesn't exist + IF vGradeID <= 0 THEN + # insert new grade with pGradeNum and pDegree + INSERT INTO `grades` + (Num, Degree) VALUES (pGradeNum, pDegree); + SET vGradeID = LAST_INSERT_ID(); + END IF; + + # try to find group + SELECT view_groups.GroupID INTO vGroupID + FROM `view_groups` + WHERE view_groups.FacultyID = pFacultyID AND + view_groups.GroupNum = pGroupNum AND + view_groups.GradeID = vGradeID + LIMIT 1; + + # group not found + IF vGroupID <= 0 THEN + # try to find specialization + SELECT specializations.ID INTO vSpecID + FROM `specializations` + WHERE (specializations.Name = pSpecName OR + (pSpecName = '' AND specializations.Name IS NULL)) AND + specializations.FacultyID = pFacultyID + LIMIT 1; + + # specialization not found + IF vSpecID <= 0 THEN + # create new specialization + INSERT INTO `specializations` + (Name, Abbr, FacultyID) + VALUES (pSpecName, NULL, pFacultyID); + SET vSpecID = LAST_INSERT_ID(); + END IF; + + # create new group + INSERT INTO `study_groups` + (GradeID, GroupNum, SpecializationID) + VALUES (vGradeID, pGroupNum, vSpecID); + SET vGroupID = LAST_INSERT_ID(); + END IF; + + # TODO: user roles + # create account + INSERT INTO `accounts` + (Login, Password , EMail, UserRoleID, ActivationCode ) + VALUES ( NULL, NULL, NULL, 1, pActivationCode); + SET vAccountID = LAST_INSERT_ID(); + + # create student + INSERT INTO `students` + (AccountID, LastName, FirstName, SecondName) + VALUES (vAccountID, pLastName, pFirstName, pSecondName); + + # bind group in current semester + INSERT INTO `students_groups` + (StudentID, GroupID, SemesterID) + VALUES (LAST_INSERT_ID(), vGroupID, @CurrentSemesterID); + + RETURN ROW_COUNT()-1; +END // + + + +# Give a student an academic leave or attach him to group. +# params: +# StudentID (int) +# GroupID (int) : is used, if OnLeave == false +# OnLeave (bool) : true - into study leave, false - attach to group +DROP FUNCTION IF EXISTS ControlStudentGroup// +CREATE FUNCTION `ControlStudentGroup` ( + `pStudentID` INT, + `pGroupID` INT, + `pState` BOOLEAN + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vChecker INT DEFAULT 0; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # out to study leave + IF pState THEN + UPDATE `students_groups` + SET students_groups.IsStudyLeave = TRUE, + students_groups.Date = CURDATE() + WHERE students_groups.StudentID = pStudentID AND + students_groups.SemesterID = @CurrentSemesterID + LIMIT 1; + # attach to new group + ELSE + INSERT INTO `students_groups` + (StudentID, GroupID, SemesterID) + VALUES(pStudentID, pGroupID, @CurrentSemesterID); + END IF; + RETURN ROW_COUNT()-1; +END // + + +# ------------------------------------------------------------------------------------------- +# Label: disciplines +# ------------------------------------------------------------------------------------------- + + + +DROP FUNCTION IF EXISTS AddDiscipline// +CREATE FUNCTION `AddDiscipline` + ( `pTeacherID` INT, `pGradeID` INT, `pSubjectID` INT, + `pExamType` VARCHAR(30) CHARSET utf8, + `pLectureCount` INT, `pPracticeCount` INT, `pLabCount` INT, + `pFacultyID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vChecker, vDisciplineID INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # create discipline + INSERT INTO `disciplines` + (AuthorID, GradeID, SubjectID, ExamType, LectureCount, PracticeCount,LabCount, SemesterID,FacultyID) + VALUES ( pTeacherID, pGradeID, pSubjectID, pExamType, pLectureCount, pPracticeCount, pLabCount, + @CurrentSemesterID, pFacultyID); + SET vDisciplineID = LAST_INSERT_ID(); + + # bind teacher(author) + INSERT INTO `disciplines_teachers` + (DisciplineID,TeacherID) + VALUES (vDisciplineID, pTeacherID); + + # add exam and extra modules + IF pExamType = 'exam' THEN + SET vChecker = AddModuleExam(pTeacherID, vDisciplineID); + END IF; + SET vChecker = AddModuleExtra(pTeacherID, vDisciplineID); + RETURN vDisciplineID; +END // + + + +DROP FUNCTION IF EXISTS ChangeDisciplineSubject// +CREATE FUNCTION `ChangeDisciplineSubject` + (`pTeacherID` INT, `pDisciplineID` INT, `pSubjectID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) OR + InternalIsMapLocked(pDisciplineID) + THEN + RETURN -1; + END IF; + + UPDATE `disciplines` + SET disciplines.SubjectID = pSubjectID + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + RETURN ROW_COUNT()-1; +END // + + + +DROP FUNCTION IF EXISTS ChangeDisciplineGrade// +CREATE FUNCTION `ChangeDisciplineGrade` + (`pTeacherID` INT, `pDisciplineID` INT, `pGradeID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vCurGradeID INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + IF InternalIsMapLocked(pDisciplineID) OR + NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) + THEN + RETURN -1; + END IF; + + # get current grade + SELECT disciplines.GradeID INTO vCurGradeID + FROM `disciplines` + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + IF vCurGradeID = pGradeID THEN + RETURN 0; + END IF; + + # delete all students + DELETE FROM `disciplines_groups` + WHERE disciplines_groups.DisciplineID = pDisciplineID; + DELETE FROM `disciplines_students` + WHERE disciplines_students.DisciplineID = pDisciplineID; + + # set grade + UPDATE `disciplines` + SET disciplines.GradeID = pGradeID + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + RETURN ROW_COUNT()-1; +END // + + +DROP FUNCTION IF EXISTS ChangeDisciplineControl// +CREATE FUNCTION `ChangeDisciplineControl` + ( `pTeacherID` INT, `pDisciplineID` INT, + `pExamType` VARCHAR(30) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vOldExamType, vChecker, vExtraMax, vExtraID INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + IF InternalIsMapLocked(pDisciplineID) OR + NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) + THEN + RETURN -1; + END IF; + + # get exam type and extra module ID + SELECT disciplines.ExamType, modules.ID INTO vOldExamType, vExtraID + FROM `disciplines` + INNER JOIN `modules` ON modules.Type = 'extra' AND + modules.DisciplineID = pDisciplineID + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + IF vExtraID <= 0 THEN + RETURN -1; + END IF; + # check that exam type really changed + IF (vOldExamType = pExamType) THEN + RETURN 0; + END IF; + + + IF pExamType = 'exam' THEN # change to exam + SET vExtraMax = 7; + # count discipline's current max rate + SELECT view_disciplines_results.DisciplineRateMax INTO vChecker + FROM `view_disciplines_results` + WHERE view_disciplines_results.DisciplineID = pDisciplineID + LIMIT 1; + # can't add exam module + IF vChecker >= 61 THEN + RETURN 1; + END IF; + SET vChecker = AddModuleExam(pTeacherID, pDisciplineID); + + # delete extra submodules(only 1 extra for exam) + DELETE FROM `submodules` + WHERE submodules.OrderNum > 1 AND submodules.ModuleID = vExtraID; + ELSE # change to credit + SET vExtraMax = 29; + SET vChecker = DeleteModuleExam(pTeacherID, pDisciplineID); + # 2 extra submodules (1 created for exam) + SET vChecker = AddSubmodule(pTeacherID, vExtraID, vExtraMax, '', NULL, 'LandmarkControl'); + END IF; + + # set new exam type + UPDATE `disciplines` + SET disciplines.ExamType = pExamType + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + # set max rate for extra + UPDATE `submodules` + SET submodules.MaxRate = vExtraMax + WHERE submodules.ModuleID = vExtraID; + RETURN 0; +END // + +DROP FUNCTION IF EXISTS ChangeDisciplineHours// +CREATE FUNCTION `ChangeDisciplineHours` + ( `pTeacherID` INT, `pDisciplineID` INT, + `pHours` INT, `pType` INT + # Type: 0 - Practice Hours, 1 - Lecture Hours, 2 - Lab Hours + ) RETURNS int(11) + NO SQL +BEGIN + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) THEN + RETURN -1; + END IF; + + CASE pType + WHEN 0 THEN + UPDATE `disciplines` + SET disciplines.PracticeCount = pHours + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + WHEN 1 THEN + UPDATE `disciplines` + SET disciplines.LectureCount = pHours + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + WHEN 2 THEN + UPDATE `disciplines` + SET disciplines.LabCount = pHours + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + END CASE; + RETURN ROW_COUNT()-1; +END // + + + +DROP FUNCTION IF EXISTS BindGroup// +CREATE FUNCTION `BindGroup` + (`pTeacherID` INT, `pDisciplineID` INT, `pGroupID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vChecker, vSemesterID INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -3; + + # 1. check if AccessedTeacher is author + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) OR + InternalIsMapLocked(pDisciplineID) + THEN + RETURN -1; + END IF; + + # 2. check if group is bound to discipline + SELECT disciplines_groups.ID INTO vChecker + FROM `disciplines_groups` + WHERE disciplines_groups.GroupID = pGroupID AND + disciplines_groups.DisciplineID = pDisciplineID + LIMIT 1; + IF vChecker > 0 THEN + RETURN 1; + END IF; + + SELECT disciplines.SemesterID INTO vSemesterID + FROM `disciplines` + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + + # 3. delete students of this group which were bound to discipline before + DELETE FROM `disciplines_students` + WHERE disciplines_students.DisciplineID = pDisciplineID AND + disciplines_students.StudentID IN + (SELECT students_groups.StudentID + FROM `students_groups` + WHERE students_groups.GroupID = pGroupID AND + students_groups.SemesterID = vSemesterID + ); + + # 4. bind whole group + INSERT INTO `disciplines_groups` + (DisciplineID, GroupID) + VALUES (pDisciplineID, pGroupID ); + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS BindStudent// +CREATE FUNCTION `BindStudent` + ( `pTeacherID` INT, `pDisciplineID` INT, `pStudentID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vInGroup, vChecker, vGroupID, vTemp INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # 1. check if AccessedTeacher is author + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) THEN + RETURN -1; + END IF; + + # 2. check if student's group is bound yet + SELECT disciplines_groups.ID INTO vInGroup + FROM `students_groups` + INNER JOIN `disciplines_groups` ON disciplines_groups.DisciplineID = pDisciplineID AND + disciplines_groups.GroupID = students_groups.GroupID + WHERE students_groups.StudentID = pStudentID AND + students_groups.SemesterID = @CurrentSemesterID + + LIMIT 1; + + # try to remove detached attribute + IF vInGroup > 0 THEN + DELETE FROM `disciplines_students` + WHERE disciplines_students.DisciplineID = pDisciplineID AND + disciplines_students.StudentID = pStudentID + LIMIT 1; + RETURN 0; + END IF; + + + # 3. try bind student + INSERT INTO `disciplines_students` + (DisciplineID, StudentID, Type) + VALUES (pDisciplineID, pStudentID, 'attach') + # update stub/ already bounded + ON DUPLICATE KEY UPDATE + disciplines_students.StudentID = disciplines_students.StudentID; + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS UnbindGroup// +CREATE FUNCTION `UnbindGroup` + ( `pTeacherID` INT, `pDisciplineID` INT, `pGroupID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vSemesterID INT DEFAULT -1; + + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) OR InternalIsMapLocked(pDisciplineID)THEN + RETURN -1; + END IF; + + # detach group from the discipline + DELETE FROM `disciplines_groups` + WHERE disciplines_groups.DisciplineID = pDisciplineID AND + disciplines_groups.GroupID = pGroupID + LIMIT 1; + + + SELECT disciplines.SemesterID INTO vSemesterID + FROM `disciplines` + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + + # delete attached, and detached (doesn't take disc in any case) + DELETE FROM `disciplines_students` + WHERE disciplines_students.DisciplineID = pDisciplineID AND + disciplines_students.StudentID IN + (SELECT students_groups.StudentID + FROM `students_groups` + WHERE students_groups.GroupID = pGroupID AND + students_groups.SemesterID = vSemesterID); + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS UnbindStudent// +CREATE FUNCTION `UnbindStudent` + (`pTeacherID` INT, `pDisciplineID` INT, `pStudentID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vInGroup INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) THEN + RETURN -1; + END IF; + + # try to get general group, if student in it. + SELECT disciplines_groups.ID INTO vInGroup + FROM `students` + INNER JOIN `students_groups` ON students_groups.StudentID = students.ID AND + students_groups.SemesterID = @CurrentSemesterID + INNER JOIN `disciplines_groups` ON disciplines_groups.DisciplineID = pDisciplineID AND + disciplines_groups.GroupID = students_groups.GroupID + WHERE students.ID = pStudentID + LIMIT 1; + + IF vInGroup > 0 THEN # student in general group + INSERT INTO `disciplines_students` + (DisciplineID, StudentID, Type) + VALUES (pDisciplineID, pStudentID, 'detach'); + ELSE + DELETE FROM `disciplines_students` + WHERE disciplines_students.DisciplineID = pDisciplineID AND + disciplines_students.StudentID = pStudentID + LIMIT 1; + END IF; + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS BindTeacher// +CREATE FUNCTION `BindTeacher` + (`pTeacherID` INT, `pBindingTeacherID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) THEN + RETURN -1; + END IF; + + # try to insert BindingTeacher in access list + INSERT INTO `disciplines_teachers` + (DisciplineID, TeacherID) + VALUES (pDisciplineID, pBindingTeacherID) + ON DUPLICATE KEY UPDATE # just stub + disciplines_teachers.TeacherID = disciplines_teachers.TeacherID; + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS UnbindTeacher// +CREATE FUNCTION `UnbindTeacher` + ( `pAuthorID` INT, `pBindingTeacher` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + IF pAuthorID = pBindingTeacher OR + NOT InternalIsTeacherAuthor(pAuthorID, pDisciplineID) + THEN + RETURN -1; + END IF; + + DELETE FROM `disciplines_teachers` + WHERE disciplines_teachers.DisciplineID = pDisciplineID AND + disciplines_teachers.TeacherID = pBindingTeacher; + RETURN ROW_COUNT()-1; +END // + + +# assign new author to discipline +DROP FUNCTION IF EXISTS DelegateDiscipline// +CREATE FUNCTION `DelegateDiscipline` + ( `pAuthorID` INT, `pNewAuthorID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + IF pAuthorID = pNewAuthorID OR + NOT InternalIsTeacherAuthor(pAuthorID, pDisciplineID) OR + NOT InternalIsTeacherBounded(pNewAuthorID, pDisciplineID) + THEN + RETURN -1; + END IF; + + UPDATE `disciplines` + SET disciplines.AuthorID = pNewAuthorID + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + RETURN ROW_COUNT()-1; +END // + + +# erase all discipline's rates(and logs), unlock discipline for editing +DROP FUNCTION IF EXISTS ClearDiscipline// +CREATE FUNCTION `ClearDiscipline` + ( `pAuthorID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + IF NOT InternalIsTeacherAuthor(pAuthorID, pDisciplineID) THEN + RETURN -1; + END IF; + + # clear logs + DELETE FROM `logs_rating` + WHERE logs_rating.SubModuleID IN + (SELECT view_roadmap.SubmoduleID + FROM `view_roadmap` + WHERE view_roadmap.DisciplineID = pDisciplineID); + + # clear rating + DELETE FROM `rating_table` + WHERE rating_table.SubModuleID IN + (SELECT view_roadmap.SubmoduleID + FROM `view_roadmap` + WHERE view_roadmap.DisciplineID = pDisciplineID); + + # unlock discipline + UPDATE `disciplines` + SET disciplines.IsLocked = 0 + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + + RETURN ROW_COUNT()-1; +END // + + + +DROP FUNCTION IF EXISTS DeleteDiscipline// +CREATE FUNCTION `DeleteDiscipline` + ( `pAuthorID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vTemp INT DEFAULT -1; + IF NOT InternalIsTeacherAuthor(pAuthorID, pDisciplineID) THEN + RETURN -1; + END IF; + + SELECT disciplines.IsLocked INTO vTemp + FROM `disciplines` + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + IF vTemp != 0 THEN + RETURN -1; + END IF; + + # delete only if discipline cleared(doesn't exists related rating's records) + SET vTemp = CountRatings(pAuthorID, pDisciplineID); + IF vTemp > 0 THEN + RETURN -1; + END IF; + + # delete roadmap + DELETE FROM `submodules` + WHERE submodules.ModuleID IN + (SELECT modules.ID + FROM `modules` + WHERE modules.DisciplineID = pDisciplineID + ); + DELETE FROM `modules` + WHERE modules.DisciplineID = pDisciplineID; + + # detach all entities from discipline + DELETE FROM `disciplines_teachers` + WHERE disciplines_teachers.DisciplineID = pDisciplineID; + DELETE FROM `disciplines_students` + WHERE disciplines_students.DisciplineID = pDisciplineID; + DELETE FROM `disciplines_groups` + WHERE disciplines_groups.DisciplineID = pDisciplineID; + + # delete discipline + DELETE FROM `disciplines` + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + + RETURN 0; +END // + + +# get count of related with discipline records in rating_table +DROP FUNCTION IF EXISTS CountRatings// +CREATE FUNCTION `CountRatings` + ( `pTeacherID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vRes INT DEFAULT 0; + + IF NOT InternalIsTeacherBounded(pTeacherID, pDisciplineID) THEN + RETURN -1; + END IF; + + SELECT COUNT(rating_table.StudentID) + INTO vRes + FROM `rating_table` + INNER JOIN `submodules` ON rating_table.SubModuleID = submodules.ID + INNER JOIN `modules` ON submodules.ModuleID = modules.ID + WHERE modules.DisciplineID = pDisciplineID + LIMIT 1; + + RETURN vRes; +END // + + + +DROP FUNCTION IF EXISTS RestrictAfterMilestone// +CREATE FUNCTION `RestrictAfterMilestone` + ( `pTeacherID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + UPDATE `disciplines` + SET disciplines.MilestoneDate = CURDATE(), + disciplines.isMilestone = 1 + WHERE disciplines.ID = pDisciplineID + LIMIT 1; + RETURN 0; +END // + + +DROP FUNCTION IF EXISTS RestrictAfterMilestoneForCredits// +CREATE FUNCTION `RestrictAfterMilestoneForCredits` ( `pTeacherID` INT, + `pFacultyID` INT + ) RETURNS int(11) + NO SQL +BEGIN + UPDATE `disciplines` + SET disciplines.MilestoneDate = CURDATE(), + disciplines.isMilestone = 1 + WHERE disciplines.SemesterID = @CurrentSemesterID AND + disciplines.ExamType = 'credit' AND + disciplines.FacultyID= pFacultyID; + RETURN 0; +END // + +# ------------------------------------------------------------------------------------------- +# Label: modules +# Label: roadmap +# ------------------------------------------------------------------------------------------- + + + +DROP FUNCTION IF EXISTS ChangeModuleName// +CREATE FUNCTION `ChangeModuleName` + ( `pTeacherID` INT, `pModuleID` INT, + `pName` VARCHAR(200) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + UPDATE `modules` + SET modules.Name = pName + WHERE modules.ID = pModuleID AND + modules.Type = 'regular' AND + NOT InternalIsMapLocked(modules.DisciplineID) + LIMIT 1; + RETURN ROW_COUNT()-1; +END // + + + +DROP FUNCTION IF EXISTS AddModule// +CREATE FUNCTION `AddModule` + ( `pTeacherID` INT, `pDisciplineID` INT, + `pName` VARCHAR(200) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vOrderNum INT DEFAULT 0; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) OR + InternalIsMapLocked(pDisciplineID) + THEN + RETURN -2; + END IF; + + # get free orderNum + SELECT MAX(modules.OrderNum)+1 INTO vOrderNum + FROM `modules` + WHERE modules.DisciplineID = pDisciplineID AND modules.Type = 'regular' + LIMIT 1; + IF vOrderNum IS NULL THEN + SET vOrderNum = 1; + END IF; + + INSERT INTO `modules` + (Name, OrderNum, DisciplineID ) + VALUES (pName, vOrderNum, pDisciplineID); + RETURN LAST_INSERT_ID(); +END // + + + +DROP FUNCTION IF EXISTS AddModuleExam// +CREATE FUNCTION `AddModuleExam` + (`pTeacherID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vChecker, vModule INT DEFAULT -1; + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) OR + InternalIsMapLocked(pDisciplineID) + THEN + RETURN -1; + END IF; + + # check exam module existence + SELECT modules.ID + INTO vChecker + FROM `modules` + WHERE modules.DisciplineID = pDisciplineID AND + modules.Type = 'exam'; + IF vChecker > 0 THEN + RETURN -2; + END IF; + + INSERT INTO `modules` + (Name, OrderNum, DisciplineID, Type) + VALUES ('Ркзамен' , 3141592 , pDisciplineID, 'exam'); + + SET vModule = LAST_INSERT_ID(); + # 3 attempt for pass exam + SET vChecker = AddSubmodule(pTeacherID, vModule, 40, '', NULL, 'LandmarkControl'); + SET vChecker = AddSubmodule(pTeacherID, vModule, 40, '', NULL, 'LandmarkControl'); + SET vChecker = AddSubmodule(pTeacherID, vModule, 40, '', NULL, 'LandmarkControl'); + RETURN vModule; +END // + + +DROP FUNCTION IF EXISTS AddModuleExtra// +CREATE FUNCTION `AddModuleExtra` + ( `pTeacherID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vChecker, vModule, vType, vGap INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) + THEN + RETURN -1; + END IF; + + # try to find existing extra module + SELECT modules.ID INTO vChecker + FROM `modules` + WHERE modules.DisciplineID = pDisciplineID AND modules.Type = 'extra' + LIMIT 1; + IF vChecker > 0 THEN + RETURN -2; + END IF; + + # add extra module + INSERT INTO `modules` + (Name, OrderNum, DisciplineID, Type) + VALUES ('Добор баллов' , 2900666 , pDisciplineID, 'extra'); + + + # get discipline exam type + SELECT modules.ID, disciplines.ExamType + INTO vModule, vType + FROM `modules` + INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + WHERE modules.DisciplineID = pDisciplineID AND + modules.Type = 'extra' + LIMIT 1; + IF vModule <= 0 THEN + RETURN -1; + END IF; + + # 1 extra attempt for exam and 2 for credit + SET vGap = -1; + IF vType = 1 THEN # exam + SET vGap = 7; + END IF; + IF vType = 2 THEN # credit + SET vGap = 29; + SET vChecker = AddSubmodule(pTeacherID, vModule, vGap, '', NULL, 'LandmarkControl'); + END IF; + + SET vChecker = AddSubmodule(pTeacherID, vModule, vGap, '', NULL, 'LandmarkControl'); + RETURN vModule; +END // + + +DROP FUNCTION IF EXISTS DeleteModule// +CREATE FUNCTION `DeleteModule` + ( `pTeacherID` INT, `pModuleID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vDisciplineID INT DEFAULT -1; + + # get discipline ID + SELECT disciplines.ID INTO vDisciplineID + FROM `modules` + INNER JOIN `disciplines` ON modules.DisciplineID = disciplines.ID AND + disciplines.AuthorID = pTeacherID + WHERE modules.ID = pModuleID + LIMIT 1; + + # check rights + IF NOT InternalIsTeacherAuthor(pTeacherID, vDisciplineID) OR + InternalIsMapLocked(vDisciplineID) + THEN + RETURN -1; + END IF; + + DELETE FROM `submodules` + WHERE submodules.ModuleID = pModuleID; + DELETE FROM `modules` + WHERE modules.ID = pModuleID; + + # restore continuous ordering + SET @counter = 0; + UPDATE `modules` + SET modules.OrderNum = (@counter := @counter + 1) + WHERE modules.DisciplineID = vDisciplineID AND + modules.Type = 'regular' + ORDER BY modules.OrderNum ASC; + + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS DeleteModuleExam// +CREATE FUNCTION `DeleteModuleExam` + ( `pTeacherID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vExamModuleID INT DEFAULT -1; + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) OR + InternalIsMapLocked(pDisciplineID) + THEN + RETURN -1; + END IF; + + # get exam module ID + SELECT modules.ID INTO vExamModuleID + FROM `modules` + WHERE modules.Type = 'exam' AND + modules.DisciplineID = pDisciplineID + LIMIT 1; + IF vExamModuleID <= 0 THEN + RETURN -1; + END IF; + + DELETE FROM `submodules` + WHERE vExamModuleID = submodules.ModuleID; + DELETE FROM `modules` + WHERE vExamModuleID = modules.ID + LIMIT 1; + + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS SwapModuleOrder// +CREATE FUNCTION `SwapModuleOrder` + ( `pTeacherID` INT, `pModuleID1` INT, `pModuleID2` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vChecker, vOrder1, vOrder2, + vDisciplineID1, vDisciplineID2 INT DEFAULT -1; + + # get disciplineID and orderNum for 1st module(pModuleID1) + SELECT modules.OrderNum, + modules.DisciplineID + INTO vOrder1, vDisciplineID1 + FROM `modules` + INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + WHERE disciplines.AuthorID = pTeacherID AND + modules.ID = pModuleID1 AND + modules.Type = 'regular' + LIMIT 1; + + # get disciplineID and orderNum for 2st module(pModuleID2) + SELECT modules.OrderNum, + modules.DisciplineID + INTO vOrder2, vDisciplineID2 + FROM `modules` + INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + WHERE disciplines.AuthorID = pTeacherID AND + modules.ID = pModuleID2 AND + modules.Type = 'regular' + LIMIT 1; + + # check that modules belong to one discipline, check rights + IF vDisciplineID1 != vDisciplineID2 OR vDisciplineID1 <= 0 OR + InternalIsMapLocked(vDisciplineID1) THEN + RETURN -1; + END IF; + + # swap + UPDATE `modules` + SET modules.OrderNum = 271828 + WHERE modules.ID = pModuleID1; + UPDATE `modules` + SET modules.OrderNum = vOrder1 + WHERE modules.ID = pModuleID2 + LIMIT 1; + UPDATE `modules` + SET modules.OrderNum = vOrder2 + WHERE modules.ID = pModuleID1 + LIMIT 1; + + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS AddModuleBonus// +CREATE FUNCTION `AddModuleBonus` + ( `pTeacherID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vChecker, vModuleID INT DEFAULT -1; + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) OR + InternalIsMapLocked(pDisciplineID) + THEN + RETURN -1; + END IF; + + # check existing of bonus module + SELECT modules.ID INTO vChecker + FROM `modules` + WHERE modules.DisciplineID = pDisciplineID AND + modules.Type = 'bonus'; + IF vChecker > 0 THEN + RETURN -2; + END IF; + + INSERT INTO `modules` + (Name, OrderNum, DisciplineID, Type) + VALUES ('Бонусные баллы' , 2141692 , pDisciplineID, 'bonus'); + + SET vModuleID = LAST_INSERT_ID(); + SET vChecker = AddSubmodule(pTeacherID, vModuleID, 10, '', NULL, 'LandmarkControl'); + RETURN 0; +END // + + +DROP FUNCTION IF EXISTS DeleteModuleBonus// +CREATE FUNCTION `DeleteModuleBonus` + ( `pTeacherID` INT, `pDisciplineID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vBonusModuleID INT DEFAULT -1; + IF NOT InternalIsTeacherAuthor(pTeacherID, pDisciplineID) OR + InternalIsMapLocked(pDisciplineID) + THEN + RETURN -1; + END IF; + + # get bonus module ID + SELECT modules.ID INTO vBonusModuleID + FROM `modules` + WHERE modules.Type = 'bonus' AND + modules.DisciplineID = pDisciplineID + LIMIT 1; + IF vBonusModuleID <= 0 THEN + RETURN -1; + END IF; + + DELETE FROM `submodules` + WHERE vBonusModuleID = submodules.ModuleID; + + DELETE FROM `modules` + WHERE vBonusModuleID = modules.ID + LIMIT 1; + + RETURN 0; +END // + + + +# ------------------------------------------------------------------------------------------- +# Label: submodules +# Label: roadmap +# ------------------------------------------------------------------------------------------- + +DROP FUNCTION IF EXISTS ChangeSubmoduleMaxAndControl// +CREATE FUNCTION `ChangeSubmoduleMaxAndControl` + ( `pTeacherID` INT, + `pSubmoduleID` INT, + `pMaxRate` INT, + `pControlType` VARCHAR(30) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vChecker, vDisciplineID, vIsLocked, vNewDiscMaxRate, vCurRate INT DEFAULT -1; + + # check that discipline and submodule exists and doesn't locked + SELECT disciplines.IsLocked, + view_disciplines_results.DisciplineRateMax - submodules.MaxRate + pMaxRate + INTO vIsLocked, vNewDiscMaxRate + FROM `submodules` + INNER JOIN `modules` ON submodules.ModuleID = modules.ID + INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + INNER JOIN `view_disciplines_results` ON view_disciplines_results.DisciplineID = disciplines.ID + WHERE submodules.ID = pSubmoduleID AND + disciplines.AuthorID = pTeacherID + LIMIT 1; + IF vIsLocked != 0 OR + vNewDiscMaxRate > 100 + THEN + RETURN -1; + END IF; + + UPDATE `submodules` + SET submodules.MaxRate = pMaxRate, + submodules.Type = pControlType + WHERE submodules.ID = pSubmoduleID + LIMIT 1; + RETURN ROW_COUNT()-1; +END // + + + +DROP FUNCTION IF EXISTS ChangeSubmoduleName// +CREATE FUNCTION `ChangeSubmoduleName` + ( `pTeacherID` INT, + `pSubmoduleID` INT, + `pName` VARCHAR(200) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vIsLocked INT DEFAULT -1; + + SELECT disciplines.IsLocked INTO vIsLocked + FROM `submodules` + INNER JOIN `modules` ON submodules.ModuleID = modules.ID + INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + WHERE disciplines.AuthorID = pTeacherID AND + submodules.ID = pSubmoduleID + LIMIT 1; + IF vIsLocked != 0 THEN + RETURN -1; + END IF; + + UPDATE `submodules` + SET submodules.Name = pName + WHERE submodules.ID = pSubmoduleID + LIMIT 1; + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS ChangeSubmoduleDescription// +CREATE FUNCTION `ChangeSubmoduleDescription` + ( `pTeacherID` INT, + `pSubmoduleID` INT, + `pDescription` VARCHAR(200) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vIsLocked INT DEFAULT -1; + + SELECT disciplines.IsLocked INTO vIsLocked + FROM `submodules` + INNER JOIN `modules` ON submodules.ModuleID = modules.ID + INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + WHERE disciplines.AuthorID = pTeacherID AND + submodules.ID = pSubmoduleID + LIMIT 1; + IF vIsLocked != 0 THEN + RETURN -1; + END IF; + + UPDATE `submodules` + SET submodules.Description = pDescription + WHERE submodules.ID = pSubmoduleID + LIMIT 1; + RETURN 0; +END // + + + + +DROP FUNCTION IF EXISTS DeleteSubmodule// +CREATE FUNCTION `DeleteSubmodule` + ( `pTeacherID` INT, `pSubmoduleID` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vIsLocked, vModuleID INT DEFAULT -1; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + SELECT modules.ID, disciplines.IsLocked + INTO vModuleID, vIsLocked + FROM `submodules` + INNER JOIN `modules` ON modules.ID = submodules.ModuleID + INNER JOIN `disciplines` ON modules.DisciplineID = disciplines.ID + WHERE disciplines.AuthorID = pTeacherID AND + submodules.ID = pSubmoduleID + LIMIT 1; + IF vIsLocked != 0 THEN + RETURN -1; + END IF; + + # handler will catch constraint violation + DELETE FROM `submodules` + WHERE submodules.ID = pSubmoduleID + LIMIT 1; + + # restore continuous ordering + SET @counter = 0; + UPDATE `submodules` + SET submodules.OrderNum = (@counter := @counter + 1) + WHERE submodules.ModuleID = vModuleID + ORDER BY submodules.OrderNum ASC; + + RETURN 0; +END // + + + +DROP FUNCTION IF EXISTS AddSubmodule// +CREATE FUNCTION `AddSubmodule` + ( `pTeacherID` INT, `pModuleID` INT, `pMaxRate` INT, + `pName` VARCHAR(200) CHARSET utf8, + `pDescription` VARCHAR(200) CHARSET utf8, + `pControlType` VARCHAR(30) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vOrderNum, vIsLocked INT DEFAULT -1; + DECLARE vDescription VARCHAR(200) CHARSET utf8 DEFAULT pDescription; + # DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # check author and discipline lock + SELECT disciplines.IsLocked INTO vIsLocked + FROM `modules` + INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + WHERE disciplines.AuthorID = pTeacherID AND + modules.ID = pModuleID + LIMIT 1; + IF vIsLocked != 0 THEN + RETURN -2; + END IF; + + # get free order + SET vOrderNum = 0; + SELECT MAX(submodules.OrderNum) INTO vOrderNum + FROM `submodules` + WHERE submodules.ModuleID = pModuleID + LIMIT 1; + IF vOrderNum IS NULL THEN + SET vOrderNum = 0; + END IF; + SET vOrderNum = vOrderNum + 1; + + # insert submodule + + IF vDescription = '' THEN + SET vDescription = NULL; + END IF; + INSERT INTO `submodules` + (ModuleID, MaxRate, OrderNum, Name, Description, Type) + VALUES (pModuleID, pMaxRate, vOrderNum, pName, vDescription, pControlType); + + RETURN LAST_INSERT_ID(); +END // + + + +DROP FUNCTION IF EXISTS SwapSubmoduleOrder// +CREATE FUNCTION `SwapSubmoduleOrder` +( `pTeacherID` INT, `pSubmoduleID1` INT, `pSubmoduleID2` INT ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vDisciplineID, vOrder1, vOrder2, + vModule1, vModule2 INT DEFAULT -1; + + SELECT submodules.OrderNum, + submodules.ModuleID, + disciplines.ID + INTO vOrder1, vModule1, vDisciplineID + FROM `submodules` + INNER JOIN `modules` ON submodules.ModuleID = modules.ID + INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + WHERE disciplines.AuthorID = pTeacherID AND + submodules.ID = pSubmoduleID1 + LIMIT 1; + + SELECT submodules.OrderNum, + submodules.ModuleID + INTO vOrder2, vModule2 + FROM `submodules` + INNER JOIN `modules` ON submodules.ModuleID = modules.ID + INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + WHERE disciplines.AuthorID = pTeacherID AND + submodules.ID = pSubmoduleID2 + LIMIT 1; + + # check, that modules exists and belong to one discipline + IF vModule1 <= 0 OR vModule1 != vModule2 OR + InternalIsMapLocked(vDisciplineID) + THEN + RETURN -1; + END IF; + + # swap + UPDATE `submodules` + SET submodules.OrderNum = 271828 + WHERE submodules.ID = pSubmoduleID1 + LIMIT 1; + UPDATE `submodules` + SET submodules.OrderNum = vOrder1 + WHERE submodules.ID = pSubmoduleID2 + LIMIT 1; + UPDATE `submodules` + SET submodules.OrderNum = vOrder2 + WHERE submodules.ID = pSubmoduleID1 + LIMIT 1; + RETURN 0; +END // + + +# ------------------------------------------------------------------------------------------- +# Label: rating +# ------------------------------------------------------------------------------------------- + +# TODO: kill +DROP FUNCTION IF EXISTS GetMaxRateForDisc// +CREATE FUNCTION `GetMaxRateForDisc` +( `pDisciplineID` INT ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vResult INT DEFAULT 0; + + SELECT SUM(submodules.MaxRate) + INTO vResult + FROM `modules` + LEFT JOIN `submodules` ON submodules.ModuleID = modules.ID + WHERE modules.DisciplineID = pDisciplineID AND + submodules.IsUsed != 0 AND + (modules.Type = 1 OR ( modules.Type = 2 AND submodules.OrderNum = 1)) + LIMIT 1; + RETURN (vResult); +END // + + +# Вычисление максимального балла для submodule +DROP FUNCTION IF EXISTS CalculateMaxRateForExtra// +CREATE FUNCTION `CalculateMaxRateForExtra` +( `pSubmoduleID` INT, `pStudentID` INT) RETURNS int(11) + NO SQL +BEGIN + DECLARE vExamType INT DEFAULT -1; # enum('exam', 'credit');# utf8; + DECLARE vLim INT; + DECLARE vResult INT DEFAULT 0; + + SELECT disciplines.ExamType INTO vExamType + FROM `submodules` + INNER JOIN `modules` ON modules.ID = submodules.ModuleID + INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + WHERE submodules.ID = pSubmoduleID + LIMIT 1; + + IF vExamType = -1 THEN + RETURN -1; + ELSEIF vExamType = 1 THEN # exam + SET vLim = 38; + ELSE # credit or grading_credit + SET vLim = 60; + END IF; + + SELECT view_rating_result.RateRegular INTO vResult + FROM `submodules` + INNER JOIN `modules` ON modules.ID = submodules.ModuleID + INNER JOIN view_rating_result ON view_rating_result.DisciplineID = modules.DisciplineID AND + view_rating_result.StudentID = pStudentID + WHERE submodules.ID = pSubmoduleID + LIMIT 1; + RETURN vLim - vResult; +END // + + +DROP FUNCTION IF EXISTS SetStudentRate// +CREATE FUNCTION `SetStudentRate` + ( `pTeacherID` INT, + `pStudentID` INT, + `pSubmoduleID` INT, + `pRate` INT + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE vDisciplineID, vMaxRate, vModuleType INT DEFAULT -1; + DECLARE vIsOver, vIsLocked, vIsUsed BOOLEAN DEFAULT FALSE; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + SET vIsOver = TRUE; + SELECT disciplines.ID, + disciplines.IsLocked, + disciplines.IsMilestone, + submodules.IsUsed, + submodules.maxRate, + modules.Type + INTO vDisciplineID, vIsLocked, vIsOver, vIsUsed, vMaxRate, vModuleType + FROM `submodules` + INNER JOIN `modules` ON submodules.ModuleID = modules.ID + INNER JOIN `disciplines` ON modules.DisciplineID = disciplines.ID + WHERE submodules.ID = pSubModuleID + LIMIT 1; + + # correct max rate for extra module + IF vModuleType = 4 THEN # 4 - extra + SET vMaxRate = CalculateMaxRateForExtra(pSubmoduleID, pStudentID); + END IF; + + # 1) check rights + # 2) check, you can't rate regular and bonus after milestone + # 3) check, max rate exceeding + IF NOT InternalIsStudentAttached(pStudentID, vDisciplineID) OR + NOT InternalIsTeacherBounded(pTeacherID, vDisciplineID) OR + pRate > vMaxRate OR + (vIsOver AND (vModuleType = 1 OR vModuleType = 3)) # 1 - regular, 3 - bonus + THEN + RETURN -2; + END IF; + + # add rate, or update old + SET @tmp = 0; + INSERT INTO `rating_table` + (StudentID, TeacherID, SubmoduleID, Rate, Date) + VALUES ( pStudentID, pTeacherID, pSubmoduleID, pRate, CURDATE()) + ON DUPLICATE KEY UPDATE + rating_table.TeacherID = (@tmp := pTeacherID), + rating_table.Rate = pRate, + rating_table.Date = CURDATE(); + + # log rate + INSERT INTO `logs_rating` + (StudentID, SubmoduleID, TeacherID, Rate, Action ) + VALUES (pStudentID, pSubModuleID, pTeacherID, pRate, + CASE WHEN @tmp > 0 THEN 'add' ELSE 'change' END); + + # lock discipline for structure editing + IF NOT vIsLocked THEN + UPDATE `disciplines` + SET disciplines.IsLocked = TRUE + WHERE disciplines.ID = vDisciplineID + LIMIT 1; + END IF; + + # add submodule to max rate counting + IF NOT vIsUsed THEN + UPDATE `submodules` + SET submodules.IsUsed = TRUE + WHERE submodules.ID = pSubModuleID + LIMIT 1; + END IF; + RETURN 0; +END // + + + + + +# ------------------------------------------------------------------------------------------- +# Label: requests +# ------------------------------------------------------------------------------------------- + + + +DROP FUNCTION IF EXISTS SetRequestStatus// +CREATE FUNCTION `SetRequestStatus` + (`pRequestID` INT, `pStatus` VARCHAR(20) CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + UPDATE `requests` + SET requests.Status = pStatus + WHERE requests.ID = pRequestID + LIMIT 1; + RETURN ROW_COUNT()-1; +END// + + +DROP FUNCTION IF EXISTS CreateRequest// +CREATE FUNCTION `CreateRequest` + ( `pAccountID` INT, + `pTitle` VARCHAR(50) CHARSET utf8, + `pDescription` TEXT CHARSET utf8 + ) RETURNS int(11) + NO SQL +BEGIN + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + INSERT INTO `requests` + (AccountID, Title, Description, Status) + VALUES (pAccountID, pTitle, pDescription, 'opened'); + RETURN LAST_INSERT_ID(); +END// + + + + +# ------------------------------------------------------------------------------------------- +# Label: recovery +# ------------------------------------------------------------------------------------------- + + + +DROP FUNCTION IF EXISTS CreateRecoveryToken// +CREATE FUNCTION `CreateRecoveryToken` + ( `pAccountOrEMail` VARCHAR(255) CHARSET utf8, + `pToken` VARCHAR(100) CHARSET utf8 + ) RETURNS VARCHAR(255) charset utf8 + NO SQL +BEGIN + DECLARE vAccountID INT DEFAULT -1; + DECLARE vUserFullName TEXT; + DECLARE EXIT HANDLER FOR SQLEXCEPTION RETURN -1; + + # get account ID + SELECT accounts.ID INTO vAccountID + FROM `accounts` + WHERE accounts.EMail = pAccountOrEMail + LIMIT 1; + IF vAccountID <= 0 THEN + RETURN ''; + END IF; + + SET vUserFullName = GetUserFullNameByAccountID(vAccountID); + IF vUserFullName IS NULL OR vUserFullName = '' THEN + RETURN ''; + END IF; + + # transform all unused recovery tokens into used + UPDATE `recovery_tokens` + SET recovery_tokens.isUsed = 1 + WHERE recovery_tokens.isUsed = 0; + + # handle catch constraints violations + INSERT INTO `recovery_tokens` + (AccountID, Token ) + VALUES (vAccountID, Token); + RETURN vUserFullName; +END// + +DROP FUNCTION IF EXISTS GetUserFullNameByAccountID// +CREATE FUNCTION `GetUserFullNameByAccountID` + ( `pAccountID` INT(11)) RETURNS VARCHAR(255) charset utf8 +NO SQL +BEGIN + DECLARE vUserFullName VARCHAR(255); + DECLARE vChecker INT DEFAULT -1; + + SELECT students.ID As ID, CONCAT(students.LastName,' ',students.FirstName,' ',students.SecondName) As UserName + INTO vChecker, vUserFullName + FROM `students` + WHERE students.AccountID = pAccountID + LIMIT 1; + + IF vChecker <= 0 THEN + SELECT teachers.ID As ID, CONCAT(teachers.LastName,' ',teachers.FirstName,' ',teachers.SecondName) As UserName + INTO vChecker, vUserFullName + FROM `teachers` + WHERE teachers.AccountID = pAccountID + LIMIT 1; + + IF vChecker <= 0 THEN + RETURN ''; + END IF; + END IF; + + RETURN vUserFullName; +END// + +DROP FUNCTION IF EXISTS UseRecoveryToken// +CREATE FUNCTION `UseRecoveryToken` +( `pToken` VARCHAR(100) CHARSET utf8) RETURNS int(11) + NO SQL +BEGIN + DECLARE vChecker INT DEFAULT -1; + + # set token used + UPDATE `recovery_tokens` + SET recovery_tokens.IsUsed = 1 + WHERE recovery_tokens.Token = pToken + LIMIT 1; + RETURN ROW_COUNT()-1; +END// + + + +DELIMITER ; \ No newline at end of file diff --git a/db/StoredProcedures.sql b/db/StoredProcedures.sql index 182126f84fcdc8da2e05c61c61a36aefdbb3b1dc..f874f972ba52b1f61138ba85b3204453a8c8b04d 100644 --- a/db/StoredProcedures.sql +++ b/db/StoredProcedures.sql @@ -1,4428 +1,1048 @@ DELIMITER // -DROP FUNCTION IF EXISTS ChangeSubmoduleOrder// -DROP FUNCTION IF EXISTS ChangeSubmodule// -DROP FUNCTION IF EXISTS ChangeModule// -DROP FUNCTION IF EXISTS ChangeModuleOrder// -DROP FUNCTION IF EXISTS ChangeSubmoduleControlType// -DROP FUNCTION IF EXISTS ChangeSubmoduleMaxRate// -DROP PROCEDURE IF EXISTS GetGroupsForDiscipline // -DROP PROCEDURE IF EXISTS SearchStudentsNew// -DROP FUNCTION IF EXISTS CreateRequest// -DROP PROCEDURE IF EXISTS GetAccInfoByID// -DROP PROCEDURE IF EXISTS GetPersonalInfoByID// -DROP FUNCTION IF EXISTS GetRateForDisc// +DROP PROCEDURE IF EXISTS GetCurSemesterInfo// +DROP PROCEDURE IF EXISTS GetCurSemesterID// +DROP PROCEDURE IF EXISTS GetHashKey// --- ------------------------------------------------------------------------------------------- --- Label: abbreviations --- ------------------------------------------------------------------------------------------- - --- abbreviation: abbr --- specialization: spec --- department: dep - - --- ------------------------------------------------------------------------------------------- --- Label: changes --- ------------------------------------------------------------------------------------------- --- ChangePersonalDataForTeacher -> ChangeTeacher - --- ------------------------------------------------------------------------------------------- --- Label: internals --- ------------------------------------------------------------------------------------------- - - --- actually check for first scoring, in this case you cannot yet edit discipline --- SetRate stored procedure can change isLocked flag -DROP FUNCTION IF EXISTS InternalIsMapLocked// -CREATE FUNCTION `InternalIsMapLocked` ( `DisciplineID` INT - ) RETURNS boolean - NO SQL -BEGIN - DECLARE checker boolean; - SET checker = -1; - SELECT disciplines.isLocked - INTO checker - FROM `disciplines` - WHERE DisciplineID = disciplines.ID - LIMIT 1; - RETURN ( checker > 0 ); -END // - +DROP PROCEDURE IF EXISTS GetStudyGroupsForDisciplineFull// --- check, that student really take this course -DROP FUNCTION IF EXISTS InternalIsStudentAttached// -CREATE FUNCTION `InternalIsStudentAttached` ( `StudentID` INT, - `DisciplineID` INT - ) RETURNS boolean - NO SQL -BEGIN - DECLARE checker boolean; +DROP PROCEDURE IF EXISTS GetStudyGroupsForDiscipline// +DROP PROCEDURE IF EXISTS GetStudyGroups// - -- 1. student in main group and not detached OR - -- 2. student attached - SELECT ( ( disciplines_students.Type IS NOT NULL AND disciplines_students.Type = 'attach' ) OR - ( disciplines_groups.StudyGroupID IS NOT NULL AND - disciplines_groups.StudyGroupID = study_groups.ID AND - ( disciplines_students.Type IS NULL OR disciplines_students.Type != 'detach' ) - ) - ) - INTO checker - FROM `students` - INNER JOIN `study_groups` ON students.StudyGroupID = study_groups.ID - LEFT JOIN `disciplines_students` ON StudentID = disciplines_students.StudentID AND - DisciplineID = disciplines_students.DisciplineID - LEFT JOIN `disciplines_groups` ON study_groups.ID = disciplines_groups.StudyGroupID AND - DisciplineID = disciplines_groups.DisciplineID - WHERE students.ID = StudentID - LIMIT 1; +DROP PROCEDURE IF EXISTS GetDisciplineInfoByID// +DROP PROCEDURE IF EXISTS GetMapForDisciplineExam// +DROP PROCEDURE IF EXISTS GetMapForDiscipline// - RETURN (checker IS NOT NULL AND checker); -END // +DROP PROCEDURE IF EXISTS GetMapForStudent// +DROP PROCEDURE IF EXISTS GetMapForStudentExam// +DROP PROCEDURE IF EXISTS GetRatesForStudentsGroup// +DROP PROCEDURE IF EXISTS CreateFaculty // --- check, that teacher teach this course -DROP FUNCTION IF EXISTS InternalIsTeacherBinded// -CREATE FUNCTION `InternalIsTeacherBinded` ( `TeacherID` INT, - `DisciplineID` INT - ) RETURNS boolean - NO SQL -BEGIN - DECLARE checker boolean; - SET checker = FALSE; - SELECT (disciplines_teachers.ID IS NOT NULL AND disciplines_teachers.ID > 0) - INTO checker - FROM `disciplines_teachers` - WHERE TeacherID = disciplines_teachers.TeacherID AND - DisciplineID = disciplines_teachers.DisciplineID - LIMIT 1; - RETURN (checker IS NOT NULL AND checker); -END // +# ------------------------------------------------------------------------------------------- +# Label: abbreviations +# ------------------------------------------------------------------------------------------- -DROP FUNCTION IF EXISTS InternalIsTeacherAuthor// -CREATE FUNCTION `InternalIsTeacherAuthor` ( `TeacherID` INT, - `DisciplineID` INT - ) RETURNS boolean - NO SQL -BEGIN - DECLARE checker boolean; - SELECT (TeacherID = disciplines.AuthorID) - INTO checker - FROM `disciplines` - WHERE disciplines.ID = DisciplineID - LIMIT 1; - RETURN (checker IS NOT NULL AND checker); -END // +# abbreviation: abbr +# specialization: spec +# department: dep -DROP FUNCTION IF EXISTS GetDisciplineMaxRate// -CREATE FUNCTION `GetDisciplineMaxRate` ( `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE vMax INT; - SET vMax = 0; - -- discipline map consist of submodules, we sum all their max rates - SELECT SUM(submodules.MaxRate) - INTO vMax - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID AND - (modules.Type = 'regular' OR (modules.Type = 'exam' AND submodules.OrderNum = 1)) - WHERE DisciplineID = modules.DisciplineID; - - IF vMax IS NULL THEN - SET vMax = 0; - END IF; - RETURN vMax; -END // +# ------------------------------------------------------------------------------------------- +# Label: preferences +# Label: magic +# ------------------------------------------------------------------------------------------- -DROP FUNCTION IF EXISTS GetRateForDisc// -CREATE FUNCTION `GetRateForDisc` ( `StudentID` INT, - `DisciplineID` INT - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetSettings// +CREATE PROCEDURE `GetSettings`(IN `pKey` VARCHAR(50) CHARSET utf8) NO SQL BEGIN - DECLARE rate INT; - SET rate = -1; - - SELECT SUM(rating_table.Rate) - INTO rate - FROM `rating_table` - INNER JOIN `submodules` ON rating_table.SubmoduleID = submodules.ID - INNER JOIN `modules` ON submodules.ModuleID = modules.ID AND - DisciplineID = modules.DisciplineID - WHERE rating_table.StudentID = StudentID AND - ( modules.Type != 2 OR - submodules.ID = - ( SELECT submodules.ID - FROM `submodules` - INNER JOIN `rating_table` ON rating_table.SubModuleID = submodules.ID - WHERE submodules.ModuleID = modules.ID AND - rating_table.StudentID = StudentID - ORDER BY submodules.OrderNum DESC - LIMIT 1 - ) - ) - LIMIT 1; - - RETURN rate; + SELECT general_settings.* + FROM `general_settings` + WHERE general_settings.Name = pKey + LIMIT 1; END // -DROP FUNCTION IF EXISTS GetRateForDiscSemester// -CREATE FUNCTION `GetRateForDiscSemester` ( `StudentID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE rate INT; - SET rate = -1; - - - SELECT SUM(rating_table.Rate) - INTO rate - FROM `rating_table` - INNER JOIN `submodules` ON rating_table.SubmoduleID = submodules.ID - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - WHERE rating_table.StudentID = StudentID AND - DisciplineID = modules.DisciplineID AND - modules.Type = 'regular' - LIMIT 1; - - RETURN rate; -END // - +# ------------------------------------------------------------------------------------------- +# Label: semesters +# ------------------------------------------------------------------------------------------- -DROP FUNCTION IF EXISTS GetRateForDiscBonus// -CREATE FUNCTION `GetRateForDiscBonus` ( `StudentID` INT, - `DisciplineID` INT - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetSemesterInfo// +CREATE PROCEDURE `GetSemesterInfo` (IN `pSemesterID` INT) NO SQL BEGIN - DECLARE rate INT; - SET rate = -1; - - - SELECT SUM(rating_table.Rate) - INTO rate - FROM `rating_table` - INNER JOIN `submodules` ON rating_table.SubmoduleID = submodules.ID - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - WHERE rating_table.StudentID = StudentID AND - DisciplineID = modules.DisciplineID AND - modules.Type = 'bonus' - LIMIT 1; - - RETURN rate; + SELECT semesters.Num As 'Num', + semesters.Year As 'Year' + FROM `semesters` + WHERE semesters.ID = pSemesterID + LIMIT 1; END // - - - -DROP FUNCTION IF EXISTS GetRateForDiscExam// -CREATE FUNCTION `GetRateForDiscExam` ( `StudentID` INT, - `DisciplineID` INT - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetSemesters// +CREATE PROCEDURE `GetSemesters` () NO SQL BEGIN - DECLARE rate INT; - SET rate = -1; - + SELECT semesters.ID, + semesters.Year, + semesters.Num + FROM `semesters` + ORDER BY semesters.ID DESC; +END // - SELECT rating_table.Rate - INTO rate - FROM `rating_table` - INNER JOIN `submodules` ON rating_table.SubmoduleID = submodules.ID - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - WHERE rating_table.StudentID = StudentID AND - DisciplineID = modules.DisciplineID AND - modules.Type = 'exam' - ORDER BY submodules.OrderNum DESC - LIMIT 1; - RETURN rate; -END // +# ------------------------------------------------------------------------------------------- +# Label: faculties +# ------------------------------------------------------------------------------------------- -DROP FUNCTION IF EXISTS GetRateForDiscExamNum// -CREATE FUNCTION `GetRateForDiscExamNum` ( `StudentID` INT, - `DisciplineID` INT, - `OrderNum` INT - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetFaculties// +CREATE PROCEDURE `GetFaculties` ( ) NO SQL BEGIN - DECLARE rate INT; - SET rate = -1; - - - SELECT rating_table.Rate - INTO rate - FROM `rating_table` - INNER JOIN `submodules` ON rating_table.SubmoduleID = submodules.ID - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - WHERE rating_table.StudentID = StudentID AND - DisciplineID = modules.DisciplineID AND - modules.Type = 'exam' AND - submodules.OrderNum = OrderNum - LIMIT 1; - - RETURN rate; + SELECT faculties.ID, + faculties.Name, + faculties.Abbr + FROM `faculties` + ORDER BY faculties.Name ASC; END // +# ------------------------------------------------------------------------------------------- +# Label: departments +# ------------------------------------------------------------------------------------------- -DROP FUNCTION IF EXISTS GetRateForDiscExtra// -CREATE FUNCTION `GetRateForDiscExtra` ( `StudentID` INT, - `DisciplineID` INT, - `OrderNum` INT - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetDepartments// +CREATE PROCEDURE `GetDepartments` (IN `pFacultyID` INT) NO SQL BEGIN - DECLARE rate INT; - SET rate = -1; - - - SELECT rating_table.Rate - INTO rate - FROM `rating_table` - INNER JOIN `submodules` ON rating_table.SubmoduleID = submodules.ID - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - WHERE rating_table.StudentID = StudentID AND - DisciplineID = modules.DisciplineID AND - modules.Type = 'extra' AND - submodules.OrderNum = OrderNum - LIMIT 1; - - RETURN rate; + SELECT departments.ID, + departments.Name + FROM `departments` + WHERE departments.FacultyID = pFacultyID + ORDER BY departments.Name ASC; END // +# ------------------------------------------------------------------------------------------- +# Label: specializations +# ------------------------------------------------------------------------------------------- - - --- check, if anyone module is created -DROP FUNCTION IF EXISTS InternalIsMapCreated// -CREATE FUNCTION `InternalIsMapCreated` ( `DisciplineID` INT - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetSpecializations// +CREATE PROCEDURE `GetSpecializations` (IN `pFacultyID` INT) NO SQL -BEGIN - DECLARE res INT; - - SELECT SUM(submodules.MaxRate) - INTO res - FROM `modules` - LEFT JOIN `submodules` ON submodules.ModuleID = modules.ID - WHERE modules.DisciplineID = DisciplineID AND - (modules.Type = 1 OR ( modules.Type = 2 AND submodules.OrderNum = 1)) - LIMIT 1; - - - RETURN (res = 100); +BEGIN + SELECT specializations.ID, + specializations.Name, + specializations.Abbr + FROM `specializations` + WHERE specializations.FacultyID = pFacultyID + ORDER BY subjects.Name ASC; END // +# ------------------------------------------------------------------------------------------- +# Label: job positions +# ------------------------------------------------------------------------------------------- --- set notification flag -DROP FUNCTION IF EXISTS InternalNotify// -CREATE FUNCTION `InternalNotify` ( `AccountID` INT - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetJobPositions// +CREATE PROCEDURE `GetJobPositions` ( ) NO SQL -BEGIN - UPDATE `accounts` - SET accounts.Notification = 1 - WHERE accounts.ID = AccountID - LIMIT 1; - RETURN 0; +BEGIN + SELECT job_positions.ID, + job_positions.Name + FROM `job_positions` + ORDER BY job_positions.Name; END // +# ------------------------------------------------------------------------------------------- +# Label: grades +# ------------------------------------------------------------------------------------------- - --- ------------------------------------------------------------------------------------------- --- Label: preferences --- Label: magic --- ------------------------------------------------------------------------------------------- - - -DROP FUNCTION IF EXISTS SetHashKey// -CREATE FUNCTION `SetHashKey` ( `Value` VARCHAR(300) charset utf8 - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetGrades// +CREATE PROCEDURE `GetGrades` ( ) NO SQL BEGIN - UPDATE `general_settings` - SET general_settings.ValS = Value - WHERE general_settings.ID = 2 - LIMIT 1; - RETURN 0; + SELECT grades.ID AS 'ID', + grades.Num AS 'Num', + grades.Degree AS 'Degree' + FROM `grades` + ORDER BY grades.ID; END // +# ------------------------------------------------------------------------------------------- +# Label: study groups +# ------------------------------------------------------------------------------------------- -DROP FUNCTION IF EXISTS GetHashKey// -CREATE FUNCTION `GetHashKey` ( ) RETURNS varchar(300) CHARSET utf8 +DROP PROCEDURE IF EXISTS GetGroups// +CREATE PROCEDURE `GetGroups` + (IN `pGradeID` INT, IN `pFacultyID` INT) NO SQL BEGIN - RETURN ( SELECT general_settings.ValS - FROM `general_settings` - WHERE general_settings.ID = 2 - LIMIT 1 - ); + SELECT view_groups.GroupID AS 'ID', + view_groups.GroupNum, + view_groups.SpecID, + view_groups.SpecName, + view_groups.SpecAbbr + FROM `view_groups` + WHERE view_groups.GradeID = pGradeID AND + view_groups.FacultyID = pFacultyID + ORDER BY view_groups.GroupNum ASC; END // - -DROP FUNCTION IF EXISTS SetBitmaskByPagename// -CREATE FUNCTION `SetBitmaskByPagename` ( `Pagename` TEXT CHARSET utf8, - `Mask` INT - ) RETURNS int(11) +# get all general study groups, that takes this course +DROP PROCEDURE IF EXISTS GetGroupsForDiscipline// +CREATE PROCEDURE `GetGroupsForDiscipline` (IN `pDisciplineID` INT) NO SQL BEGIN - DECLARE checker INT; - SELECT page_access.ID - INTO checker - FROM `page_access` - WHERE page_access.Pagename = Pagename - LIMIT 1; - - IF checker > 0 THEN - UPDATE `page_access` - SET page_access.Bitmask = Mask - WHERE page_access.Pagename = Pagename - LIMIT 1; - ELSE - INSERT INTO `page_access` - (page_access.Pagename, page_access.Bitmask) - VALUES (Pagename, Mask); - END IF; - - RETURN 0; + SELECT view_groups.GroupID AS 'ID', + view_groups.GroupNum, + view_groups.GradeID, + view_groups.GradeNum, + view_groups.Degree, + view_groups.SpecID, + view_groups.SpecName, + view_groups.SpecAbbr + FROM `disciplines_groups` + INNER JOIN `view_groups` ON disciplines_groups.GroupID = view_groups.GroupID + WHERE disciplines_groups.DisciplineID = pDisciplineID + ORDER BY view_groups.GradeID ASC, view_groups.GroupID ASC; END // -DROP FUNCTION IF EXISTS GetBitmaskByPagename// -CREATE FUNCTION `GetBitmaskByPagename` ( `Pagename` TEXT CHARSET utf8 - ) RETURNS int(11) +# ------------------------------------------------------------------------------------------- +# Label: subjects +# ------------------------------------------------------------------------------------------- + +DROP PROCEDURE IF EXISTS GetSubjects// +CREATE PROCEDURE `GetSubjects` (IN `pFacultyID` INT) NO SQL BEGIN - RETURN ( SELECT page_access.Bitmask - FROM `page_access` - WHERE page_access.Pagename = Pagename - LIMIT 1 - ); + SELECT subjects.ID, + subjects.Name, + subjects.Abbr + FROM `subjects_faculties` + INNER JOIN `subjects` ON subjects_faculties.SubjectID = subjects.ID + WHERE subjects_faculties.FacultyID = pFacultyID + ORDER BY subjects.Name ASC; END // +# ------------------------------------------------------------------------------------------- +# Label: accounts +# ------------------------------------------------------------------------------------------- --- ------------------------------------------------------------------------------------------- --- Label: semesters --- ------------------------------------------------------------------------------------------- - - -DROP FUNCTION IF EXISTS GetCurSemesterID// -CREATE FUNCTION `GetCurSemesterID` ( ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetAccountInfo// +CREATE PROCEDURE `GetAccountInfo` ( IN `pUserID` INT ) NO SQL BEGIN - RETURN ( SELECT general_settings.Val - FROM `general_settings` - WHERE general_settings.ID = 1 - LIMIT 1 - ); + SELECT accounts.ID, + accounts.Login, + accounts.EMail, + user_roles.Type, + user_roles.RoleName AS 'Role', + user_roles.Mark AS 'RoleMark', + accounts.IsEnabled, + accounts.ActivationCode AS 'Code', + accounts.UserAgent + FROM `accounts` + INNER JOIN `user_roles` ON accounts.UserRoleID = user_roles.ID + WHERE accounts.ID = pUserID + LIMIT 1; END // -DROP FUNCTION IF EXISTS SetSemesterID// -CREATE FUNCTION `SetSemesterID` ( `SemesterID` INT - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetPersonalInfo// +CREATE PROCEDURE `GetPersonalInfo` ( IN `pUserID` INT ) NO SQL BEGIN - SET @CurrentSemesterID = SemesterID; - RETURN 0; -END // + DECLARE vAccountType INT DEFAULT -1; + SELECT user_roles.Type INTO vAccountType + FROM `accounts` + INNER JOIN `user_roles` ON accounts.UserRoleID = user_roles.ID + WHERE accounts.ID = pUserID + LIMIT 1; + # type 1: student + # 2: teacher + IF vAccountType = 1 THEN + SELECT view_students.LastName, + view_students.FirstName, + view_students.SecondName, + view_students.StudentID, + view_students.GradeID, + view_students.GradeNum, + view_students.GroupID, + view_students.GroupNum, + view_students.GroupName, + view_students.Degree, + view_students.SpecID, + view_students.SpecName, + view_students.SpecAbbr, + view_students.FacultyID, + view_students.FacultyName, + view_students.FacultyAbbr + FROM `view_students` + WHERE view_students.AccountID = pUserID AND + view_students.SemesterID = @CurrentSemesterID + LIMIT 1; + ELSE + SELECT view_teachers.LastName, + view_teachers.FirstName, + view_teachers.SecondName, + view_teachers.TeacherID, + view_teachers.DepID, + view_teachers.DepName, + view_teachers.JobPositionName, + view_teachers.FacultyID, + view_teachers.FacultyName, + view_teachers.FacultyAbbr + FROM `view_teachers` + WHERE view_teachers.AccountID = pUserID + LIMIT 1; + END IF; +END // + + + + +# ------------------------------------------------------------------------------------------- +# Label: teachers +# ------------------------------------------------------------------------------------------- +DROP PROCEDURE IF EXISTS GetTeachersByFaculty// +# CREATE PROCEDURE `GetTeachersByFaculty` (IN `pFacultyID` INT) +# NO SQL +# BEGIN +# SELECT view_teachers.TeacherID AS 'ID', +# view_teachers.LastName AS 'Last', +# view_teachers.FirstName AS 'First', +# view_teachers.SecondName AS 'Second', +# view_teachers.AccountID, +# view_teachers.JobPositionName, +# view_teachers.DepID, +# view_teachers.DepName +# FROM `view_teachers` +# WHERE view_teachers.FacultyID = pFacultyID +# ORDER BY view_teachers.LastName ASC, view_teachers.FirstName ASC; +# END // -DROP FUNCTION IF EXISTS SetCurSemesterID// -CREATE FUNCTION `SetCurSemesterID` ( `SemesterID` INT - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetTeachersByDepartment// +CREATE PROCEDURE `GetTeachersByDepartment` (IN `pDepartmentID` INT) NO SQL BEGIN - DECLARE checker INT; - - SELECT semesters.ID - INTO checker - FROM `semesters` - WHERE semesters.ID = SemesterID - LIMIT 1; - IF semesters.ID IS NULL OR semesters.ID <= 0 THEN - INSERT INTO `general_settings` - (general_settings.ID, general_settings.Val) - VALUES (1, SemesterID); - ELSE - UPDATE `general_settings` - SET general_settings.Val = SemesterID - WHERE general_settings.ID = 1 - LIMIT 1; - END IF; - RETURN 0; + SELECT view_teachers.TeacherID AS 'ID', + view_teachers.LastName, + view_teachers.FirstName, + view_teachers.SecondName, + view_teachers.AccountID, + view_teachers.JobPositionName, + view_teachers.DepID, + view_teachers.DepName + FROM `view_teachers` + WHERE view_teachers.DepID = pDepartmentID + ORDER BY view_teachers.LastName ASC, view_teachers.FirstName ASC; END // - -DROP FUNCTION IF EXISTS GetSemesterID// -CREATE FUNCTION `GetSemesterID` ( `Year` INT, - `Num` INT - ) RETURNS int(11) +# get teachers, that teach course +DROP PROCEDURE IF EXISTS GetTeachersForDiscipline// +CREATE PROCEDURE `GetTeachersForDiscipline`(IN `pDisciplineID` INT) NO SQL BEGIN - RETURN ( SELECT semesters.ID - FROM `semesters` - WHERE semesters.Year = Year AND - semesters.Num = Num - LIMIT 1 - ); -END // - - --- TODO: deprecated --- DROP PROCEDURE IF EXISTS GetCurSemesterInfo// --- CREATE PROCEDURE `GetCurSemesterInfo` ( ) --- NO SQL --- BEGIN --- SELECT semesters.ID AS 'SemesterID', --- semesters.Num As 'SemesterNum', --- semesters.Year As 'SemesterYear' --- FROM `general_settings` --- INNER JOIN `semesters` ON general_settings.Val = semesters.ID --- WHERE general_settings.ID = 1 --- LIMIT 1; --- END // - - - -DROP PROCEDURE IF EXISTS GetSemesterInfo// -CREATE PROCEDURE `GetSemesterInfo` ( IN `SemesterID` INT - ) + SELECT view_disciplines_teachers.TeacherID AS 'ID', + view_disciplines_teachers.LastName, + view_disciplines_teachers.FirstName, + view_disciplines_teachers.SecondName, + view_disciplines_teachers.JobPositionID, + view_disciplines_teachers.JobPositionName, + view_disciplines_teachers.DepID, + view_disciplines_teachers.DepName, + view_disciplines_teachers.FacultyID, + view_disciplines_teachers.FacultyAbbr, + view_disciplines_teachers.IsAuthor + FROM `view_disciplines_teachers` + WHERE view_disciplines_teachers.DisciplineID = pDisciplineID + ORDER BY view_disciplines_teachers.IsAuthor DESC, + view_disciplines_teachers.LastName ASC, + view_disciplines_teachers.FirstName ASC; +END // + + + +# get teachers, that don't teach course +DROP PROCEDURE IF EXISTS SearchTeachers// +CREATE PROCEDURE `SearchTeachers` + ( IN `pFacultyID` INT, IN `pDepartmentID` INT, + IN `pFullName` VARCHAR(100) CHARSET utf8, + # order: LastName + FirstName + SecondName + IN `pDisciplineID` INT ) NO SQL BEGIN - SELECT semesters.Num As 'Num', - semesters.Year As 'Year' - FROM `semesters` - WHERE semesters.ID = SemesterID - LIMIT 1; -END // + DECLARE vAuthorID INT DEFAULT -1; + SELECT disciplines.AuthorID INTO vAuthorID + FROM `disciplines` + WHERE disciplines.ID = pDisciplineID + LIMIT 1; -DROP PROCEDURE IF EXISTS GetSemesters// -CREATE PROCEDURE `GetSemesters` () - NO SQL -BEGIN - SELECT semesters.ID, - semesters.Year, - semesters.Num - FROM `semesters` - ORDER BY semesters.ID DESC; + SELECT view_teachers.TeacherID AS 'ID', + view_teachers.LastName, + view_teachers.FirstName, + view_teachers.SecondName, + view_teachers.JobPositionName, + view_teachers.DepID, + view_teachers.DepName, + (view_teachers.TeacherID = vAuthorID) AS 'IsAuthor' + FROM `view_teachers` + WHERE NOT InternalIsTeacherBounded(view_teachers.TeacherID, pDisciplineID) AND + view_teachers.FacultyID = pFacultyID AND + CONCAT( view_teachers.LastName, view_teachers.FirstName, view_teachers.SecondName) + LIKE CONCAT('%', pFullName, '%') + ORDER BY view_teachers.FacultyID ASC,view_teachers.DepName ASC, + view_teachers.LastName ASC, view_teachers.FirstName ASC; END // --- ------------------------------------------------------------------------------------------- --- Label: faculties --- ------------------------------------------------------------------------------------------- - +# ------------------------------------------------------------------------------------------- +# Label: students +# ------------------------------------------------------------------------------------------- - -DROP PROCEDURE IF EXISTS GetFaculties// -CREATE PROCEDURE `GetFaculties` ( ) +DROP PROCEDURE IF EXISTS GetStudentsByStudyGroups// +DROP PROCEDURE IF EXISTS GetStudents// +CREATE PROCEDURE `GetStudents` (IN `pGroupID` INT) NO SQL BEGIN - SELECT faculties.ID AS 'ID', - faculties.Name AS 'Name', - faculties.Abbr AS 'Abbr' - FROM `faculties` - ORDER BY faculties.Name ASC; + SELECT view_students.StudentID AS 'ID', + view_students.LastName, + view_students.FirstName, + view_students.SecondName, + view_students.AccountID, + view_students.GradeID, + view_students.GradeNum, + view_students.Degree, + view_students.GroupID, + view_students.GroupNum + FROM `view_students` + WHERE view_students.GroupID = pGroupID AND + view_students.SemesterID = @CurrentSemesterID + ORDER BY view_students.LastName ASC, view_students.FirstName ASC; END // --- ------------------------------------------------------------------------------------------- --- Label: departments --- ------------------------------------------------------------------------------------------- - - -DROP PROCEDURE IF EXISTS GetDepartments// -CREATE PROCEDURE `GetDepartments` ( IN `FacultyID` INT ) +DROP PROCEDURE IF EXISTS GetStudentsByFaculty// +CREATE PROCEDURE `GetStudentsByFaculty` + ( IN `pFacultyID` INT, + IN `pGradeID` INT, + IN `pGroupID` INT + ) NO SQL BEGIN - SELECT departments.ID AS 'ID', - departments.Name AS 'Name' - FROM `departments` - WHERE FacultyID = departments.FacultyID - ORDER BY departments.Name ASC; -END // - - - - --- ------------------------------------------------------------------------------------------- --- Label: specializations --- ------------------------------------------------------------------------------------------- - - -DROP PROCEDURE IF EXISTS GetSpecializations// -CREATE PROCEDURE `GetSpecializations` ( IN `FacultyID` INT - ) + SELECT view_students.StudentID AS 'ID', + view_students.LastName, + view_students.FirstName, + view_students.SecondName, + view_students.AccountID, + view_students.GradeID, + view_students.GradeNum, + view_students.Degree, + view_students.GroupID, + view_students.GroupNum + FROM `view_students` + WHERE view_students.FacultyID = pFacultyID AND + view_students.SemesterID = @CurrentSemesterID AND + (pGradeID = 0 OR view_students.GradeID = pGradeID) AND + (pGroupID = 0 OR view_students.GroupID = pGroupID) + ORDER BY view_students.LastName ASC, view_students.FirstName ASC; +END // + + +# students, that don't included in general groups without attached +DROP PROCEDURE IF EXISTS SearchStudents// +CREATE PROCEDURE `SearchStudents` + ( IN `pGradeID` INT, IN `pGroupID` INT, IN `pFacultyID` INT, + IN `pFullName` VARCHAR(100) CHARSET utf8, + IN `pDisciplineID` INT) NO SQL BEGIN - SELECT specializations.ID AS 'ID', - specializations.Name AS 'Name', - specializations.Abbr AS 'Abbr' - FROM `specializations` - WHERE specializations.FacultyID = FacultyID - ORDER BY subjects.Name ASC; -END // - - - --- ------------------------------------------------------------------------------------------- --- Label: job positions --- ------------------------------------------------------------------------------------------- - - -DROP PROCEDURE IF EXISTS GetJobPositions// -CREATE PROCEDURE `GetJobPositions` ( ) + SELECT view_students.StudentID AS 'ID', + view_students.LastName, + view_students.FirstName, + view_students.SecondName, + view_students.GradeID, + view_students.GradeNum, + view_students.Degree, + view_students.GroupID, + view_students.GroupNum + FROM `view_students` + LEFT JOIN `disciplines_students` ON disciplines_students.StudentID = view_students.StudentID AND + disciplines_students.DisciplineID = pDisciplineID + LEFT JOIN `disciplines_groups` ON disciplines_groups.GroupID = view_students.GroupID AND + disciplines_groups.DisciplineID = pDisciplineID + WHERE view_students.SemesterID = @CurrentSemesterID AND + view_students.FacultyID = pFacultyID AND + view_students.GradeID = pGradeID AND + (view_students.GroupID = pGroupID OR pGroupID = 0) AND + CONCAT(view_students.LastName, view_students.FirstName, view_students.SecondName) + LIKE CONCAT('%', pFullName, '%') AND + disciplines_groups.ID IS NULL AND + (disciplines_students.Type IS NULL OR disciplines_students.Type != 'attach') + ORDER BY view_students.GradeID ASC, + view_students.GroupID ASC; +END // + + + +# all students in general groups, that take course (with attached and detached) +DROP PROCEDURE IF EXISTS GetStudentsForDiscipline// +CREATE PROCEDURE `GetStudentsForDiscipline` + ( IN `pDisciplineID` INT) NO SQL BEGIN - SELECT job_positions.ID AS 'ID', - job_positions.Name AS 'Name' - FROM `job_positions` - ORDER BY job_positions.Name; -END // - - --- ------------------------------------------------------------------------------------------- --- Label: grades --- ------------------------------------------------------------------------------------------- - - -DROP FUNCTION IF EXISTS GetGradeID// -CREATE FUNCTION `GetGradeID`( `GradeNum` INT, - `Degree` VARCHAR(30) charset utf8-- enum('bachelor','master','specialist') - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE res INT; - - SELECT grades.ID - INTO res - FROM `grades` - WHERE grades.Num = GradeNum AND - grades.Degree = Degree - LIMIT 1; - - IF res > 0 THEN - RETURN res; - ELSE - RETURN -1; - END IF; -END // - - -DROP PROCEDURE IF EXISTS GetGrades// -CREATE PROCEDURE `GetGrades` ( ) + SELECT view_disciplines_students.StudentID AS 'ID', + view_disciplines_students.LastName, + view_disciplines_students.FirstName, + view_disciplines_students.SecondName, + view_disciplines_students.GradeID, + view_disciplines_students.GradeNum, + view_disciplines_students.Degree, + view_disciplines_students.GroupID, + view_disciplines_students.GroupNum, + view_disciplines_students.AttachType AS 'AttachType' + FROM `view_disciplines_students` + WHERE view_disciplines_students.DisciplineID = pDisciplineID AND + view_disciplines_students.SemesterID = @CurrentSemesterID + ORDER BY (view_disciplines_students.AttachType IS NULL OR + view_disciplines_students.AttachType = 'detach') DESC, + view_disciplines_students.GradeID ASC, + view_disciplines_students.GroupNum ASC, + view_disciplines_students.LastName ASC, + view_disciplines_students.FirstName ASC; +END // + + + +# all students takes that course (general groups + attached) +DROP PROCEDURE IF EXISTS GetStudentsForRating// +CREATE PROCEDURE `GetStudentsForRating` + ( IN `pDisciplineID` INT) NO SQL -BEGIN - SELECT grades.ID AS 'ID', - grades.Num AS 'Num', - grades.Degree AS 'Degree' - FROM `grades` - ORDER BY grades.ID; +BEGIN + SELECT view_disciplines_students.StudentID AS 'ID', + view_disciplines_students.LastName, + view_disciplines_students.FirstName, + view_disciplines_students.SecondName, + view_disciplines_students.GradeID, + view_disciplines_students.GradeNum, + view_disciplines_students.Degree, + view_disciplines_students.GroupID, + view_disciplines_students.GroupNum, + (view_disciplines_students.AttachType IS NOT NULL) AS 'IsAttached' + FROM `view_disciplines_students` + WHERE view_disciplines_students.SemesterID = @CurrentSemesterID AND + view_disciplines_students.DisciplineID = pDisciplineID AND + (view_disciplines_students.AttachType IS NULL OR + view_disciplines_students.AttachType = 'attach') + ORDER BY view_disciplines_students.GradeID ASC, + view_disciplines_students.GroupNum ASC, + view_disciplines_students.LastName ASC, + view_disciplines_students.FirstName ASC; END // --- ------------------------------------------------------------------------------------------- --- Label: study groups --- ------------------------------------------------------------------------------------------- - - -DROP FUNCTION IF EXISTS CreateStudyGroup// -CREATE FUNCTION `CreateStudyGroup` ( `GradeID` INT, - `GroupNum` INT, - `SpecializationID` INT, - `GroupName` VARCHAR(50) CHARSET utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker INT; - - -- check for grade (GradeID) availability - SET checker = -1; - SELECT grades.ID - INTO checker - FROM `grades` - INNER JOIN `specializations` ON SpecializationID = specializations.ID - WHERE GradeID = grades.ID - LIMIT 1; - IF checker <= 0 OR GroupName IS NULL THEN - RETURN -1; - END IF; - -- check, that such discipline already created - SET checker = -1; - SELECT study_groups.ID - INTO checker - FROM `study_groups` - WHERE GradeID = study_groups.GradeID AND - GroupNum = study_groups.GroupNum AND - SpecializationID = study_groups.SpecializationID - LIMIT 1; - IF checker > 0 THEN - RETURN -1; - END IF; - - -- create discipline - INSERT INTO `study_groups` - (study_groups.GradeID, study_groups.GroupNum, study_groups.SpecializationID, study_groups.Name ) - VALUES (GradeID, GroupNum, SpecializationID, GroupName); - RETURN 0; -END // +# ------------------------------------------------------------------------------------------- +# Label: disciplines +# ------------------------------------------------------------------------------------------- --- TODO: check --- DROP PROCEDURE IF EXISTS GetStudyGroups// --- CREATE PROCEDURE `GetStudyGroups` ( IN `GradeID` INT, --- IN `FacultyID` INT --- ) --- NO SQL --- BEGIN --- SELECT study_groups.ID AS 'GroupID', --- study_groups.GroupNum AS 'GroupNum', --- specializations.ID AS 'SpecID', --- specializations.Name AS 'SpecName', --- specializations.Abbr AS 'SpecAbbr' --- FROM `study_groups` --- INNER JOIN `specializations` ON specializations.ID = study_groups.SpecializationID AND --- FacultyID = specializations.FacultyID --- WHERE GradeID = 0 OR --- study_groups.GradeID = GradeID --- ORDER BY specializations.ID ASC, --- study_groups.GradeID ASC, --- study_groups.GroupNum ASC; --- END // +DROP PROCEDURE IF EXISTS GetDisciplineInfo// +CREATE PROCEDURE `GetDisciplineInfo` + ( IN `pDisciplineID` INT) +NO SQL + BEGIN + SELECT view_disciplines.DisciplineID, + view_disciplines.AuthorID, + view_disciplines.GradeID, + view_disciplines.GradeNum, + view_disciplines.Degree, + view_disciplines.ExamType, + view_disciplines.LectureCount, + view_disciplines.PracticeCount, + view_disciplines.LabCount, + view_disciplines.SemesterID, + view_disciplines.SubjectID, + view_disciplines.SubjectName, + view_disciplines.SubjectAbbr, + view_disciplines.FacultyID, + view_disciplines.FacultyName, + view_disciplines.IsLocked, + view_disciplines.isMilestone, + (modules.ID IS NOT NULL) AS 'IsBonus' + FROM `view_disciplines` + LEFT JOIN `modules` ON modules.DisciplineID = view_disciplines.DisciplineID AND + modules.Type = 'bonus' + WHERE view_disciplines.DisciplineID = pDisciplineID + LIMIT 1; + END // -DROP PROCEDURE IF EXISTS GetStudyGroups// -CREATE PROCEDURE `GetStudyGroups` ( IN `GradeID` INT, - IN `FacultyID` INT - ) +# TODO: haven't reference on it +# all disciplines for faculty in current semester +DROP PROCEDURE IF EXISTS GetDisciplines// +CREATE PROCEDURE `GetDisciplines` ( IN `pFacultyID` INT ) NO SQL BEGIN - SELECT study_groups.ID AS 'ID', - study_groups.GroupNum AS 'GroupNum', - specializations.ID AS 'SpecID', - specializations.Name AS 'SpecName', - specializations.Abbr AS 'SpecAbbr' - FROM `study_groups` - INNER JOIN `specializations` ON specializations.ID = study_groups.SpecializationID AND - FacultyID = specializations.FacultyID - WHERE GradeID = study_groups.GradeID - ORDER BY study_groups.GroupNum ASC; + SELECT view_disciplines.DisciplineID AS 'ID', + view_disciplines.SubjectID, + view_disciplines.SubjectName, + view_disciplines.ExamType, + (view_disciplines_results.DisciplineRateMax = 100) AS 'IsMapCreated' + FROM `view_disciplines` + INNER JOIN `view_disciplines_results` + ON view_disciplines_results.DisciplineID = view_disciplines.DisciplineID + WHERE view_disciplines.SemesterID = @CurrentSemesterID AND + view_disciplines.FacultyID = pFacultyID + ORDER BY view_disciplines.SubjectName ASC; END // --- get all study groups, that takes this course (i.e. Discipline) -DROP PROCEDURE IF EXISTS GetStudyGroupsForDiscipline// -CREATE PROCEDURE `GetStudyGroupsForDiscipline` ( IN `DisciplineID` INT ) - NO SQL -BEGIN - SELECT study_groups.ID AS 'ID', - study_groups.GroupNum AS 'GroupNum', - study_groups.Name AS 'Name', - grades.ID AS 'GradeID', - grades.Num AS 'GradeNum', - grades.Degree AS 'Degree', - -- TODO deprecated disciplines_groups.ID AS 'DiscGroupID', - specializations.ID AS 'SpecID', - specializations.Name AS 'SpecName', - specializations.Abbr AS 'SpecAbbr' - FROM `disciplines_groups` - INNER JOIN `study_groups` ON study_groups.ID = disciplines_groups.StudyGroupID - INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID - INNER JOIN `grades` ON study_groups.GradeID = grades.ID - WHERE disciplines_groups.DisciplineID = DisciplineID - ORDER BY grades.ID ASC, - study_groups.GroupNum ASC; -END // - -DROP PROCEDURE IF EXISTS GetStudyGroupsForDisciplineFull// -CREATE PROCEDURE `GetStudyGroupsForDisciplineFull` ( IN `DisciplineID` INT ) +# processed format of output (after desequentialization) +# { discipline1 {group1, group2, ...}, discipline2 {groupN, ...}, ... } +DROP PROCEDURE IF EXISTS GetDisciplinesForTeacher// +CREATE PROCEDURE `GetDisciplinesForTeacher`(IN `pTeacherID` INT) NO SQL BEGIN - SELECT DISTINCT - study_groups.ID AS 'ID', - study_groups.GroupNum AS 'GroupNum', - study_groups.Name AS 'Name', - grades.ID AS 'GradeID', - grades.Num AS 'GradeNum', - grades.Degree AS 'Degree', - -- TODO deprecated disciplines_groups.ID AS 'DiscGroupID', - specializations.ID AS 'SpecID', - specializations.Name AS 'SpecName', - specializations.Abbr AS 'SpecAbbr' - FROM `students` - INNER JOIN `study_groups` ON students.StudyGroupID = study_groups.ID - INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID - INNER JOIN `grades` ON study_groups.GradeID = grades.ID - WHERE InternalIsStudentAttached(students.ID, DisciplineID) - ORDER BY grades.ID ASC, - study_groups.GroupNum ASC; -END // - - --- ------------------------------------------------------------------------------------------- --- Label: subjects --- ------------------------------------------------------------------------------------------- - - - -DROP FUNCTION IF EXISTS CreateSubject// -CREATE FUNCTION `CreateSubject` ( `FacultyID` INT, - `SubjectName` VARCHAR(200) charset utf8, - `SubjectAbbr` VARCHAR(20) charset utf8 - ) RETURNS int(11) + SELECT DISTINCT view_disciplines.DisciplineID AS 'ID', + view_disciplines.ExamType, + view_disciplines.GradeID, + view_disciplines.GradeNum, + view_disciplines.Degree, + view_groups.GroupID, + view_groups.GroupNum, + view_groups.GroupName, + view_disciplines.SubjectID, + view_disciplines.SubjectName, + (pTeacherID = view_disciplines.AuthorID) AS 'IsAuthor', + (view_disciplines_results.DisciplineRateMax = 100) AS 'IsMapCreated', + view_disciplines.IsLocked + FROM `disciplines_teachers` + LEFT JOIN `disciplines_groups` ON disciplines_groups.DisciplineID = disciplines_teachers.DisciplineID + # left -> inner join with maybe NULL ? + LEFT JOIN `view_groups` ON view_groups.GroupID = disciplines_groups.GroupID + LEFT JOIN `view_disciplines` ON disciplines_teachers.DisciplineID = view_disciplines.DisciplineID + LEFT JOIN `view_disciplines_results` ON view_disciplines_results.DisciplineID = view_disciplines.DisciplineID + WHERE disciplines_teachers.TeacherID = pTeacherID AND + view_disciplines.SemesterID = @CurrentSemesterID + ORDER BY view_disciplines.GradeID ASC, + view_disciplines.SubjectName ASC, + view_disciplines.DisciplineID ASC, + view_groups.GroupNum ASC; +END // + + +# get all disciplines, that student take. +DROP PROCEDURE IF EXISTS GetDisciplinesForStudent// +CREATE PROCEDURE `GetDisciplinesForStudent`(IN `pStudentID` INT) NO SQL -BEGIN - DECLARE checker, SubjectID INT; - - SET SubjectID = -1; - SELECT subjects.ID - INTO SubjectID - FROM `subjects` - WHERE SubjectName = subjects.Name - LIMIT 1; - - IF SubjectID <= 0 THEN - -- subject with this name doesn't exist - - -- create subject - INSERT INTO `subjects` - (subjects.Name, subjects.Abbr) - VALUES (SubjectName, SubjectAbbr); - - -- get it's id - SET SubjectID = -1; - SELECT subjects.ID - INTO SubjectID - FROM `subjects` - WHERE SubjectName = subjects.Name - LIMIT 1; - IF SubjectID <= 0 THEN - RETURN -1; - END IF; - ELSE - -- subject extst - -- if subject already attached to faculty, then exit - SET checker = -1; - SELECT subjects_faculties.ID - INTO checker - FROM `subjects_faculties` - WHERE FacultyID = subjects_faculties.FacultyID AND - SubjectID = subjects_faculties.SubjectID - LIMIT 1; - IF checker > 0 THEN - RETURN 1; - END IF; - END IF; - - -- attach subject to faculty - INSERT INTO `subjects_faculties` - (subjects_faculties.SubjectID, subjects_faculties.FacultyID) - VALUES (SubjectID, FacultyID); - RETURN 0; -END // - - -DROP PROCEDURE IF EXISTS GetSubjects// -CREATE PROCEDURE `GetSubjects` ( IN `FacultyID` INT - ) +BEGIN + SELECT view_disciplines.DisciplineID AS 'ID', + view_disciplines.SubjectID, + view_disciplines.SubjectName, + view_disciplines.ExamType, + view_teachers.LastName, + view_teachers.FirstName, + view_teachers.SecondName, + (view_rating_result.RateRegular + view_rating_result.RateExtra + + view_rating_result.RateBonus + view_rating_result.RateExam) AS 'Rate', + view_disciplines_results.DisciplineRateCur AS 'MaxCurrentRate' + # --isMapCreated + FROM `view_disciplines_students` + INNER JOIN `view_disciplines` ON view_disciplines.DisciplineID = view_disciplines_students.DisciplineID + INNER JOIN `view_disciplines_results` ON view_disciplines_results.DisciplineID = view_disciplines_students.DisciplineID + INNER JOIN `view_rating_result` ON view_rating_result.StudentID = pStudentID AND + view_rating_result.DisciplineID = view_disciplines_results.DisciplineID + INNER JOIN `view_teachers` ON view_teachers.TeacherID = view_disciplines.AuthorID + WHERE view_disciplines_students.SemesterID = @CurrentSemesterID AND + view_disciplines.SemesterID = @CurrentSemesterID AND + view_disciplines_students.StudentID = pStudentID AND + (view_disciplines_students.AttachType IS NULL OR view_disciplines_students.AttachType != 'detach') + ORDER BY view_disciplines.ExamType ASC, view_disciplines.DisciplineID ASC; +END // + + +# get all disciplines for group, including disciplines, where students have attached status +DROP PROCEDURE IF EXISTS GetDisciplinesForGroup// +CREATE PROCEDURE `GetDisciplinesForGroup`(IN `pGroupID` INT) NO SQL BEGIN - SELECT subjects.ID AS 'ID', - subjects.Name AS 'Name', - subjects.Abbr AS 'Abbr' - FROM `subjects_faculties` - INNER JOIN `subjects` ON subjects_faculties.SubjectID = subjects.ID - WHERE subjects_faculties.FacultyID = FacultyID - ORDER BY subjects.Name ASC; -END // - - - - --- ------------------------------------------------------------------------------------------- --- Label: accounts --- ------------------------------------------------------------------------------------------- - --- TODO: count? wtf? - -DROP FUNCTION IF EXISTS GetAccCountByCode// -CREATE FUNCTION `GetAccCountByCode` ( `Code` VARCHAR(40) CHARSET utf8 - ) RETURNS int(11) + (SELECT view_disciplines.DisciplineID, + view_disciplines.SubjectName, + view_disciplines.ExamType + FROM `disciplines_groups` + INNER JOIN `view_disciplines` ON view_disciplines.DisciplineID = disciplines_groups.DisciplineID AND + view_disciplines.SemesterID = @CurrentSemesterID + WHERE disciplines_groups.GroupID = pGroupID + ) UNION DISTINCT + (SELECT view_disciplines.DisciplineID, + view_disciplines.SubjectName, + view_disciplines.ExamType + FROM `disciplines_students` + INNER JOIN `students` ON disciplines_students.StudentID = students.ID + INNER JOIN `view_disciplines` ON view_disciplines.DisciplineID = disciplines_students.DisciplineID AND + view_disciplines.SemesterID = @CurrentSemesterID + INNER JOIN `students_groups` ON students_groups.StudentID = students.ID AND + students_groups.SemesterID = @CurrentSemesterID + WHERE students_groups.GroupID = pGroupID + ); +END // + + + +# ------------------------------------------------------------------------------------------- +# Label: rating +# ------------------------------------------------------------------------------------------- + +DROP PROCEDURE IF EXISTS GetRatesForGroup// +CREATE PROCEDURE `GetRatesForGroup` + ( IN `pDisciplineID` INT, IN `pGroupID` INT) NO SQL BEGIN - RETURN ( SELECT COUNT(*) - FROM `accounts` - WHERE accounts.ActivationCode = Code - LIMIT 1 - ); -END // - + DECLARE vChecker BOOLEAN DEFAULT FALSE; + SELECT disciplines_groups.ID IS NOT NULL INTO vChecker + FROM `disciplines_groups` + WHERE disciplines_groups.DisciplineID = pDisciplineID AND + disciplines_groups.GroupID = pGroupID + LIMIT 1; -DROP FUNCTION IF EXISTS GetAccCountByMail // -CREATE FUNCTION `GetAccCountByMail` ( `EMail` VARCHAR(50) CHARSET utf8 - ) RETURNS int(11) - NO SQL -BEGIN - RETURN ( SELECT COUNT(*) - FROM `accounts` - WHERE accounts.EMail = EMail - LIMIT 1 - ); + IF !vChecker THEN + SELECT students.ID, + students.LastName, + students.FirstName, + students.SecondName, + view_rating_result.RateRegular AS 'intermediate', + view_rating_result.RateBonus AS 'bonus', + view_rating_result.RateExam AS 'exam' + FROM `students` + LEFT JOIN `view_rating_result` ON view_rating_result.DisciplineID = pDisciplineID AND + view_rating_result.StudentID = students.ID + INNER JOIN `students_groups` ON students_groups.StudentID = students.ID AND + students_groups.SemesterID = @CurrentSemesterID + WHERE students_groups.GroupID = pGroupID AND + EXISTS(SELECT * FROM `disciplines_students` + WHERE disciplines_students.DisciplineID = pDisciplineID AND + disciplines_students.StudentID = students.ID) + ORDER BY students.LastName ASC; + ELSE + SELECT students.ID, + students.LastName, + students.FirstName, + students.SecondName, + view_rating_result.RateRegular AS 'intermediate', + view_rating_result.RateBonus AS 'bonus', + view_rating_result.RateExam AS 'exam' + FROM `students` + LEFT JOIN `view_rating_result` ON view_rating_result.DisciplineID = pDisciplineID AND + view_rating_result.StudentID = students.ID + INNER JOIN `students_groups` ON students_groups.StudentID = students.ID AND + students_groups.SemesterID = @CurrentSemesterID + WHERE students_groups.GroupID = pGroupID AND + NOT EXISTS(SELECT * FROM `disciplines_students` + WHERE disciplines_students.DisciplineID = pDisciplineID AND + disciplines_students.StudentID = students.ID) + ORDER BY students.LastName ASC; + END IF; END // -DROP FUNCTION IF EXISTS GetAccCountByLogin// -CREATE FUNCTION `GetAccCountByLogin` ( `Login` VARCHAR(50) CHARSET utf8 - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetRates// +CREATE PROCEDURE `GetRates` + ( IN `pStudentID` INT, IN `pDisciplineID` INT) NO SQL -BEGIN - RETURN ( SELECT COUNT(*) - FROM `accounts` - WHERE accounts.Login = Login - LIMIT 1 - ); -END // - - - -DROP PROCEDURE IF EXISTS GetAccountInfo// -CREATE PROCEDURE `GetAccountInfo` ( IN `UserID` INT - ) +BEGIN + SELECT view_roadmap.ModuleID, + view_roadmap.ModuleName, + view_roadmap.SubmoduleID, + view_roadmap.SubmoduleName, + view_roadmap.SubmoduleRate AS 'MaxRate', + view_roadmap.SubmoduleType AS 'SubmoduleControl', + view_roadmap.ModuleType, + rating_table.Rate, + rating_table.Date + FROM `view_roadmap` + LEFT JOIN `rating_table` ON view_roadmap.SubmoduleID = rating_table.SubmoduleID AND + rating_table.StudentID = pStudentID + WHERE view_roadmap.DisciplineID = pDisciplineID AND + ( + view_roadmap.ModuleType != 'exam' OR + view_roadmap.SubmoduleID = (@tmp = + (SELECT rating_table.SubmoduleID FROM `submodules` + INNER JOIN `rating_table` ON rating_table.SubModuleID = submodules.ID + WHERE submodules.ModuleID = view_roadmap.ModuleID AND rating_table.StudentID = pStudentID + ORDER BY submodules.OrderNum DESC + LIMIT 1) + ) OR + ( @tmp IS NULL AND view_roadmap.SubmoduleOrderNum = 1) + ) + ORDER BY view_roadmap.ModuleType ^ 1 ASC, + -- 1, 3, 2, 4 ASC + view_roadmap.ModuleOrderNum ASC, + view_roadmap.SubmoduleOrderNum ASC; +END // + + +# TODO: rename ~ GetRatesForStudent, Rating +DROP PROCEDURE IF EXISTS GetRatesExam// +CREATE PROCEDURE `GetRatesExam` + ( IN `pStudentID` INT, IN `pDisciplineID` INT) NO SQL -BEGIN - SELECT accounts.ID AS 'ID', - accounts.Login AS 'Login', - accounts.EMail AS 'EMail', - user_roles.Type AS 'Type', - user_roles.RoleName AS 'Role', - user_roles.Mark AS 'RoleMark', - accounts.isEnabled, - accounts.ActivationCode AS 'Code', - accounts.UserAgent - FROM `accounts` - INNER JOIN `user_roles` ON accounts.UserRoleID = user_roles.ID - WHERE accounts.ID = UserID - LIMIT 1; +BEGIN + SELECT view_roadmap.ModuleID, + view_roadmap.ModuleName, + view_roadmap.SubmoduleID, + view_roadmap.SubmoduleName, + view_roadmap.SubmoduleRate AS 'MaxRate', + view_roadmap.SubmoduleType, + rating_table.Rate, + rating_table.Date, + view_roadmap.ModuleType + FROM `view_roadmap` + LEFT JOIN `rating_table` ON rating_table.SubmoduleID = view_roadmap.SubmoduleID AND + rating_table.StudentID = pStudentID + WHERE view_roadmap.DisciplineID = pDisciplineID + ORDER BY view_roadmap.ModuleOrderNum ASC, + view_roadmap.SubmoduleOrderNum ASC; END // - - -DROP PROCEDURE IF EXISTS GetPersonalInfo// -CREATE PROCEDURE `GetPersonalInfo` ( IN `UserID` INT - ) +DROP PROCEDURE IF EXISTS GetAttestationData// +CREATE PROCEDURE `GetAttestationData` + ( IN `pDisciplineID` INT, IN `pGroupID` INT) NO SQL -BEGIN - DECLARE accType INT; - SELECT user_roles.Type - INTO accType - FROM `accounts` - INNER JOIN `user_roles` ON accounts.UserRoleID = user_roles.ID - WHERE accounts.ID = UserID - LIMIT 1; - - -- type 1: student - -- 2: teacher - IF accType = 1 THEN - - SELECT students.LastName AS 'Last', - students.FirstName AS 'First', - students.SecondName AS 'Second', - students.ID AS 'StudentID', - grades.ID AS 'GradeID', - grades.Num AS 'GradeNum', - study_groups.ID AS 'GroupID', - study_groups.GroupNum AS 'GroupNum', - study_groups.Name AS 'GroupName', - grades.Degree AS 'Degree', - specializations.ID AS 'SpecID', - specializations.Name AS 'SpecName', - specializations.Abbr AS 'SpecAbbr', - faculties.ID AS 'FacultyID', - faculties.Name AS 'FacultyName', - faculties.Abbr AS 'FacultyAbbr' - FROM `students` - INNER JOIN `study_groups` ON students.StudyGroupID = study_groups.ID - INNER JOIN `grades` ON grades.ID = study_groups.GradeID - INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID - INNER JOIN `faculties` ON specializations.FacultyID = faculties.ID - WHERE students.AccountID = UserID - LIMIT 1; - - ELSE - SELECT teachers.LastName AS 'Last', - teachers.FirstName AS 'First', - teachers.SecondName AS 'Second', - teachers.ID AS 'TeacherID', - departments.ID AS 'DepID', - departments.Name AS 'DepName', - job_positions.Name AS 'JobPositionName', - faculties.ID AS 'FacultyID', - faculties.Name AS 'FacultyName', - faculties.Abbr AS 'FacultyAbbr' - FROM `teachers` - INNER JOIN `departments` ON departments.ID = teachers.DepartmentID - INNER JOIN `faculties` ON departments.FacultyID = faculties.ID - INNER JOIN `job_positions` ON job_positions.ID = teachers.JobPositionID - WHERE teachers.AccountID = UserID - LIMIT 1; - - END IF; -END // - - - -DROP FUNCTION IF EXISTS ActivateAccount// -CREATE FUNCTION `ActivateAccount` ( `Code` VARCHAR(40) CHARSET utf8, - `Login` VARCHAR(50) CHARSET utf8, - `EMail` VARCHAR(50) CHARSET utf8, - `Password` VARCHAR(255) CHARSET utf8 - ) RETURNS int(11) +BEGIN + SELECT students.ID AS 'StudentID', + rating_table.Rate As 'Rate', + rating_table.Date As 'Date', + submodules.OrderNum As 'OrderNum', + modules.Type As 'Type' + FROM `students` + INNER JOIN `students_groups` ON students_groups.StudentID = students.ID AND + students_groups.SemesterID = @CurrentSemesterID + + LEFT JOIN `disciplines_groups` ON disciplines_groups.DisciplineID = pDisciplineID AND + disciplines_groups.GroupID = students_groups.GroupID + LEFT JOIN `disciplines_students` ON disciplines_students.DisciplineID = pDisciplineID AND + disciplines_students.StudentID = students.ID + + LEFT JOIN `modules` ON modules.DisciplineID = pDisciplineID AND + (modules.Type = 'exam' OR modules.Type = 'extra') + LEFT JOIN `submodules` ON submodules.ModuleID = modules.ID + LEFT JOIN `rating_table` ON rating_table.SubmoduleID = submodules.ID AND + rating_table.StudentID = students.ID + WHERE students_groups.GroupID = pGroupID AND rating_table.Rate IS NOT NULL AND + ((disciplines_students.StudentID IS NOT NULL AND disciplines_students.Type = 'attach') + OR (disciplines_groups.DisciplineID IS NOT NULL AND disciplines_students.Type IS NULL) + ) + ORDER BY CONCAT(students.LastName, ' ', students.FirstName, ' ', students.SecondName) ASC, + students.ID ASC, + modules.Type = 'exam' ASC, + submodules.OrderNum ASC; +END // + + +# ------------------------------------------------------------------------------------------- +# Label: disciplines +# Label: roadMaps +# ------------------------------------------------------------------------------------------- + +# TODO: order hardcode +# get roadmap of discipline +DROP PROCEDURE IF EXISTS GetRoadmap// +CREATE PROCEDURE `GetRoadmap` + ( IN `pDisciplineID` INT) NO SQL BEGIN - DECLARE checker, UserID INT; - - - -- check for matching with existing accounts (note: Login & E-Mail are unique) - SET checker = -1; - SELECT accounts.ID - INTO checker - FROM `accounts` - WHERE accounts.Login = Login OR - accounts.EMail = EMail - LIMIT 1; - IF checker > 0 OR Password IS NULL THEN - RETURN -1; - END IF; - - -- check for existing of accounts with such Code - SET UserID = -1; - SELECT accounts.ID - INTO UserID - FROM `accounts` - WHERE accounts.ActivationCode = Code - LIMIT 1; - IF UserID <= 0 THEN - RETURN -2; - END IF; - - -- activate account - UPDATE `accounts` - SET accounts.Login = Login, - accounts.Password = Password, - accounts.EMail = EMail, - accounts.ActivationCode = NULL - WHERE accounts.ID = UserID - LIMIT 1; - RETURN UserID; -END // - - - -DROP FUNCTION IF EXISTS ChangePassword// -CREATE FUNCTION `ChangePassword` ( `UserID` INT, - `Password` VARCHAR(255) CHARSET utf8 - ) RETURNS int(11) + SELECT view_disciplines.SubjectID, + view_disciplines.SubjectName, + view_roadmap.ModuleID, + view_roadmap.ModuleName, + view_roadmap.ModuleType, + view_roadmap.SubmoduleID, + view_roadmap.SubmoduleName, + view_roadmap.SubmoduleRate AS 'MaxRate', + view_roadmap.SubmoduleType + FROM `view_roadmap` + INNER JOIN `view_disciplines` ON view_disciplines.DisciplineID = pDisciplineID + WHERE view_roadmap.DisciplineID = pDisciplineID AND + (view_roadmap.ModuleType != 'exam' OR view_roadmap.SubmoduleOrderNum = 1) + ORDER BY view_roadmap.ModuleType ^ 1 ASC, + # 1, 3, 2, 4 ASC + view_roadmap.ModuleOrderNum ASC, + view_roadmap.SubmoduleOrderNum ASC; +END // + + +# get roadmap of discipline exam +DROP PROCEDURE IF EXISTS GetRoadmapExam// +CREATE PROCEDURE `GetRoadmapExam` + ( IN `pDisciplineID` INT) NO SQL BEGIN - DECLARE checker INT; - - IF Password IS NULL THEN - RETURN -1; - END IF; + SELECT view_disciplines.SubjectID, + view_disciplines.SubjectName, + view_roadmap.ModuleID, + view_roadmap.ModuleName, + view_roadmap.ModuleType, + view_roadmap.SubmoduleID, + view_roadmap.SubmoduleName, + view_roadmap.SubmoduleRate AS 'MaxRate', + view_roadmap.SubmoduleType + FROM `view_roadmap` + INNER JOIN `view_disciplines` ON view_disciplines.DisciplineID = pDisciplineID + WHERE view_roadmap.DisciplineID = pDisciplineID AND + (view_roadmap.ModuleType = 'exam' OR view_roadmap.ModuleType = 'extra') + ORDER BY InternalOrderModuleTypesForSession(view_roadmap.ModuleType) ASC, + view_roadmap.ModuleOrderNum ASC, + view_roadmap.SubmoduleOrderNum ASC; +END // + + + + +# ------------------------------------------------------------------------------------------- +# Label: requests +# ------------------------------------------------------------------------------------------- + +# DROP PROCEDURE IF EXISTS GetRequests +# CREATE PROCEDURE `GetRequests` ( IN `AccountID` INT, +# IN `Type` INT # 0 to me, 1 - from me, 3 - all +# ) +# NO SQL +# BEGIN +# SELECT requests.ID, +# requests.To, +# requests.From, +# requests.Field1, +# requests.Field2, +# requests.Field3, +# requests.Data, +# requests.DataExt, +# requests.Date, +# requests.Type, +# requests.Status +# FROM `requests` +# WHERE ((Type & 1) != 0 AND requests.To = AccountID) OR +# ((Type & 2) != 0 AND requests.From = AccountID) +# ORDER BY requests.To = AccountID DESC, requests.Type ASC, requests.ID ASC; +# END + + + +# ------------------------------------------------------------------------------------------- +# Label: recovery +# ------------------------------------------------------------------------------------------- - -- check account with UserID - SET checker = -1; - SELECT accounts.ID - INTO checker - FROM `accounts` - WHERE accounts.ID = UserID - LIMIT 1; - IF checker <= 0 THEN - RETURN -1; - END IF; - - -- set new password - UPDATE `accounts` - SET accounts.Password = Password - WHERE accounts.ID = UserID - LIMIT 1; - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS ChangeLogin// -CREATE FUNCTION `ChangeLogin` ( `UserID` INT, - `Login` VARCHAR(50) CHARSET utf8 - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetRecoveryInfoByToken// +CREATE PROCEDURE `GetRecoveryInfoByToken` +(IN `pToken` VARCHAR(100) CHARSET utf8) NO SQL BEGIN - DECLARE checker INT; - - -- check for account with UserID - SET checker = -1; - SELECT accounts.ID - INTO checker - FROM `accounts` - WHERE accounts.ID = UserID - LIMIT 1; - IF checker <= 0 THEN - RETURN -1; - END IF; - - -- search accounts with Login (login must be unique) - SET checker = -1; - SELECT accounts.ID - INTO checker - FROM `accounts` - WHERE accounts.Login = Login - LIMIT 1; - IF checker > 0 THEN - RETURN -1; - END IF; - - - -- set new login - UPDATE `accounts` - SET accounts.Login = Login - WHERE accounts.ID = UserID - LIMIT 1; - RETURN 0; + SELECT recovery_tokens.ID, + recovery_tokens.AccountID, + recovery_tokens.Date, + recovery_tokens.Token, + recovery_tokens.IsUsed + FROM `recovery_tokens` + WHERE recovery_tokens.Token = pToken + LIMIT 1; END // -DROP FUNCTION IF EXISTS ChangeMail// -CREATE FUNCTION `ChangeMail` ( `UserID` INT, - `EMail` VARCHAR(50) CHARSET utf8 - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetRecoveryInfoByEMail// +CREATE PROCEDURE `GetRecoveryInfoByEMail` +(IN `pEMail` VARCHAR(255) CHARSET utf8) NO SQL BEGIN - DECLARE checker INT; - - -- check for account with UserID - SET checker = -1; - SELECT accounts.ID - INTO checker - FROM `accounts` - WHERE accounts.ID = UserID - LIMIT 1; - IF checker <= 0 THEN - RETURN -1; - END IF; - - -- search accounts with EMail (e-mail must be unique) - SET checker = -1; - SELECT accounts.ID - INTO checker - FROM `accounts` - WHERE accounts.EMail = EMail - LIMIT 1; - IF checker > 0 THEN - RETURN -1; - END IF; - - -- set new e-mail - UPDATE `accounts` - SET accounts.EMail = EMail - WHERE accounts.ID = UserID - LIMIT 1; - RETURN 0; + SELECT recovery_tokens.ID, + recovery_tokens.AccountID, + recovery_tokens.Date, + recovery_tokens.Token, + recovery_tokens.IsUsed + FROM `accounts` + INNER JOIN `recovery_tokens` ON recovery_tokens.AccountID = accounts.ID + WHERE accounts.EMail = pEMail AND + recovery_tokens.IsUsed = 0 + LIMIT 1; END // -DROP FUNCTION IF EXISTS SignIn// -CREATE FUNCTION `SignIn`( `LoginOrMail` VARCHAR(255) CHARSET utf8, - `Password` VARCHAR(64) CHARSET utf8 - ) RETURNS int(11) +# TODO: kill GetRateForDisc +DROP PROCEDURE IF EXISTS GetReports// +CREATE PROCEDURE `GetReports` (IN `pGroupID` INT) NO SQL -BEGIN - DECLARE curID INT; - - SET curID = -1; - SELECT accounts.ID - INTO curID - FROM `accounts` - WHERE accounts.Password = Password AND - ( accounts.Login = LoginOrMail OR - accounts.EMail = LoginOrMail ) - LIMIT 1; - IF curID <= 0 THEN - RETURN -1; - END IF; - - -- loging - INSERT INTO `logs_signin` - ( logs_signin.AccountID ) - VALUES ( curID ); - RETURN curID; +BEGIN + SELECT students.ID AS 'StudentID', + students.LastName, + students.FirstName, + students.SecondName, + disciplines.ID, + GetRateForDisc(students.ID, disciplines.ID) AS 'Rate', + GetMaxRateForDisc(disciplines.ID) AS 'MaxRate' + FROM `students` + LEFT JOIN `disciplines` ON disciplines.ID IN + ( + SELECT disciplines_groups.DisciplineID + FROM `disciplines_groups` + WHERE disciplines_groups.GroupID = pGroupID + UNION DISTINCT + SELECT disciplines_students.DisciplineID + FROM `disciplines_students` + INNER JOIN `students` ON disciplines_students.ID = students.ID + INNER JOIN `students_groups` ON students_groups.StudentID = students.ID AND + students_groups.SemesterID = @CurrentSemesterID + WHERE students_groups.GroupID = pGroupID + ) + INNER JOIN `subjects` ON disciplines.SubjectID = subjects.ID + INNER JOIN `students_groups` ON students_groups.StudentID = students.ID AND + students_groups.SemesterID = @CurrentSemesterID + WHERE students_groups.GroupID = pGroupID; END // - - --- ------------------------------------------------------------------------------------------- --- Label: teachers --- ------------------------------------------------------------------------------------------- - - -DROP FUNCTION IF EXISTS ChangeTeacherInfo// -CREATE FUNCTION `ChangeTeacherInfo` ( `TeacherID` INT, - `TeacherLast` VARCHAR(30) CHARSET utf8, - `TeacherFirst` VARCHAR(30) CHARSET utf8, - `TeacherSecond` VARCHAR(30) CHARSET utf8, - `JobPositionID` INT, - `DepartmentID` INT - ) RETURNS int(11) +DROP PROCEDURE IF EXISTS GetFinalFormInfo// +CREATE PROCEDURE `GetFinalFormInfo` +(IN `pDisciplineID` INT, IN `pGroupID` INT) NO SQL -BEGIN - DECLARE checker INT; - SET checker = -1; - - -- check existing of Teacher, jobPosition & Department - SELECT teachers.ID - INTO checker - FROM `teachers` - INNER JOIN `job_positions` ON JobPositionID = job_positions.ID - INNER JOIN `departments` ON DepartmentID = departments.ID - WHERE TeacherID = teachers.ID - LIMIT 1; - IF checker <= 0 OR - TeacherLast IS NULL OR - TeacherSecond IS NULL OR - TeacherSecond IS NULL - THEN - RETURN -1; - END IF; - - -- set new info - UPDATE `teachers` - SET teachers.LastName = TeacherLast, - teachers.FirstName = TeacherFirst, - teachers.SecondName = TeacherSecond, - teachers.JobPositionID = JobPositionID, - teachers.DepartmentID = DepartmentID - WHERE TeacherID = teachers.ID - LIMIT 1; - RETURN 0; +BEGIN + SELECT study_groups.GroupNum AS 'GroupNum', + study_groups.Name AS 'GroupName', + grades.ID AS 'GradeID', + grades.Num AS 'GradeNum', + grades.Degree AS 'Degree', + specializations.ID AS 'SpecID', + specializations.Name AS 'SpecName', + specializations.Abbr AS 'SpecAbbr', + specializations.Code AS 'SpecCode', + faculties.ID AS 'FacultyID', + faculties.Name AS 'FacultyName', + faculties.Abbr AS 'FacultyAbbr', + disciplines.ExamType AS 'ExamType', + subjects.ID AS 'SubjectID', + subjects.Name AS 'SubjectName', + subjects.Abbr AS 'SubjectAbbr', + teachers.ID AS 'AuthorID', + teachers.LastName AS 'LastName', + teachers.FirstName AS 'FirstName', + teachers.SecondName AS 'SecondName', + job_positions.Name AS 'JobPosition', + departments.ID AS 'DepID', + departments.Name AS 'DepName', + semesters.Year AS 'Year', + semesters.Num AS 'SemesterNum' + FROM `study_groups` + INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID + INNER JOIN `grades` ON study_groups.GradeID = grades.ID + INNER JOIN `faculties` ON faculties.ID = specializations.FacultyID + INNER JOIN `disciplines` ON disciplines.ID = pDisciplineID + INNER JOIN `subjects` ON disciplines.SubjectID = subjects.ID + INNER JOIN `teachers` ON teachers.ID = disciplines.AuthorID + INNER JOIN `departments` ON departments.ID = teachers.DepartmentID + INNER JOIN `job_positions` ON job_positions.ID = teachers.JobPositionID + INNER JOIN `semesters` ON semesters.ID = @CurrentSemesterID + WHERE study_groups.ID = pGroupID + LIMIT 1; END // - -DROP PROCEDURE IF EXISTS GetTeachersByFaculty// -CREATE PROCEDURE `GetTeachersByFaculty` ( IN `FacultyID` INT - ) - NO SQL -BEGIN - SELECT teachers.ID AS 'ID', - teachers.LastName AS 'Last', - teachers.FirstName AS 'First', - teachers.SecondName AS 'Second', - teachers.AccountID AS 'AccountID', - job_positions.Name AS 'JobPositionName', - departments.ID AS 'DepID', - departments.Name AS 'DepName' - FROM `teachers` - INNER JOIN `departments` ON departments.ID = teachers.DepartmentID AND - FacultyID = departments.FacultyID - INNER JOIN `job_positions` ON job_positions.ID = teachers.JobPositionID - ORDER BY teachers.LastName ASC, - teachers.FirstName ASC, - teachers.SecondName ASC; -END // - - --- CHANGE - -DROP PROCEDURE IF EXISTS GetTeachersByDepartment// -CREATE PROCEDURE `GetTeachersByDepartment` ( IN `DepartmentID` INT - ) - NO SQL -BEGIN - SELECT teachers.ID AS 'ID', - teachers.LastName AS 'Last', - teachers.FirstName AS 'First', - teachers.SecondName AS 'Second', - teachers.AccountID AS 'AccountID', - job_positions.Name AS 'JobPositionName', - departments.ID AS 'DepID', - departments.Name AS 'DepName' - FROM `teachers` - INNER JOIN `departments` ON teachers.DepartmentID = departments.ID AND - DepartmentID = departments.ID - INNER JOIN `job_positions` ON job_positions.ID = teachers.JobPositionID - ORDER BY teachers.LastName ASC, - teachers.FirstName ASC, - teachers.SecondName ASC; -END // - - -DROP FUNCTION IF EXISTS CreateTeacher// -CREATE FUNCTION `CreateTeacher`( `Last` VARCHAR(30) CHARSET utf8, - `First` VARCHAR(30) CHARSET utf8, - `Second` VARCHAR(30) CHARSET utf8, - `JobPositionID` INT, - `DepartmentID` INT, - `Code` VARCHAR(40) CHARSET utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE accID, checker, RoleID INT; - - IF Code IS NULL OR Last IS NULL OR First IS NULL THEN - RETURN -1; - END IF; - - -- check Department & jobPosition existing - SET checker = -1; - SELECT departments.ID - INTO checker - FROM `departments` - INNER JOIN `job_positions` ON job_positions.ID = JobPositionID - WHERE departments.ID = DepartmentID - LIMIT 1; - IF checker <= 0 THEN - RETURN -1; - END IF; - - -- search accounts with same Code - SET accID = -1; - SELECT accounts.ID - INTO accID - FROM `accounts` - WHERE accounts.ActivationCode = Code - LIMIT 1; - IF accID > 0 THEN - RETURN -2; - END IF; - - -- user role 2 - common teacher - -- add new account - INSERT INTO `accounts` - ( accounts.Login , accounts.Password , accounts.EMail, accounts.UserRoleID, accounts.ActivationCode ) - VALUES ( NULL, NULL, NULL, 2, Code); - - - -- get this account ID - SET accID = -1; - SELECT accounts.ID - INTO accID - FROM `accounts` - WHERE accounts.ActivationCode = Code - LIMIT 1; - IF accID <= 0 THEN - RETURN -3; - END IF; - - -- add new teacher - INSERT INTO `teachers` - ( teachers.AccountID, - teachers.LastName, - teachers.FirstName, - teachers.SecondName, - teachers.JobPositionID, - teachers.DepartmentID - ) - VALUES (accID, Last, First, Second, JobPositionID, DepartmentID); - RETURN 0; -END // - - --- TODO: deprecated - -DROP FUNCTION IF EXISTS `CreateTeacherByDepName`// -CREATE FUNCTION `CreateTeacherByDepName`( `Last` VARCHAR(30) CHARSET utf8, - `First` VARCHAR(30) CHARSET utf8, - `Second` VARCHAR(30) CHARSET utf8, - `DepartmentName` VARCHAR(200) CHARSET utf8, - `FacultyID` INT(11), - `Code` VARCHAR(40) CHARSET utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE curID, checker, RoleID, DepID INT; - - IF Code IS NULL OR Last IS NULL OR First IS NULL THEN - RETURN -1; - END IF; - - SET checker = -1; - SELECT departments.ID - INTO DepID - FROM `departments` - WHERE departments.Name = DepartmentName OR - (DepartmentName = '' AND departments.Name IS NULL) - LIMIT 1; - IF DepID <= 0 OR DepID IS NULL THEN - INSERT INTO `departments` (Name, FacultyID) - VALUES (DepartmentName, FacultyID); - - SELECT departments.ID - INTO DepID - FROM `departments` - WHERE departments.Name = DepartmentName OR - (DepartmentName = '' AND departments.Name IS NULL) - LIMIT 1; - END IF; - - SET checker = -1; - SELECT job_positions.ID - INTO checker - FROM `job_positions` - WHERE job_positions.ID = 12 - LIMIT 1; - IF checker <= 0 THEN - RETURN -1; - END IF; - - SET curID = -1; - SELECT accounts.ID - INTO curID - FROM `accounts` - WHERE accounts.ActivationCode = Code - LIMIT 1; - IF curID > 0 THEN - RETURN -2; - END IF; - - -- TODO: user roles - INSERT INTO `accounts` - ( accounts.Login , accounts.Password , accounts.EMail, accounts.UserRoleID, accounts.ActivationCode ) - VALUES ( NULL, NULL, NULL, 2, Code); - - SET curID = -1; - SELECT accounts.ID - INTO curID - FROM `accounts` - WHERE accounts.ActivationCode = Code - LIMIT 1; - IF curID <= 0 THEN - RETURN -3; - END IF; - - INSERT INTO `teachers` - ( teachers.AccountID, - teachers.LastName, - teachers.FirstName, - teachers.SecondName, - teachers.JobPositionID, - teachers.DepartmentID - ) - VALUES (curID, Last, First, Second, 12, DepID); - RETURN 0; -END // - - - -DROP PROCEDURE IF EXISTS GetTeachersForDiscipline// -CREATE PROCEDURE `GetTeachersForDiscipline`(IN `DisciplineID` INT) - NO SQL -BEGIN - - SELECT teachers.ID AS 'ID', - teachers.LastName AS 'Last', - teachers.FirstName AS 'First', - teachers.SecondName AS 'Second', - job_positions.ID AS 'JobPositionID', - job_positions.Name AS 'JobPositionName', - departments.ID AS 'DepID', - departments.Name AS 'DepName', - faculties.ID AS 'FacultyID', - faculties.Name AS 'FacultyName', - faculties.Abbr AS 'FacultyAbbr', - (teachers.ID = disciplines.AuthorID) AS 'isAuthor' - FROM `disciplines_teachers` - INNER JOIN `disciplines` ON disciplines.ID = disciplines_teachers.DisciplineID - INNER JOIN `teachers` ON teachers.ID = disciplines_teachers.TeacherID - INNER JOIN `departments` ON departments.ID = teachers.DepartmentID - INNER JOIN `faculties` ON departments.FacultyID = faculties.ID - INNER JOIN `job_positions` ON job_positions.ID = teachers.JobPositionID - WHERE disciplines_teachers.DisciplineID = DisciplineID - ORDER BY isAuthor DESC, teachers.LastName ASC; -END // - - - --- TODO: rename -DROP PROCEDURE IF EXISTS SearchTeachers// -CREATE PROCEDURE `SearchTeachers` ( IN `FacultyID` INT, - IN `DepartmentID` INT, - IN `Name` VARCHAR(100) CHARSET utf8, - IN `DisciplineID` INT - ) - NO SQL -BEGIN - SELECT teachers.ID AS 'ID', - teachers.LastName AS 'Last', - teachers.FirstName AS 'First', - teachers.SecondName AS 'Second', - teachers.AccountID AS 'AccountID', - job_positions.Name AS 'JobPositionName', - departments.ID AS 'DepID', - departments.Name AS 'DepName' - FROM `teachers` - INNER JOIN `departments` ON teachers.DepartmentID = departments.ID AND - ( DepartmentID = 0 OR DepartmentID = departments.ID ) AND - ( FacultyID = 0 OR FacultyID = departments.FacultyID ) - INNER JOIN `job_positions` ON teachers.JobPositionID = job_positions.ID - WHERE NOT InternalIsTeacherBinded(teachers.ID, DisciplineID) AND - CONCAT(teachers.LastName, teachers.FirstName, teachers.SecondName) LIKE CONCAT("%",Name,"%") - ORDER BY departments.FacultyID ASC, - departments.Name ASC, - teachers.LastName ASC, - teachers.FirstName ASC, - teachers.SecondName ASC; -END // - - --- ------------------------------------------------------------------------------------------- --- Label: students --- ------------------------------------------------------------------------------------------- - -DROP PROCEDURE IF EXISTS GetStudentsByStudyGroups// -DROP PROCEDURE IF EXISTS GetStudents// -CREATE PROCEDURE `GetStudents` ( IN `StudyGroupID` INT - ) - NO SQL -BEGIN - SELECT students.ID AS 'ID', - students.LastName AS 'Last', - students.FirstName AS 'First', - students.SecondName AS 'Second', - students.AccountID AS 'AccountID', - grades.ID AS 'GradeID', - grades.Num AS 'GradeNum', - grades.Degree AS 'Degree', - study_groups.ID AS 'GroupID', - study_groups.GroupNum AS 'GroupNum' - FROM `students` - INNER JOIN `study_groups` ON students.StudyGroupID = study_groups.ID AND - StudyGroupID = study_groups.ID - INNER JOIN `grades` ON study_groups.GradeID = grades.ID - ORDER BY students.LastName ASC, - students.FirstName ASC, - students.SecondName ASC; -END // - - - - -DROP PROCEDURE IF EXISTS GetStudentsByFaculty// -CREATE PROCEDURE `GetStudentsByFaculty` ( IN `FacultyID` INT, - IN `GradeID` INT, - IN `GroupID` INT ) - NO SQL -BEGIN - SELECT students.ID AS 'ID', - students.LastName AS 'Last', - students.FirstName AS 'First', - students.SecondName AS 'Second', - students.AccountID AS 'AccountID', - grades.ID AS 'GradeID', - grades.Num AS 'GradeNum', - study_groups.ID AS 'GroupID', - study_groups.GroupNum AS 'GroupNum', - grades.Degree AS 'Degree' - FROM `students` - INNER JOIN `study_groups` ON study_groups.ID = students.StudyGroupID AND - (GroupID = students.StudyGroupID OR GroupID = 0) - INNER JOIN `grades` ON study_groups.GradeID = grades.ID AND - (GradeID = grades.ID OR GradeID = 0) - INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID AND - FacultyID = specializations.FacultyID - ORDER BY students.LastName ASC, - students.FirstName ASC, - students.SecondName ASC; -END // - - - - -DROP PROCEDURE IF EXISTS GetStudentsByGradeID// -CREATE PROCEDURE `GetStudentsByGradeID` ( IN `GradeID` INT, - IN `FacultyID` INT ) - NO SQL -BEGIN - SELECT DISTINCT students.ID AS 'StudentID', - students.LastName As 'StudentLast', - students.FirstName AS 'StudentFirst', - students.SecondName AS 'StudentSecond', - students.AccountID AS 'StudentAccID', - study_groups.ID AS 'GroupID', - grades.ID AS 'GradeID', - grades.Num AS 'GroupGrade', - grades.Degree AS 'GroupDegree', - study_groups.GroupNum AS 'GroupNum', - disciplines_students.Type AS 'Type' - FROM `students` - INNER JOIN `study_groups` ON students.StudyGroupID = study_groups.ID AND - GradeID = study_groups.GradeID - INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID AND - FacultyID = specializations.FacultyID - INNER JOIN `grades` ON study_groups.GradeID = grades.ID - ORDER BY students.LastName ASC, - students.FirstName ASC, - students.SecondName ASC; -END // - - - -DROP FUNCTION IF EXISTS CreateStudent// -CREATE FUNCTION `CreateStudent`( `Last` VARCHAR(30) CHARSET utf8, - `First` VARCHAR(30) CHARSET utf8, - `Second` VARCHAR(30) CHARSET utf8, - `GradeID` INT, - `GroupN` INT, - `FacultyID` INT, - `Code` VARCHAR(40) CHARSET utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE accID, StudyGroupID INT; - - IF Code IS NULL OR Last IS NULL OR First IS NULL THEN - RETURN -1; - END IF; - - -- find studygroup - SET StudyGroupID = -1; - SELECT study_groups.ID - INTO StudyGroupID - FROM `study_groups` - INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID AND - FacultyID = specializations.FacultyID - WHERE study_groups.GradeID = GradeID AND - study_groups.ID = GroupN - LIMIT 1; - IF StudyGroupID <= 0 THEN - RETURN -1; - END IF; - - - -- try to find account with same activation code - SET accID = -1; - SELECT accounts.ID - INTO accID - FROM `accounts` - WHERE accounts.ActivationCode = Code - LIMIT 1; - IF accID > 0 THEN - RETURN -2; - END IF; - - -- create new account - INSERT INTO `accounts` - ( accounts.Login , accounts.Password , accounts.EMail, accounts.UserRoleID, accounts.ActivationCode ) - VALUES ( NULL, NULL, NULL, 1, Code); - - - -- get created account ID - SET accID = -1; - SELECT accounts.ID - INTO accID - FROM `accounts` - WHERE accounts.ActivationCode = Code - LIMIT 1; - IF accID <= 0 THEN - RETURN -3; - END IF; - - - -- create student - INSERT INTO `students` - (students.StudyGroupID, students.AccountID, students.LastName, students.FirstName, students.SecondName) - VALUES (StudyGroupID, accID, Last, First, Second); - RETURN 0; -END // - - --- TODO: ?#$@! magic -DROP FUNCTION IF EXISTS CreateStudentEx// -CREATE FUNCTION `CreateStudentEx`( `Last` VARCHAR(30) CHARSET utf8, - `First` VARCHAR(30) CHARSET utf8, - `Second` VARCHAR(30) CHARSET utf8, - `GradeNum` INT, - `groupNum` INT, - `Degree` VARCHAR(20) CHARSET utf8, - `SpecName` VARCHAR(50) CHARSET utf8, - `FacultyID` INT, - `Code` VARCHAR(40) CHARSET utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE curID, gradeID, specID, SG_ID INT; - - IF Code IS NULL OR Last IS NULL OR First IS NULL THEN - RETURN -1; - END IF; - - SET gradeID = -1; - SELECT grades.ID - INTO gradeID - FROM `grades` - WHERE grades.Num = GradeNum AND - grades.Degree = Degree - LIMIT 1; - IF gradeID <= 0 THEN - INSERT INTO `grades` - (grades.Num, grades.Degree) - VALUES (GradeNum, Degree); - - SET gradeID = -1; - SELECT grades.ID - INTO gradeID - FROM `grades` - WHERE grades.Num = GradeNum AND - grades.Degree = Degree - LIMIT 1; - END IF; - - - SET SG_ID = -1; - SELECT study_groups.ID - INTO SG_ID - FROM `study_groups` - INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID - WHERE study_groups.GroupNum = groupNum AND - study_groups.GradeID = gradeID AND - specializations.FacultyID = FacultyID - LIMIT 1; - IF SG_ID <= 0 THEN - SET specID = -1; - SELECT specializations.ID - INTO specID - FROM `specializations` - WHERE ( specializations.Name = SpecName OR - ( SpecName = '' AND specializations.Name IS NULL ) - ) AND - specializations.FacultyID = FacultyID - LIMIT 1; - IF specID <= 0 THEN - INSERT INTO `specializations` - (specializations.Name, specializations.Abbr, specializations.FacultyID ) - VALUES (SpecName, NULL, FacultyID); - - SET specID = -1; - SELECT specializations.ID - INTO specID - FROM `specializations` - WHERE specializations.Name = SpecName AND - specializations.FacultyID = FacultyID - LIMIT 1; - END IF; - - INSERT INTO `study_groups` - (study_groups.GradeID, study_groups.GroupNum, study_groups.SpecializationID) - VALUES (gradeID, groupNum, specID); - - SET SG_ID = -1; - SELECT study_groups.ID - INTO SG_ID - FROM `study_groups` - INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID - WHERE study_groups.GroupNum = groupNum AND - study_groups.GradeID = gradeID AND - specializations.FacultyID = FacultyID - LIMIT 1; - IF SG_ID <= 0 THEN - RETURN -1; - END IF; - END IF; - - SET curID = -1; - SELECT accounts.ID - INTO curID - FROM `accounts` - WHERE accounts.ActivationCode = Code - LIMIT 1; - IF curID > 0 THEN - RETURN -2; - END IF; - - -- TODO: user roles - INSERT INTO `accounts` - ( accounts.Login , accounts.Password , accounts.EMail, accounts.UserRoleID, accounts.ActivationCode ) - VALUES ( NULL, NULL, NULL, 1, Code); - - SET curID = -1; - SELECT accounts.ID - INTO curID - FROM `accounts` - WHERE accounts.ActivationCode = Code - LIMIT 1; - IF curID <= 0 THEN - RETURN -3; - END IF; - - INSERT INTO `students` - (students.StudyGroupID, students.AccountID, students.LastName, students.FirstName, students.SecondName) - VALUES (SG_ID, curID, Last, First, Second); - RETURN 0; -END // - - - --- DROP PROCEDURE IF EXISTS SearchStudents// --- CREATE PROCEDURE `SearchStudents` ( IN `GradeID` INT, --- IN `GroupN` INT, --- IN `FacultyID` INT, --- IN `Name` VARCHAR(100) CHARSET utf8 --- ) --- NO SQL --- BEGIN --- SELECT students.ID AS 'ID', --- students.LastName AS 'Last', --- students.FirstName AS 'First', --- students.SecondName AS 'Second', --- grades.ID AS 'GradeID', --- grades.Num AS 'GradeNum', --- grades.Degree AS 'Degree', --- study_groups.ID AS 'GroupID', --- study_groups.GroupNum AS 'GroupNum' --- FROM `students` --- INNER JOIN `study_groups` ON students.StudyGroupID = study_groups.ID AND --- GradeID = study_groups.GradeID AND --- ( GroupN = 0 OR GroupN = study_groups.GroupNum ) --- INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID --- INNER JOIN `grades` ON study_groups.GradeID = grades.ID --- WHERE FacultyID = specializations.FacultyID AND --- CONCAT(students.LastName, students.FirstName, students.SecondName) LIKE CONCAT("%",Name,"%") --- ORDER BY grades.ID ASC, study_groups.GroupNum ASC; --- END // - - - -DROP PROCEDURE IF EXISTS SearchStudents// -CREATE PROCEDURE `SearchStudents` ( IN `GradeID` INT, - IN `StudyGroupID` INT, - IN `FacultyID` INT, - IN `Name` VARCHAR(100) CHARSET utf8, - IN `DisciplineID` INT - ) - NO SQL -BEGIN - SELECT students.ID AS 'ID', - students.LastName AS 'Last', - students.FirstName AS 'First', - students.SecondName AS 'Second', - grades.ID AS 'GradeID', - grades.Num AS 'GradeNum', - grades.Degree AS 'Degree', - study_groups.ID AS 'GroupID', - study_groups.GroupNum AS 'GroupNum' - FROM `students` - INNER JOIN `study_groups` ON students.StudyGroupID = study_groups.ID AND - GradeID = study_groups.GradeID AND - ( StudyGroupID = 0 OR StudyGroupID = study_groups.ID ) - INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID AND - FacultyID = specializations.FacultyID - INNER JOIN `grades` ON study_groups.GradeID = grades.ID - LEFT JOIN `disciplines_groups` ON study_groups.ID = disciplines_groups.StudyGroupID AND - DisciplineID = disciplines_groups.DisciplineID - WHERE CONCAT(students.LastName, students.FirstName, students.SecondName) LIKE CONCAT("%",Name,"%") AND - NOT InternalIsStudentAttached(students.ID, DisciplineID) AND - disciplines_groups.ID IS NULL - ORDER BY grades.ID ASC, - study_groups.GroupNum ASC; -END // - - - -DROP PROCEDURE IF EXISTS GetStudentsForDiscipline// -CREATE PROCEDURE `GetStudentsForDiscipline` ( IN `TeacherID` INT, - IN `DisciplineID` INT - ) - NO SQL -BEGIN - IF NOT InternalIsTeacherBinded(TeacherID, DisciplineID) - THEN - SELECT NULL AS 'ID' - LIMIT 0; - - ELSE - SELECT DISTINCT students.ID AS 'ID', - students.LastName AS 'Last', - students.FirstName AS 'First', - students.SecondName AS 'Second', - grades.ID AS 'GradeID', - grades.Num AS 'GradeNum', - grades.Degree AS 'Degree', - study_groups.ID AS 'GroupID', - study_groups.GroupNum AS 'GroupNum', - disciplines_students.Type AS 'Type' - FROM `students` - INNER JOIN `study_groups` ON students.StudyGroupID = study_groups.ID - INNER JOIN `grades` ON grades.ID = study_groups.GradeID - LEFT JOIN `disciplines_students` ON DisciplineID = disciplines_students.DisciplineID AND - students.ID = disciplines_students.StudentID - LEFT JOIN `disciplines_groups` ON DisciplineID = disciplines_groups.DisciplineID AND - study_groups.ID = disciplines_groups.StudyGroupID - INNER JOIN `disciplines` ON DisciplineID = disciplines.ID - WHERE disciplines_groups.ID IS NOT NULL OR - disciplines_students.ID IS NOT NULL - ORDER BY grades.ID = disciplines.GradeID DESC, - grades.ID ASC, - study_groups.GroupNum ASC, - students.LastName ASC, - students.FirstName ASC, - students.SecondName ASC; - END IF; -END // - - - -DROP PROCEDURE IF EXISTS GetStudentsForRating// -CREATE PROCEDURE `GetStudentsForRating` ( IN `TeacherID` INT, - IN `DisciplineID` INT - ) - NO SQL -BEGIN - IF NOT InternalIsTeacherBinded(TeacherID, DisciplineID) - THEN - SELECT NULL AS 'ID' - LIMIT 0; - ELSE - SELECT DISTINCT students.ID AS 'ID', - students.LastName AS 'Last', - students.FirstName AS 'First', - students.SecondName AS 'Second', - grades.ID AS 'GradeID', - grades.Num AS 'GradeNum', - grades.Degree AS 'Degree', - study_groups.ID AS 'GroupID', - study_groups.GroupNum AS 'GroupNum', - (disciplines_students.Type IS NOT NULL AND disciplines_students.Type = 'attach') AS 'isAttached' - FROM `students` - INNER JOIN `study_groups` ON students.StudyGroupID = study_groups.ID - INNER JOIN `grades` ON grades.ID = study_groups.GradeID - LEFT JOIN `disciplines_students` ON DisciplineID = disciplines_students.DisciplineID AND - students.ID = disciplines_students.StudentID - WHERE InternalIsStudentAttached(students.ID, DisciplineID) - ORDER BY grades.ID ASC, - study_groups.GroupNum ASC, - students.LastName ASC, - students.FirstName ASC, - students.SecondName ASC; - END IF; -END // - - - - - - - --- ------------------------------------------------------------------------------------------- --- Label: disciplines --- ------------------------------------------------------------------------------------------- - - -DROP PROCEDURE IF EXISTS GetDisciplines// -CREATE PROCEDURE `GetDisciplines` ( IN `FacultyID` INT ) - NO SQL -BEGIN - SELECT disciplines.ID AS 'ID', - subjects.ID AS 'SubjectID', - subjects.Name AS 'SubjectName', - disciplines.ExamType AS 'ExamType', - departments.Name AS 'DepName', - InternalIsMapCreated(disciplines.ID) AS 'isMapCreated' - FROM `disciplines` - INNER JOIN `subjects` ON disciplines.SubjectID = subjects.ID - INNER JOIN `teachers` ON disciplines.AuthorID = teachers.ID - INNER JOIN `departments` ON teachers.DepartmentID = departments.ID - WHERE @CurrentSemesterID = disciplines.SemesterID AND - disciplines.FacultyID = FacultyID - ORDER BY departments.Name ASC; -END // - - --- TODO bad query -DROP PROCEDURE IF EXISTS GetDisciplinesForTeacher// -CREATE PROCEDURE `GetDisciplinesForTeacher`(IN `TeacherID` INT) - NO SQL -BEGIN - SELECT DISTINCT disciplines.ID AS 'ID', - disciplines.ExamType AS 'ExamType', - disciplines.GradeID AS 'GradeID', - grades.Num AS 'GradeNum', - grades.Degree AS 'Degree', - study_groups.ID AS 'GroupID', - study_groups.GroupNum AS 'GroupNum', - study_groups.Name AS 'GroupName', - subjects.ID AS 'SubjectID', - subjects.Name AS 'SubjectName', - (TeacherID = disciplines.AuthorID) AS 'isAuthor', - InternalIsMapCreated(disciplines.ID) AS 'isMapCreated', - disciplines.isLocked AS 'isLocked' - FROM `disciplines_groups` - RIGHT JOIN `disciplines` ON disciplines_groups.DisciplineID = disciplines.ID OR - disciplines_groups.DisciplineID IS NULL - INNER JOIN `grades` ON grades.ID = disciplines.GradeID - INNER JOIN `disciplines_teachers` ON disciplines.ID = disciplines_teachers.DisciplineID AND - TeacherID = disciplines_teachers.TeacherID - INNER JOIN `subjects` ON subjects.ID = disciplines.SubjectID - LEFT JOIN `study_groups` ON study_groups.ID = disciplines_groups.StudyGroupID - WHERE disciplines.SemesterID = @CurrentSemesterID - ORDER BY grades.ID ASC, - subjects.Name ASC, - disciplines.ID ASC, - study_groups.GroupNum ASC; -END // - - - -DROP PROCEDURE IF EXISTS GetDisciplinesForStudent// -CREATE PROCEDURE `GetDisciplinesForStudent`(IN `StudentID` INT) - NO SQL -BEGIN - SELECT disciplines.ID AS 'ID', - subjects.ID AS 'SubjectID', - subjects.Name AS 'SubjectName', - disciplines.ExamType AS 'ExamType', - teachers.LastName AS 'Last', - teachers.FirstName AS 'First', - teachers.SecondName AS 'Second', - GetRateForDisc(StudentID, disciplines.ID ) AS 'Rate', - GetMaxRateForDisc(disciplines.ID ) AS 'MaxCurrentRate', - InternalIsMapCreated(disciplines.ID) AS 'isMapCreated' - FROM `disciplines` - INNER JOIN `subjects` ON disciplines.SubjectID = subjects.ID - INNER JOIN `teachers` ON disciplines.AuthorID = teachers.ID - WHERE @CurrentSemesterID = disciplines.SemesterID AND - InternalIsStudentAttached(StudentID, disciplines.ID) - ORDER BY disciplines.ExamType ASC, Rate DESC; -END // - - - -DROP PROCEDURE IF EXISTS GetMapForStudent// -CREATE PROCEDURE `GetMapForStudent` ( IN `StudentID` INT, - IN `DisciplineID` INT - ) - NO SQL -BEGIN - SELECT modules.ID AS 'ModuleID', - modules.Name AS 'ModuleName', - submodules.ID AS 'SubmoduleID', - submodules.Name AS 'SubModuleName', - submodules.Description AS 'SubmoduleDescription', - submodules.MaxRate, - submodules.Type AS 'SubmoduleControl', - rating_table.Rate, - rating_table.Date, - modules.Type AS 'ModuleType' - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID AND - DisciplineID = modules.DisciplineID - LEFT JOIN `rating_table` ON submodules.ID = rating_table.SubmoduleID AND - StudentID = rating_table.StudentID - - - WHERE modules.Type != 2 OR - submodules.ID = - ( @tmp = (SELECT submodules.ID - FROM `submodules` - INNER JOIN `rating_table` ON rating_table.SubModuleID = submodules.ID - WHERE submodules.ModuleID = modules.ID AND - rating_table.StudentID = StudentID - ORDER BY submodules.OrderNum DESC - LIMIT 1) - ) OR - (@tmp IS NULL AND submodules.OrderNum = 1) - ORDER BY modules.Type ^ 1 ASC, - -- 1, 3, 2, 4 ASC - modules.OrderNum ASC, - submodules.OrderNum ASC; -END // - - -DROP PROCEDURE IF EXISTS GetMapForStudentExam// -CREATE PROCEDURE `GetMapForStudentExam` ( IN `StudentID` INT, - IN `DisciplineID` INT - ) - NO SQL -BEGIN - SELECT modules.ID AS 'ModuleID', - modules.Name AS 'ModuleName', - submodules.ID AS 'SubmoduleID', - submodules.Name AS 'SubModuleName', - submodules.Description AS 'SubmoduleDescription', - submodules.MaxRate, - submodules.Type AS 'SubmoduleControl', - rating_table.Rate, - rating_table.Date, - modules.Type AS 'ModuleType' - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID AND - DisciplineID = modules.DisciplineID - LEFT JOIN `rating_table` ON submodules.ID = rating_table.SubmoduleID AND - StudentID = rating_table.StudentID - ORDER BY OrderModuleTypesForSession(modules.Type) ASC, - submodules.OrderNum ASC; -END // - -DROP FUNCTION IF EXISTS OrderModuleTypesForSession// -CREATE FUNCTION `OrderModuleTypesForSession` (`ModuleType` INT - ) RETURNS INT(3) - NO SQL -BEGIN - DECLARE Res INT; - SET Res = 0; - IF ModuleType = 4 THEN SET Res = 1; # extra - ELSEIF ModuleType = 2 THEN SET Res = 2; # exam - ELSEIF ModuleType = 3 THEN SET Res = 3; # bonus - ELSE SET Res = 4; # regular - END IF; - - RETURN Res; -END // - - - -DROP PROCEDURE IF EXISTS GetMapForDiscipline// -CREATE PROCEDURE `GetMapForDiscipline` ( IN `TeacherID` INT, - IN `DisciplineID` INT - ) - NO SQL -BEGIN - IF NOT InternalIsTeacherBinded(TeacherID, DisciplineID) - THEN - SELECT NULL AS 'ID' - LIMIT 0; - ELSE - SELECT subjects.ID AS 'SubjectID', - subjects.Name AS 'SubjectName', - modules.ID AS 'ModuleID', - modules.Name AS 'ModuleName', - modules.Type AS 'ModuleType', - submodules.ID AS 'SubmoduleID', - submodules.Name AS 'SubModuleName', - submodules.Description AS 'SubmoduleDescription', - submodules.MaxRate, - submodules.Type AS 'SubmoduleControl' - FROM `modules` - LEFT JOIN `submodules` ON modules.ID = submodules.ModuleID - INNER JOIN `disciplines` ON modules.DisciplineID = disciplines.ID - INNER JOIN `subjects` ON disciplines.SubjectID = subjects.ID - WHERE modules.DisciplineID = DisciplineID AND - (modules.Type != 2 OR submodules.OrderNum = 1) - ORDER BY modules.Type ^ 1 ASC, - -- 1, 3, 2, 4 ASC - modules.OrderNum ASC, - submodules.OrderNum ASC; - END IF; -END // - - -DROP PROCEDURE IF EXISTS GetMapForDisciplineExam// -CREATE PROCEDURE `GetMapForDisciplineExam` ( IN `TeacherID` INT, - IN `DisciplineID` INT - ) - NO SQL -BEGIN - IF NOT InternalIsTeacherBinded(TeacherID, DisciplineID) - THEN - SELECT NULL AS 'ID' - LIMIT 0; - ELSE - SELECT subjects.ID AS 'SubjectID', - subjects.Name AS 'SubjectName', - modules.ID AS 'ModuleID', - modules.Name AS 'ModuleName', - modules.Type AS 'ModuleType', - submodules.ID AS 'SubmoduleID', - submodules.Name AS 'SubModuleName', - submodules.Description AS 'SubmoduleDescription', - submodules.MaxRate, - submodules.Type AS 'SubmoduleControl' - FROM `modules` - LEFT JOIN `submodules` ON modules.ID = submodules.ModuleID - INNER JOIN `disciplines` ON modules.DisciplineID = disciplines.ID - INNER JOIN `subjects` ON disciplines.SubjectID = subjects.ID - WHERE modules.DisciplineID = DisciplineID AND - (modules.Type = 4 OR modules.Type = 2) - ORDER BY OrderModuleTypesForSession(modules.Type) ASC, - submodules.OrderNum ASC; - END IF; -END // - - - -DROP PROCEDURE IF EXISTS GetDisciplineInfoByID// -CREATE PROCEDURE `GetDisciplineInfoByID`( IN `DiscID` INT ) - NO SQL -BEGIN - SELECT disciplines.AuthorID, - disciplines.GradeID AS 'GradeID', - grades.Num AS 'GradeNum', - grades.Degree AS 'Degree', - disciplines.ExamType, - disciplines.LectionCount, - disciplines.PracticeCount, - disciplines.LabCount, - disciplines.SemesterID, - subjects.ID AS 'SubjectID', - subjects.Name AS 'SubjectName', - subjects.Abbr AS 'SubjectAbbr', - departments.ID AS 'DepID', - departments.Name AS 'DepName', - faculties.ID AS 'FacultyID', - faculties.Name AS 'FacultyName', - disciplines.isLocked AS 'isLocked', - (modules.ID IS NOT NULL) AS 'isBonus', - disciplines.isMilestone - FROM `disciplines` - INNER JOIN `subjects` ON subjects.ID = disciplines.SubjectID - INNER JOIN `faculties` ON faculties.ID = disciplines.FacultyID - INNER JOIN `teachers` ON disciplines.AuthorID = teachers.ID - INNER JOIN `departments` ON departments.ID = teachers.DepartmentID - INNER JOIN `grades` ON grades.ID = disciplines.GradeID - LEFT JOIN `modules` ON modules.DisciplineID = disciplines.ID AND - modules.Type = 3 - WHERE disciplines.ID = DiscID; -END // - - - - - - -DROP FUNCTION IF EXISTS AddDiscipline// -CREATE FUNCTION `AddDiscipline` ( `TeacherID` INT, - `GradeID` INT, - `SubjectID` INT, - `ExamType` VARCHAR(30) charset utf8, - `LectionCount` INT, - `PracticeCount` INT, - `LabCount` INT, - `FacultyID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, DisciplineID INT; - - SET checker = -1; - SELECT grades.ID - INTO checker - FROM `grades` - INNER JOIN `faculties` ON FacultyID = faculties.ID - INNER JOIN `subjects` ON SubjectID = subjects.ID - INNER JOIN `teachers` ON TeacherID = teachers.ID - WHERE GradeID = grades.ID - LIMIT 1; - IF checker <= 0 OR - ( ExamType != 'exam' AND ExamType != 'credit') - THEN - RETURN -1; - END IF; - - INSERT INTO `disciplines` - ( disciplines.AuthorID, - disciplines.GradeID, - disciplines.SubjectID, - disciplines.ExamType, - disciplines.LectionCount, - disciplines.PracticeCount, - disciplines.LabCount, - disciplines.SemesterID, - disciplines.FacultyID - ) - VALUES ( TeacherID, GradeID, SubjectID, ExamType, LectionCount, PracticeCount, LabCount, @CurrentSemesterID, FacultyID ); - - SET DisciplineID = LAST_INSERT_ID(); - INSERT INTO `disciplines_teachers` - ( disciplines_teachers.DisciplineID, - disciplines_teachers.TeacherID - ) - VALUES ( DisciplineID, TeacherID ); - - IF ExamType = 'exam' THEN - SET checker = AddModuleExam(TeacherID, DisciplineID); - END IF; - SET checker = AddModuleExtra(TeacherID, DisciplineID); - RETURN DisciplineID; -END // - - - -DROP FUNCTION IF EXISTS ChangeDisciplineSubject// -CREATE FUNCTION `ChangeDisciplineSubject` ( `TeacherID` INT, - `DisciplineID` INT, - `SubjectID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker INT; - - IF NOT InternalIsTeacherAuthor(TeacherID, DisciplineID) OR - InternalIsMapLocked(DisciplineID) - THEN - RETURN -1; - END IF; - - SET checker = -1; - SELECT subjects.ID - INTO checker - FROM `subjects` - WHERE subjects.ID = SubjectID - LIMIT 1; - IF checker <= 0 THEN - RETURN -1; - END IF; - - UPDATE `disciplines` - SET disciplines.SubjectID = SubjectID - WHERE disciplines.ID = DisciplineID - LIMIT 1; - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS ChangeDisciplineGrade// -CREATE FUNCTION `ChangeDisciplineGrade` ( `TeacherID` INT, - `DisciplineID` INT, - `GradeID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker INT; - - SET checker = -1; - SELECT grades.ID - INTO checker - FROM `grades` - WHERE grades.ID = GradeID - LIMIT 1; - IF checker <= 0 OR - InternalIsMapLocked(DisciplineID) OR - NOT InternalIsTeacherAuthor(TeacherID, DisciplineID) - THEN - RETURN -1; - END IF; - - SELECT disciplines.GradeID - INTO checker - FROM `disciplines` - WHERE disciplines.ID = DisciplineID - LIMIT 1; - - IF checker != GradeID THEN - DELETE FROM `disciplines_groups` - WHERE disciplines_groups.DisciplineID = DisciplineID; - - DELETE FROM `disciplines_students` - WHERE disciplines_students.DisciplineID = DisciplineID; - END IF; - - - UPDATE `disciplines` - SET disciplines.GradeID = GradeID - WHERE disciplines.ID = DisciplineID - LIMIT 1; - RETURN 0; -END // - - -DROP FUNCTION IF EXISTS ChangeDisciplineControl// -CREATE FUNCTION `ChangeDisciplineControl` ( `TeacherID` INT, - `DisciplineID` INT, - `ExamType` VARCHAR(30) charset utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, extraMax, vExtraID INT; - - IF InternalIsMapLocked(DisciplineID) OR - NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) - THEN - RETURN -1; - END IF; - - SET checker = -1; - SELECT disciplines.ExamType - INTO checker - FROM `disciplines` - WHERE disciplines.ID = DisciplineID - LIMIT 1; - - -- get Extra module id - SET vExtraID = -1; - SELECT modules.ID - INTO vExtraID - FROM `modules` - WHERE modules.Type = 4 AND - modules.DisciplineID = DisciplineID - LIMIT 1; - IF vExtraID <= 0 THEN - RETURN -1; - END IF; - - - IF (checker != ExamType) - THEN - IF ExamType = 'exam' THEN - - SET extraMax = 7; - - SET checker = GetDisciplineMaxRate(DisciplineID); - IF checker >= 61 THEN - RETURN 1; - END IF; - SET checker = AddModuleExam(TeacherID, DisciplineID); - - -- delete extra module from - DELETE FROM `submodules` - WHERE submodules.OrderNum > 1 AND - submodules.ModuleID = vExtraID; - - ELSE - SET extraMax = 29; - - SET checker = DeleteModuleExam(TeacherID, DisciplineID); - SET checker = AddSubmodule(TeacherID, vExtraID, extraMax, '', NULL, 'LandmarkControl'); - - END IF; - - UPDATE `disciplines` - SET disciplines.ExamType = ExamType - WHERE DisciplineID = disciplines.ID; - - UPDATE `submodules` - SET submodules.MaxRate = extraMax - WHERE submodules.ModuleID = vExtraID; - END IF; - RETURN 0; -END // - -DROP FUNCTION IF EXISTS ChangeDisciplineHours// -CREATE FUNCTION `ChangeDisciplineHours` ( `TeacherID` INT, - `DisciplineID` INT, - `Hours` INT, - `Type` INT - -- Type: 0 - Practice Hours, 1 - Lection Hours, 2 - Lab Hours - ) RETURNS int(11) - NO SQL -BEGIN - IF NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) - THEN - RETURN -1; - END IF; - - -- TODO: switch - IF Type = 0 THEN - UPDATE `disciplines` - SET disciplines.PracticeCount = Hours - WHERE disciplines.ID = DisciplineID - LIMIT 1; - END IF; - IF Type = 1 THEN - UPDATE `disciplines` - SET disciplines.LectionCount = Hours - WHERE disciplines.ID = DisciplineID - LIMIT 1; - END IF; - IF Type = 2 THEN - UPDATE `disciplines` - SET disciplines.LabCount = Hours - WHERE disciplines.ID = DisciplineID - LIMIT 1; - END IF; - - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS BindGroup// -CREATE FUNCTION `BindGroup` ( `TeacherID` INT, - `DisciplineID` INt, - `StudyGroupID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker INT; - --- 1. check if AccessedTeacher is author - IF NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) OR - InternalIsMapLocked(disciplineID) - THEN - RETURN -1; - END IF; - --- 2. check if study group is bound to discipline - SET checker = -1; - SELECT disciplines_groups.ID - INTO checker - FROM `disciplines_groups` - WHERE disciplines_groups.StudyGroupID = StudyGroupID AND - disciplines_groups.DisciplineID = DisciplineID - LIMIT 1; - IF checker > 0 THEN - RETURN 1; - END IF; - --- 3. delete students of this group which were bound to discipline before - DELETE FROM `disciplines_students` - WHERE DisciplineID = disciplines_students.DisciplineID AND - disciplines_students.StudentID IN - ( SELECT students.ID - FROM `students` - WHERE students.StudyGroupID = StudyGroupID - ); - --- 4. bind whole group - INSERT INTO `disciplines_groups` - ( disciplines_groups.DisciplineID, - disciplines_groups.StudyGroupID - ) - VALUES ( DisciplineID, StudyGroupID ); - RETURN 0; - -END // - - - -DROP FUNCTION IF EXISTS BindStudent// -CREATE FUNCTION `BindStudent` ( `TeacherID` INT, - `DisciplineID` INT, - `StudentID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, SG, temp INT; - --- 1. check if AccessedTeacher is author - IF NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) - THEN - RETURN -1; - END IF; - --- 2. check if student's group is bound yet - SET SG = -1; - SELECT students.StudyGroupID - INTO SG - FROM `students` - WHERE students.ID = StudentID - LIMIT 1; - - SET checker = -1; - SELECT disciplines_groups.ID - INTO checker - FROM `disciplines_groups` - WHERE DisciplineID = disciplines_groups.DisciplineID AND - SG = disciplines_groups.StudyGroupID - LIMIT 1; - IF checker > 0 THEN - DELETE FROM `disciplines_students` - WHERE DisciplineID = disciplines_students.DisciplineID AND - StudentID = disciplines_students.StudentID - LIMIT 1; - RETURN 0; - END IF; - --- 3. check if student is bound - SET checker = -1; - SELECT disciplines_students.ID - INTO checker - FROM `disciplines_students` - WHERE DisciplineID = disciplines_students.DisciplineID AND - StudentID = disciplines_students.StudentID - LIMIT 1; - IF checker > 0 THEN - RETURN 1; - END IF; - --- 4. bind student - INSERT INTO `disciplines_students` - ( disciplines_students.DisciplineID, - disciplines_students.StudentID, - disciplines_students.Type - ) - VALUES ( DisciplineID, StudentID, 'attach'); - RETURN 0; - -END // - - - -DROP FUNCTION IF EXISTS UnbindGroup// -CREATE FUNCTION `UnbindGroup` ( `TeacherID` INT, - `DisciplineID` INT, - `StudyGroupID` INT - ) RETURNS int(11) - NO SQL -BEGIN - IF NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) OR - InternalIsMapLocked(disciplineID) - THEN - RETURN -1; - END IF; - - DELETE FROM `disciplines_groups` - WHERE DisciplineID = disciplines_groups.DisciplineID AND - StudyGroupID = disciplines_groups.StudyGroupID - LIMIT 1; - - DELETE FROM `disciplines_students` - WHERE DisciplineID = disciplines_students.DisciplineID AND - disciplines_students.StudentID IN - ( SELECT students.ID - FROM `students` - WHERE students.StudyGroupID = StudyGroupID - ); - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS UnbindStudent// -CREATE FUNCTION `UnbindStudent` ( `TeacherID` INT, - `DisciplineID` INt, - `StudentID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, SG INT; - - SET SG = -1; - SELECT students.StudyGroupID - INTO SG - FROM `students` - WHERE students.ID = StudentID - LIMIT 1; - IF SG <= 0 OR - NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) - THEN - RETURN -1; - END IF; - - SET checker = -1; - SELECT disciplines_groups.ID - INTO checker - FROM `disciplines_groups` - WHERE DisciplineID = disciplines_groups.DisciplineID AND - SG = disciplines_groups.StudyGroupID - LIMIT 1; - - - IF checker > 0 THEN - INSERT INTO `disciplines_students` - ( disciplines_students.DisciplineID, - disciplines_students.StudentID, - disciplines_students.Type - ) - VALUES ( DisciplineID, StudentID, 'detach'); - - ELSE - DELETE FROM `disciplines_students` - WHERE DisciplineID = disciplines_students.DisciplineID AND - StudentID = disciplines_students.StudentID - LIMIT 1; - END IF; - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS BindTeacher// -CREATE FUNCTION `BindTeacher`( `TeacherID` INT, - `BindingTeacherID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker boolean; - --- 1. check if AccessedTeacher is author - SET checker = FALSE; - SELECT (TeacherID = disciplines.AuthorID) - INTO checker - FROM `disciplines` - WHERE DisciplineID = disciplines.ID - LIMIT 1; - IF NOT checker THEN - RETURN -1; - END IF; - --- 2. check if BindingTeacher has rights to access this discipline - IF InternalIsTeacherBinded(BindingTeacherID,DisciplineID) - THEN - RETURN 1; - END IF; - --- 3. insert BindingTeacher in access list - INSERT INTO `disciplines_teachers` - ( disciplines_teachers.DisciplineID, - disciplines_teachers.TeacherID - ) - VALUES ( DisciplineID, BindingTeacherID ); - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS UnbindTeacher// -CREATE FUNCTION `UnbindTeacher` ( `AuthorID` INT, - `BindingTeacher` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker boolean; - - IF AuthorID = BindingTeacher THEN - RETURN -1; - END IF; - - SET checker = FALSE; - SELECT (AuthorID = disciplines.AuthorID) - INTO checker - FROM `disciplines` - WHERE DisciplineID = disciplines.ID - LIMIT 1; - IF NOT checker THEN - RETURN -1; - END IF; - - DELETE FROM `disciplines_teachers` - WHERE DisciplineID = disciplines_teachers.DisciplineID AND - BindingTeacher = disciplines_teachers.TeacherID; - RETURN 0; - -END // - - - -DROP FUNCTION IF EXISTS DelegateDiscipline// -CREATE FUNCTION `DelegateDiscipline` ( `AuthorID` INT, - `NewAuthorID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker boolean; - - IF AuthorID = NewAuthorID OR - NOT InternalIsTeacherAuthor(AuthorID, DisciplineID) - THEN - RETURN -1; - END IF; - - SET checker = FALSE; - SELECT (AuthorID = disciplines.AuthorID) - INTO checker - FROM `disciplines` - INNER JOIN `disciplines_teachers` ON DisciplineID = disciplines_teachers.DisciplineID AND - NewAuthorID = disciplines_teachers.TeacherID - WHERE DisciplineID = disciplines.ID AND - AuthorID = disciplines.AuthorID - LIMIT 1; - IF NOT checker THEN - RETURN -1; - END IF; - - UPDATE `disciplines` - SET disciplines.AuthorID = NewAuthorID - WHERE disciplines.ID = DisciplineID - LIMIT 1; - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS ClearDiscipline// -CREATE FUNCTION `ClearDiscipline` ( `AuthorID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker boolean; - DECLARE vtemp INT; - - IF NOT InternalIsTeacherAuthor(AuthorID, DisciplineID) THEN - RETURN -1; - END IF; - - DELETE FROM `logs_rating` - WHERE logs_rating.SubModuleID IN - ( - SELECT submodules.ID - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - WHERE modules.DisciplineID = DisciplineID - ); - - DELETE FROM `rating_table` - WHERE rating_table.SubModuleID IN - ( - SELECT submodules.ID - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - WHERE modules.DisciplineID = DisciplineID - ); - - UPDATE `disciplines` - SET disciplines.isLocked = 0 - WHERE disciplines.ID = DisciplineID - LIMIT 1; - - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS DeleteDiscipline// -CREATE FUNCTION `DeleteDiscipline` ( `AuthorID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE vtemp INT; - IF NOT InternalIsTeacherAuthor(AuthorID, DisciplineID) THEN - RETURN -1; - END IF; - - SELECT disciplines.isLocked - INTO vtemp - FROM `disciplines` - WHERE disciplines.ID = DisciplineID - LIMIT 1; - - IF vtemp != 0 THEN - RETURN -1; - END IF; - - SET vtemp = CountRatings(AuthorID, DisciplineID); - IF vtemp > 0 THEN - RETURN -1; - END IF; - - - DELETE FROM `logs_rating` - WHERE logs_rating.SubModuleID IN - ( - SELECT submodules.ID - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - WHERE modules.DisciplineID = DisciplineID - ); - - DELETE FROM `rating_table` - WHERE rating_table.SubModuleID IN - ( - SELECT submodules.ID - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - WHERE modules.DisciplineID = DisciplineID - ); - - DELETE FROM `submodules` - WHERE submodules.ModuleID IN - ( - SELECT modules.ID - FROM `modules` - WHERE modules.DisciplineID = DisciplineID - ); - - DELETE FROM `modules` - WHERE modules.DisciplineID = DisciplineID; - - DELETE FROM `disciplines_teachers` - WHERE disciplines_teachers.DisciplineID = DisciplineID; - - DELETE FROM `disciplines_students` - WHERE disciplines_students.DisciplineID = DisciplineID; - - DELETE FROM `disciplines_groups` - WHERE disciplines_groups.DisciplineID = DisciplineID; - - DELETE FROM `disciplines` - WHERE disciplines.ID = DisciplineID - LIMIT 1; - - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS CountRatings// -CREATE FUNCTION `CountRatings` ( `TeacherID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE res boolean; - - IF NOT InternalIsTeacherBinded(TeacherID, DisciplineID) THEN - RETURN -1; - END IF; - - SET res = 0; - SELECT COUNT(rating_table.StudentID) - INTO res - FROM `rating_table` - INNER JOIN `submodules` ON rating_table.SubModuleID = submodules.ID - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - WHERE modules.DisciplineID = DisciplineID - LIMIT 1; - - RETURN res; -END // - - - -DROP FUNCTION IF EXISTS RestrictAfterMilestone// -CREATE FUNCTION `RestrictAfterMilestone` ( `TeacherID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - - UPDATE `disciplines` - SET disciplines.MilestoneDate = CURDATE(), - disciplines.isMilestone = 1 - WHERE disciplines.ID = DisciplineID - LIMIT 1; - - RETURN 0; -END // - - -DROP FUNCTION IF EXISTS RestrictAfterMilestoneForCredits// -CREATE FUNCTION `RestrictAfterMilestoneForCredits` ( `TeacherID` INT, - `FacultyID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE semID INT; - - SET semID = @CurrentSemesterID; - - UPDATE `disciplines` - SET disciplines.MilestoneDate = CURDATE(), - disciplines.isMilestone = 1 - WHERE disciplines.SemesterID = semID AND - disciplines.ExamType = 'credit' AND - disciplines.FacultyID= FacultyID; - - RETURN 0; -END // - --- ------------------------------------------------------------------------------------------- --- Label: modules --- ------------------------------------------------------------------------------------------- - - - -DROP FUNCTION IF EXISTS ChangeModuleName// -CREATE FUNCTION `ChangeModuleName` ( `TeacherID` INT, - `ModuleID` INT, - `Name` VARCHAR(200) charset utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE DisciplineID INT; - - SET DisciplineID = -1; - SELECT disciplines.ID - INTO DisciplineID - FROM `modules` - INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID AND - TeacherID = disciplines.AuthorID - WHERE ModuleID = modules.ID AND - modules.Type = 1 - LIMIT 1; - IF DisciplineID <= 0 OR - InternalIsMapLocked(DisciplineID) THEN - RETURN -1; - END IF; - - UPDATE `modules` - SET modules.Name = Name - WHERE modules.ID = ModuleID - LIMIT 1; - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS AddModule// -CREATE FUNCTION `AddModule` ( `TeacherID` INT, - `DisciplineID` INT, - `Name` VARCHAR(200) charset utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker INT; - - IF NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) OR - InternalIsMapLocked(DisciplineID) - THEN - RETURN -1; - END IF; - - SET checker = 0; - SELECT MAX(modules.OrderNum) - INTO checker - FROM `modules` - WHERE DisciplineID = modules.DisciplineID AND - modules.Type = 1 - LIMIT 1; - IF checker is NULL THEN - SET checker = 0; - END IF; - SET checker = checker + 1; - - - INSERT INTO `modules` - ( modules.Name, modules.OrderNum, modules.DisciplineID ) - VALUES ( Name , checker , DisciplineID ); - - - RETURN ( SELECT modules.ID - FROM `modules` - WHERE DisciplineID = modules.DisciplineID AND - checker = modules.OrderNum - LIMIT 1 - ); -END // - - - -DROP FUNCTION IF EXISTS AddModuleExam// -CREATE FUNCTION `AddModuleExam` ( `TeacherID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, vModule INT; - IF NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) OR - InternalIsMapLocked(DisciplineID) - THEN - RETURN -1; - END IF; - - SET checker = -1; - SELECT modules.ID - INTO checker - FROM `modules` - WHERE DisciplineID = modules.DisciplineID AND - modules.Type = 2; - IF checker > 0 THEN - RETURN -2; - END IF; - - - INSERT INTO `modules` - ( modules.Name, modules.OrderNum, modules.DisciplineID, modules.Type ) - VALUES ( 'Ркзамен' , 3141692 , DisciplineID, 2 ); - - SET vModule = -1; - SELECT modules.ID - INTO vModule - FROM `modules` - WHERE DisciplineID = modules.DisciplineID AND - modules.Type = 2 - LIMIT 1; - IF vModule <= 0 THEN - RETURN -1; - END IF; - - SET checker = AddSubmodule(TeacherID, vModule, 40, '', NULL, 'LandmarkControl'); - SET checker = AddSubmodule(TeacherID, vModule, 40, '', NULL, 'LandmarkControl'); - SET checker = AddSubmodule(TeacherID, vModule, 40, '', NULL, 'LandmarkControl'); - RETURN vModule; -END // - - -DROP FUNCTION IF EXISTS AddModuleExtra// -CREATE FUNCTION `AddModuleExtra` ( `TeacherID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, vModule, vType, vGap INT; - IF NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) - THEN - RETURN -1; - END IF; - - SET vType = -1; - SET checker = -1; - SELECT modules.ID - INTO checker - FROM `modules` - WHERE DisciplineID = modules.DisciplineID AND - modules.Type = 4 - LIMIT 1; - IF checker > 0 THEN - RETURN -2; - END IF; - - - INSERT INTO `modules` - ( modules.Name, modules.OrderNum, modules.DisciplineID, modules.Type ) - VALUES ( 'Добор баллов' , 2900666 , DisciplineID, 4 ); - - SET vModule = -1; - SELECT modules.ID, disciplines.ExamType - INTO vModule, vType - FROM `modules` - INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID - WHERE DisciplineID = modules.DisciplineID AND - modules.Type = 4 - LIMIT 1; - IF vModule <= 0 THEN - RETURN -1; - END IF; - - SET vGap = -1; - IF vType = 1 THEN - -- exam - SET vGap = 7; - END IF; - IF vType = 2 THEN - -- credit - SET vGap = 29; - SET checker = AddSubmodule(TeacherID, vModule, vGap, '', NULL, 'LandmarkControl'); - END IF; - - SET checker = AddSubmodule(TeacherID, vModule, vGap, '', NULL, 'LandmarkControl'); - RETURN vModule; -END // - - -DROP FUNCTION IF EXISTS DeleteModule// -CREATE FUNCTION `DeleteModule` ( `TeacherID` INT, - `ModuleID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker INT; - - SET checker = -1; - SELECT disciplines.ID - INTO checker - FROM `modules` - INNER JOIN `disciplines` ON modules.DisciplineID = disciplines.ID AND - TeacherID = disciplines.AuthorID - WHERE ModuleID = modules.ID - LIMIT 1; - IF checker <= 0 THEN - RETURN -1; - END IF; - - IF NOT InternalIsTeacherAuthor(TeacherID,checker) OR - InternalIsMapLocked(checker) - THEN - RETURN -1; - END IF; - - DELETE FROM `submodules` - WHERE submodules.ModuleID = ModuleID; - - DELETE FROM `modules` - WHERE ModuleID = modules.ID; - - SET @counter = 0; - UPDATE `modules` - SET modules.OrderNum = (@counter := @counter + 1) - WHERE modules.DisciplineID = checker AND - modules.Type = 1 -- regular - ORDER BY modules.OrderNum ASC; - - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS DeleteModuleExam// -CREATE FUNCTION `DeleteModuleExam` ( `TeacherID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE ExamModuleID INT; - IF NOT InternalIsTeacherAuthor(TeacherID, DisciplineID) OR - InternalIsMapLocked(DisciplineID) - THEN - RETURN -1; - END IF; - - SET ExamModuleID = -1; - SELECT modules.ID - INTO ExamModuleID - FROM `modules` - WHERE modules.Type = 2 AND - DisciplineID = modules.DisciplineID - LIMIT 1; - IF ExamModuleID <= 0 THEN - RETURN -1; - END IF; - - DELETE FROM `submodules` - WHERE ExamModuleID = submodules.ModuleID; - - DELETE FROM `modules` - WHERE ExamModuleID = modules.ID - LIMIT 1; - - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS SwapModuleOrder// -CREATE FUNCTION `SwapModuleOrder` ( `TeacherID` INT, - `ModuleID1` INT, - `ModuleID2` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, ord1, ord2, disc1, disc2 INT; - - - SET disc1 = -1; - SET disc2 = -1; - SELECT modules.OrderNum, - modules.DisciplineID - INTO ord1, disc1 - FROM `modules` - INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID - WHERE TeacherID = disciplines.AuthorID AND - modules.ID = ModuleID1 AND - modules.Type = 1 - LIMIT 1; - - SELECT modules.OrderNum, - modules.DisciplineID - INTO ord2, disc2 - FROM `modules` - INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID - WHERE TeacherID = disciplines.AuthorID AND - modules.ID = ModuleID2 AND - modules.Type = 1 - LIMIT 1; - IF disc1 != disc2 OR disc1 <= 0 OR - InternalIsMapLocked(disc1) THEN - RETURN -1; - END IF; - - UPDATE `modules` - SET modules.OrderNum = 271828 - WHERE modules.ID = ModuleID1; - - UPDATE `modules` - SET modules.OrderNum = ord1 - WHERE modules.ID = ModuleID2 - LIMIT 1; - - UPDATE `modules` - SET modules.OrderNum = ord2 - WHERE modules.ID = ModuleID1 - LIMIT 1; - - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS AddModuleBonus// -CREATE FUNCTION `AddModuleBonus` ( `TeacherID` INT, - `DisciplineID` INT - - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, vModule INT; - IF NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) OR - InternalIsMapLocked(DisciplineID) - THEN - RETURN -1; - END IF; - - SET checker = -1; - SELECT modules.ID - INTO checker - FROM `modules` - WHERE DisciplineID = modules.DisciplineID AND - modules.Type = 3; - IF checker > 0 THEN - RETURN -2; - END IF; - - - INSERT INTO `modules` - ( modules.Name, modules.OrderNum, modules.DisciplineID, modules.Type ) - VALUES ( 'Бонусные баллы' , 2141692 , DisciplineID, 3 ); - - SET vModule = -1; - SELECT modules.ID - INTO vModule - FROM `modules` - WHERE DisciplineID = modules.DisciplineID AND - modules.Type = 3 - LIMIT 1; - IF vModule <= 0 THEN - RETURN -1; - END IF; - - SET checker = AddSubmodule(TeacherID, vModule, 10, '', NULL, 'LandmarkControl'); - RETURN 0; -END // - - -DROP FUNCTION IF EXISTS DeleteModuleBonus// -CREATE FUNCTION `DeleteModuleBonus` ( `TeacherID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE BonusModuleID INT; - IF NOT InternalIsTeacherAuthor(TeacherID,DisciplineID) OR - InternalIsMapLocked(DisciplineID) - THEN - RETURN -1; - END IF; - - SET BonusModuleID = -1; - SELECT modules.ID - INTO BonusModuleID - FROM `modules` - WHERE modules.Type = 3 AND - DisciplineID = modules.DisciplineID - LIMIT 1; - IF BonusModuleID <= 0 THEN - RETURN -1; - END IF; - - DELETE FROM `submodules` - WHERE BonusModuleID = submodules.ModuleID; - - DELETE FROM `modules` - WHERE BonusModuleID = modules.ID - LIMIT 1; - - RETURN 0; -END // - - - --- ------------------------------------------------------------------------------------------- --- Label: submodules --- ------------------------------------------------------------------------------------------- - - - -DROP FUNCTION IF EXISTS ChangeSubmoduleMaxAndControl// -CREATE FUNCTION `ChangeSubmoduleMaxAndControl` ( `TeacherID` INT, - `SubmoduleID` INT, - `MaxRate` INT, - `ControlType` VARCHAR(30) charset utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, disciplineID, curMaxRate INT; - - SET checker = -1; - SET disciplineID = -1; - SELECT submodules.ID, - disciplines.ID, - submodules.MaxRate - INTO checker, disciplineID, curMaxRate - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID - WHERE TeacherID = disciplines.AuthorID AND - SubmoduleID = submodules.ID - LIMIT 1; - IF checker <= 0 OR - disciplineID <= 0 OR - InternalIsMapLocked(disciplineID) OR - GetDisciplineMaxRate(disciplineID) - curMaxRate + MaxRate > 100 THEN - RETURN -1; - END IF; - - - UPDATE `submodules` - SET submodules.MaxRate = MaxRate, - submodules.Type = ControlType - WHERE submodules.ID = SubmoduleID - LIMIT 1; - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS ChangeSubmoduleName// -CREATE FUNCTION `ChangeSubmoduleName` ( `TeacherID` INT, - `SubmoduleID` INT, - `Name` VARCHAR(200) charset utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, disciplineID INT; - - SET disciplineID = -1; - SET checker = -1; - SELECT submodules.ID, - disciplines.ID - INTO checker, disciplineID - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID - WHERE TeacherID = disciplines.AuthorID AND - SubmoduleID = submodules.ID - LIMIT 1; - IF checker <= 0 OR - disciplineID <= 0 OR - InternalIsMapLocked(disciplineID) THEN - RETURN -1; - END IF; - - UPDATE `submodules` - SET submodules.Name = Name - WHERE submodules.ID = SubmoduleID - LIMIT 1; - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS ChangeSubmoduleDescription// -CREATE FUNCTION `ChangeSubmoduleDescription` ( `TeacherID` INT, - `SubmoduleID` INT, - `Description` VARCHAR(200) charset utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, disciplineID INT; - - SET checker = -1; - SET disciplineID = -1; - SELECT submodules.ID, - disciplines.ID - INTO checker, disciplineID - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID - WHERE TeacherID = disciplines.AuthorID AND - SubmoduleID = submodules.ID - LIMIT 1; - IF checker <= 0 OR - disciplineID <= 0 OR - InternalIsMapLocked(disciplineID) THEN - RETURN -1; - END IF; - - UPDATE `submodules` - SET submodules.Description = Description - WHERE submodules.ID = SubmoduleID - LIMIT 1; - RETURN 0; -END // - - - - -DROP FUNCTION IF EXISTS DeleteSubmodule// -CREATE FUNCTION `DeleteSubmodule` ( `TeacherID` INT, - `SubmoduleID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, ModID, disciplineID INT; - - SET checker = -1; - SET disciplineID = -1; - SELECT submodules.ID, modules.ID, disciplines.ID - INTO checker, ModID, disciplineID - FROM `submodules` - INNER JOIN `modules` ON modules.ID = submodules.ModuleID - INNER JOIN `disciplines` ON modules.DisciplineID = disciplines.ID - WHERE TeacherID = disciplines.AuthorID AND - SubmoduleID = submodules.ID - LIMIT 1; - IF checker <= 0 OR - disciplineID <= 0 OR - InternalIsMapLocked(disciplineID) THEN - RETURN -1; - END IF; - - SET checker = -1; - SELECT rating_table.StudentID - INTO checker - FROM `rating_table` - WHERE rating_table.SubmoduleID = SubmoduleID - LIMIT 1; - IF checker > 0 THEN - RETURN -2; - END IF; - - DELETE FROM `submodules` - WHERE submodules.ID = SubmoduleID - LIMIT 1; - - - SET @counter = 0; - UPDATE `submodules` - SET submodules.OrderNum = (@counter := @counter + 1) - WHERE submodules.ModuleID = ModID - ORDER BY submodules.OrderNum ASC; - - RETURN 0; -END // - - - -DROP FUNCTION IF EXISTS AddSubmodule// -CREATE FUNCTION `AddSubmodule` ( `TeacherID` INT, - `ModuleID` INT, - `MaxRate` INT, - `Name` VARCHAR(200) charset utf8, - `Description` VARCHAR(200) charset utf8, - `ControlType` VARCHAR(30) charset utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker INT; - - SET checker = -1; - SELECT disciplines.ID - INTO checker - FROM `modules` - INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID - WHERE TeacherID = disciplines.AuthorID AND - ModuleID = modules.ID - LIMIT 1; - IF checker <= 0 OR - InternalIsMapLocked(checker) - THEN - RETURN -1; - END IF; - - - SET checker = 0; - SELECT MAX(submodules.OrderNum) - INTO checker - FROM `submodules` - WHERE ModuleID = submodules.ModuleID - LIMIT 1; - IF checker IS NULL THEN - SET checker = 0; - END IF; - SET checker = checker + 1; - - IF Description = "" THEN - INSERT INTO `submodules` - ( submodules.ModuleID, submodules.MaxRate, submodules.OrderNum, submodules.Name, submodules.Description, submodules.Type ) - VALUES ( ModuleID, MaxRate, checker, Name, NULL, ControlType); - ELSE - INSERT INTO `submodules` - ( submodules.ModuleID, submodules.MaxRate, submodules.OrderNum, submodules.Name, submodules.Description, submodules.Type ) - VALUES ( ModuleID, MaxRate, checker, Name, Description, ControlType); - END IF; - - RETURN ( SELECT submodules.ID - FROM `submodules` - WHERE submodules.ModuleID = ModuleID AND - submodules.OrderNum = checker - LIMIT 1 - ); -END // - - - -DROP FUNCTION IF EXISTS SwapSubmoduleOrder// -CREATE FUNCTION `SwapSubmoduleOrder`( `TeacherID` INT, - `SubmoduleID1` INT, - `SubmoduleID2` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, ord1, ord2, mod1, mod2, disciplineID INT; - - SET mod1 = -1; - SET mod2 = -1; - SET disciplineID = -1; - SELECT submodules.OrderNum, - submodules.ModuleID, - disciplines.ID - INTO ord1, mod1, disciplineID - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID - WHERE TeacherID = disciplines.AuthorID AND - SubmoduleID1 = submodules.ID - LIMIT 1; - - SELECT submodules.OrderNum, - submodules.ModuleID - INTO ord2, mod2 - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - INNER JOIN `disciplines` ON disciplines.ID = modules.DisciplineID - WHERE TeacherID = disciplines.AuthorID AND - SubmoduleID2 = submodules.ID - LIMIT 1; - IF mod1 <= 0 OR mod1 != mod2 OR - InternalIsMapLocked(disciplineID) THEN - RETURN -1; - END IF; - - UPDATE `submodules` - SET submodules.OrderNum = 271828 - WHERE submodules.ID = SubmoduleID1 - LIMIT 1; - - UPDATE `submodules` - SET submodules.OrderNum = ord1 - WHERE submodules.ID = SubmoduleID2 - LIMIT 1; - - UPDATE `submodules` - SET submodules.OrderNum = ord2 - WHERE submodules.ID = SubmoduleID1 - LIMIT 1; - RETURN 0; -END // - - --- ------------------------------------------------------------------------------------------- --- Label: rating --- ------------------------------------------------------------------------------------------- - - -DROP FUNCTION IF EXISTS GetMaxRateForDisc// -CREATE FUNCTION `GetMaxRateForDisc` ( `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE res INT; - SET res = 0; - - SELECT SUM(submodules.MaxRate) - INTO res - FROM `modules` - LEFT JOIN `submodules` ON submodules.ModuleID = modules.ID - WHERE modules.DisciplineID = DisciplineID AND - submodules.isUsed != 0 AND - (modules.Type = 1 OR ( modules.Type = 2 AND submodules.OrderNum = 1)) - LIMIT 1; - - RETURN (res); -END // - - --- Вычисление максимального балла для submodule - -DROP FUNCTION IF EXISTS CalculateMaxRateForExtra// -CREATE FUNCTION `CalculateMaxRateForExtra` ( `SubmoduleID` INT, `StudentID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE examTypeVar VARCHAR(30) charset utf8; -- enum('exam', 'credit');-- utf8_general_ci; - DECLARE lim, res INT; - SET res=-1; - - IF examTypeVar = 'exam' THEN - SET lim = 38; - ELSE - SET lim = 60; - END IF; - - SELECT lim-GetRateForDiscSemester(StudentID, DisciplineID) - INTO res - FROM submodules as subm1 - JOIN modules ON subm1.ModuleID=modules.ID - JOIN disciplines ON DisciplineID=disciplines.ID - WHERE modules.type='extra' AND subm1.ID=SubmoduleID; - - return res; -END // - -DROP FUNCTION IF EXISTS SetStudentRate// -CREATE FUNCTION `SetStudentRate`( `TeacherID` INT, - `StudentID` INT, - `SubmoduleID` INT, - `Rate` INT ) - RETURNS int(11) - NO SQL -BEGIN - DECLARE checker, DisciplineID, groupID, rateID, maxRate, isOver, mtype INT; - DECLARE isLocked, isUsed tinyint; - - SET groupID = -1; - SELECT students.StudyGroupID - INTO groupID - FROM `students` - WHERE students.ID = StudentID - LIMIT 1; - IF groupID <= 0 THEN - RETURN -1; - END IF; - - SET maxRate = CalculateMaxRateForExtra(SubmoduleID, StudentID); - - SET isOver = 1; - SET isLocked = 0; - SET DisciplineID = -1; - SET mtype = -1; - SELECT modules.DisciplineID, - disciplines.isLocked, - disciplines.isMilestone, - rating_table.StudentID, - submodules.isUsed, - CASE - WHEN modules.type='extra' THEN - CalculateMaxRateForExtra(SubmoduleID, StudentID) - ELSE - submodules.maxRate - END, - modules.Type - INTO DisciplineID, isLocked, isOver, rateID, isUsed, maxRate, mtype - FROM `submodules` - INNER JOIN `modules` ON submodules.ModuleID = modules.ID - INNER JOIN `disciplines` ON modules.DisciplineID = disciplines.ID - INNER JOIN `disciplines_teachers` ON disciplines.ID = disciplines_teachers.DisciplineID AND - TeacherID = disciplines_teachers.TeacherID - LEFT JOIN `disciplines_groups` ON disciplines.ID = disciplines_groups.DisciplineID AND - groupID = disciplines_groups.StudyGroupID - LEFT JOIN `disciplines_students` ON disciplines.ID = disciplines_students.DisciplineID AND - StudentID = disciplines_students.StudentID AND - 1 = disciplines_students.Type - LEFT JOIN `rating_table` ON SubModuleID = rating_table.SubmoduleID AND - StudentID = rating_table.StudentID - WHERE submodules.ID = SubModuleID AND - ( disciplines_students.ID IS NOT NULL OR - disciplines_groups.ID IS NOT NULL - ) - LIMIT 1; - IF DisciplineID <= 0 OR - Rate > maxRate OR - (isOver > 0 AND (mtype = 1 OR mtype = 3)) - THEN - RETURN -1; - END IF; - - - IF rateID IS NOT NULL AND rateID > 0 THEN - INSERT INTO `logs_rating` - (logs_rating.StudentID, logs_rating.SubmoduleID, logs_rating.TeacherID, logs_rating.Rate, logs_rating.Action ) - VALUES (StudentID, SubModuleID, TeacherID, Rate, 'change'); - - UPDATE `rating_table` - SET rating_table.TeacherID = TeacherID, - rating_table.Rate = Rate, - rating_table.Date = CURDATE() - WHERE SubmoduleID = rating_table.SubmoduleID AND - StudentID = rating_table.StudentID - LIMIT 1; - - ELSE - IF NOT isLocked THEN - UPDATE `disciplines` - SET disciplines.isLocked = 1 - WHERE disciplines.ID = DisciplineID - LIMIT 1; - END IF; - - INSERT INTO `logs_rating` - (logs_rating.StudentID, logs_rating.SubmoduleID, logs_rating.TeacherID, logs_rating.Rate, logs_rating.Action ) - VALUES (StudentID, SubModuleID, TeacherID, Rate, 'add'); - - INSERT INTO `rating_table` - ( rating_table.StudentID, - rating_table.TeacherID, - rating_table.SubmoduleID, - rating_table.Rate, - rating_table.Date - ) - VALUES ( StudentID, TeacherID, SubmoduleID, Rate, CURDATE() ); - - IF NOT isUsed THEN - UPDATE `submodules` - SET submodules.isUsed = 1 - WHERE submodules.ID = SubModuleID - LIMIT 1; - END IF; - END IF; - RETURN 0; -END // - - - - - --- ------------------------------------------------------------------------------------------- --- Label: requests --- ------------------------------------------------------------------------------------------- - - - - -DROP PROCEDURE IF EXISTS GetRequests// -CREATE PROCEDURE `GetRequests` ( IN `OffsetN` INT, - IN `CountN` INT, - IN `AccountID` INT, - IN `vStatus` VARCHAR(20) charset utf8 - ) - NO SQL -BEGIN - SELECT requests.ID, - requests.AccountID, - requests.Title, - requests.Description, - requests.Date, - requests.Status - FROM `requests` - WHERE ( AccountID = 0 OR AccountID = requests.AccountID ) AND - ( vStatus = 'all' OR requests.Status = vStatus ) - LIMIT CountN OFFSET OffsetN; -END // - - -DROP FUNCTION IF EXISTS SetRequestStatus// -CREATE FUNCTION `SetRequestStatus` ( `RequestID` INT, - `vStatus` VARCHAR(20) charset utf8 - ) RETURNS int(11) - NO SQL -BEGIN - UPDATE `requests` - SET requests.Status = vStatus - WHERE RequestID = requests.ID - LIMIT 1; - RETURN 0; -END// - - -DROP FUNCTION IF EXISTS CreateRequest// -CREATE FUNCTION `CreateRequest` ( `AccountID` INT, - `vTitle` VARCHAR(50) charset utf8, - `vDescription` TEXT charset utf8 - ) RETURNS int(11) - NO SQL -BEGIN - INSERT INTO `requests` - (requests.AccountID, requests.Title, requests.Description, requests.Status) - VALUES (AccountID, vTitle, vDescription, 'opened'); - RETURN LAST_INSERT_ID(); -END// - - - - - --- DROP FUNCTION IF EXISTS SetRequestStatus// --- CREATE FUNCTION `SetRequestStatus` ( `RequestID` INT, --- `vStatus` VARCHAR(20) charset utf8 --- ) RETURNS int(11) --- NO SQL --- BEGIN --- IF vStatus = "closed" THEN --- INSERT INTO `requests_old` --- ( requests.ID, requests.To, requests.From, --- requests.Field1, requests.Field2, requests.Field3, --- requests.Data, requests.DataExt, --- requests.Date, requests.Type, requests.Status --- ) --- SELECT requests.ID, requests.To, requests.From, --- requests.Field1, requests.Field2, requests.Field3, --- requests.Data, requests.DataExt, --- requests.Date, requests.Type, 'closed' AS 'Status' --- FROM `requests` --- WHERE requests.ID = RequestID --- LIMIT 1; - --- DELETE FROM `requests` --- WHERE requests.ID = RequestID --- LIMIT 1; - - - --- ELSE --- UPDATE `requests` --- SET requests.Status = vStatus --- WHERE RequestID = requests.ID --- LIMIT 1; --- END IF; --- RETURN 0; --- END// - - --- DROP PROCEDURE IF EXISTS GetRequests// --- CREATE PROCEDURE `GetRequests` ( IN `AccountID` INT, --- IN `Type` INT -- 0 to me, 1 - from me, 3 - all --- ) --- NO SQL --- BEGIN --- SELECT requests.ID, --- requests.To, --- requests.From, --- requests.Field1, --- requests.Field2, --- requests.Field3, --- requests.Data, --- requests.DataExt, --- requests.Date, --- requests.Type, --- requests.Status --- FROM `requests` --- WHERE ((Type & 1) != 0 AND requests.To = AccountID) OR --- ((Type & 2) != 0 AND requests.From = AccountID) --- ORDER BY requests.To = AccountID DESC, requests.Type ASC, requests.ID ASC; --- END// - - - --- DROP FUNCTION IF EXISTS RequestReport// --- CREATE FUNCTION `RequestReport` ( `AccountID` INT, --- `vTitle` VARCHAR(50) charset utf8, --- `vDescription` TEXT charset utf8 --- ) RETURNS int(11) --- NO SQL --- BEGIN --- INSERT INTO `requests` --- (requests.To, requests.From, requests.Data, requests.DataExt, requests.Type) --- VALUES (0, AccountID, vDescription, vTitle, 4); -- 4 - report --- RETURN LAST_INSERT_ID(); --- END// - - - --- DROP FUNCTION IF EXISTS RequestDelegateDiscipline// --- CREATE FUNCTION `RequestDelegateDiscipline` ( `AuthorID` INT, --- `NewAuthorID` INT, --- `DisciplineID` INT --- ) RETURNS int(11) --- NO SQL --- BEGIN --- IF AuthorID = NewAuthorID OR --- NOT InternalIsTeacherAuthor(AuthorID, DisciplineID) --- THEN --- RETURN -1; --- END IF; - --- INSERT INTO `requests` --- (requests.To, requests.From, requests.Field1, requests.Type) --- VALUES (NewAuthorID, AuthorID, DisciplineID, 1); --- RETURN 0; --- END // - - --- DROP FUNCTION IF EXISTS RequestDeleteDiscipline// --- CREATE FUNCTION `RequestDeleteDiscipline` ( `AuthorID` INT, --- `DisciplineID` INT --- ) RETURNS int(11) --- NO SQL --- BEGIN --- IF NOT InternalIsTeacherAuthor(AuthorID, DisciplineID) --- THEN --- RETURN -1; --- END IF; - --- INSERT INTO `requests` --- (requests.To, requests.From, requests.Field1, requests.Type) --- VALUES (0, AuthorID, DisciplineID, 2); --- RETURN 0; --- END // - --- DROP FUNCTION IF EXISTS RequestClearDiscipline// --- CREATE FUNCTION `RequestClearDiscipline` ( `AuthorID` INT, --- `DisciplineID` INT --- ) RETURNS int(11) --- NO SQL --- BEGIN --- IF NOT InternalIsTeacherAuthor(AuthorID, DisciplineID) --- THEN --- RETURN -1; --- END IF; - --- INSERT INTO `requests` --- (requests.To, requests.From, requests.Field1, requests.Type) --- VALUES (0, AuthorID, DisciplineID, 3); --- RETURN 0; --- END // - - - - --- ------------------------------------------------------------------------------------------- --- Label: recovery --- ------------------------------------------------------------------------------------------- - - -DROP FUNCTION IF EXISTS CreateRecoveryToken// -CREATE FUNCTION `CreateRecoveryToken` ( `AccountEMail` VARCHAR(255) charset utf8, - `Token` VARCHAR(100) charset utf8 - ) RETURNS VARCHAR(255) charset utf8 - NO SQL -BEGIN - DECLARE checker INT; - DECLARE accID INT; - DECLARE UserFullName VARCHAR(255); - - SET accID = -1; - SELECT accounts.ID - INTO accID - FROM `accounts` - WHERE accounts.EMail = AccountEMail - LIMIT 1; - IF accID <= 0 THEN - RETURN ""; - END IF; - - SET checker = 0; - SELECT recovery_tokens.ID - INTO checker - FROM `recovery_tokens` - WHERE recovery_tokens.Token = Token - LIMIT 1; - IF checker > 0 THEN - RETURN ""; - END IF; - - SET UserFullName = GetUserFullNameByAccountID(accID); - IF UserFullName IS NULL OR UserFullName = "" THEN - RETURN ""; - END IF; - - UPDATE `recovery_tokens` - SET recovery_tokens.isUsed = 1 - WHERE recovery_tokens.isUsed = 0; - - INSERT INTO `recovery_tokens` - (AccountID, Token ) - VALUES (accID, Token); - RETURN UserFullName; -END// - -DROP FUNCTION IF EXISTS GetUserFullNameByAccountID// -CREATE FUNCTION `GetUserFullNameByAccountID` ( `AccountID` INT(11) - ) RETURNS VARCHAR(255) charset utf8 -NO SQL -BEGIN - DECLARE UserFullName VARCHAR(255); - DECLARE checker INT; - - SET checker = -1; - SELECT students.ID As ID, CONCAT(students.LastName, students.FirstName, students.SecondName) As UserName - INTO checker, UserFullName - FROM `students` - WHERE students.AccountID = AccountID - LIMIT 1; - IF checker <= 0 THEN - SELECT teachers.ID As ID, CONCAT(teachers.LastName, teachers.FirstName, teachers.SecondName) As UserName - INTO checker, UserFullName - FROM `teachers` - WHERE teachers.AccountID = AccountID - LIMIT 1; - IF checker <= 0 THEN - RETURN ""; - END IF; - END IF; - - RETURN UserFullName; -END// - - -DROP FUNCTION IF EXISTS UseRecoveryToken// -CREATE FUNCTION `UseRecoveryToken` ( `Token` VARCHAR(100) charset utf8 - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE checker INT; - - SET checker = -1; - SELECT recovery_tokens.ID - INTO checker - FROM `recovery_tokens` - WHERE recovery_tokens.Token = Token - LIMIT 1; - IF checker <= 0 THEN - RETURN -1; - END IF; - - UPDATE `recovery_tokens` - SET recovery_tokens.isUsed = 1 - WHERE recovery_tokens.Token = Token - LIMIT 1; - RETURN 0; -END// - - - -DROP PROCEDURE IF EXISTS GetRecoveryInfoByToken// -CREATE PROCEDURE `GetRecoveryInfoByToken` ( IN `Token` VARCHAR(100) charset utf8 - ) - NO SQL -BEGIN - SELECT recovery_tokens.ID, - recovery_tokens.AccountID, - recovery_tokens.Date, - recovery_tokens.Token, - recovery_tokens.isUsed - FROM `recovery_tokens` - WHERE recovery_tokens.Token = Token - LIMIT 1; -END // - -DROP PROCEDURE IF EXISTS GetRecoveryInfoByEMail// -CREATE PROCEDURE `GetRecoveryInfoByEMail` ( IN `EMail` VARCHAR(255) charset utf8 - ) - NO SQL -BEGIN - DECLARE accID INT; - - SET accID = -1; - SELECT accounts.ID - INTO accID - FROM `accounts` - WHERE accounts.EMail = EMail - LIMIT 1; - IF accID <= 0 THEN - SELECT NULL AS 'ID' - LIMIT 0; - END IF; - - SELECT recovery_tokens.ID, - recovery_tokens.AccountID, - recovery_tokens.Date, - recovery_tokens.Token, - recovery_tokens.isUsed - FROM `recovery_tokens` - WHERE recovery_tokens.AccountID = accID - AND recovery_tokens.isUsed = 0; -END // - - - - - - -DROP PROCEDURE IF EXISTS GetReports// -CREATE PROCEDURE `GetReports` ( IN `StudyGroupID` INT - ) - NO SQL -BEGIN - SELECT students.ID AS 'StudentID', - students.LastName, - students.FirstName, - students.SecondName, - disciplines.ID, - GetRateForDisc(students.ID, disciplines.ID) AS 'Rate', - GetMaxRateForDisc(disciplines.ID) AS 'MaxRate' - FROM `students` - LEFT JOIN `disciplines` ON disciplines.ID IN - ( - SELECT disciplines_groups.DisciplineID - FROM `disciplines_groups` - WHERE disciplines_groups.StudyGroupID = StudyGroupID - UNION DISTINCT - SELECT disciplines_students.DisciplineID - FROM `disciplines_students` - INNER JOIN `students` ON disciplines_students.ID = students.ID - WHERE students.StudyGroupID = StudyGroupID - ) - INNER JOIN `subjects` ON disciplines.SubjectID = subjects.ID - WHERE students.StudyGroupID = StudyGroupID; -END // - - - - --- DROP PROCEDURE IF EXISTS GetReports// --- CREATE PROCEDURE `GetReports` ( IN `StudyGroupID` INT --- ) --- NO SQL --- BEGIN --- -- CREATE TEMPORARY TABLE IF NOT EXISTS `temp_disciplines` ( --- -- `DisciplineID` int(11) NOT NULL, --- -- `MaxRate` int(11) NOT NULL DEFAULT '0', --- -- PRIMARY KEY (`DisciplineID`) --- -- ) ENGINE=MEMORY DEFAULT CHARSET=utf8 AS ( --- -- SELECT disciplines_groups.DisciplineID, --- -- 0 AS 'MaxRate' --- -- FROM `disciplines_groups` --- -- WHERE disciplines_groups.StudyGroupID = StudyGroupID --- -- UNION DISTINCT --- -- SELECT disciplines_students.DisciplineID, --- -- 0 AS 'MaxRate' --- -- FROM `disciplines_students` --- -- INNER JOIN `students` ON disciplines_students.ID = students.ID --- -- WHERE students.StudyGroupID = StudyGroupID --- -- ); - --- CREATE TEMPORARY TABLE IF NOT EXISTS `temp_disciplines` --- SELECT disciplines_groups.DisciplineID, --- 0 AS 'MaxRate' --- FROM `disciplines_groups` --- WHERE disciplines_groups.StudyGroupID = StudyGroupID --- UNION DISTINCT --- SELECT disciplines_students.DisciplineID, --- 0 AS 'MaxRate' --- FROM `disciplines_students` --- INNER JOIN `students` ON disciplines_students.ID = students.ID --- WHERE students.StudyGroupID = StudyGroupID; - --- UPDATE `temp_disciplines` --- SET temp_disciplines.MaxRate = GetMaxRateForDisc(temp_disciplines.DisciplineID); - --- SELECT students.ID AS 'StudentID', --- temp_disciplines.DisciplineID, --- temp_disciplines.MaxRate, --- GetRateForDisc(students.ID, temp_disciplines.DisciplineID) AS 'Rate' --- FROM `students` --- LEFT JOIN `temp_disciplines` ON 1=1 --- WHERE students.StudyGroupID = StudyGroupID; --- END // - -DROP PROCEDURE IF EXISTS GetDisciplinesForGroup// -CREATE PROCEDURE `GetDisciplinesForGroup` ( IN `GroupID` INT - ) - NO SQL -BEGIN - SELECT disciplines_groups.DisciplineID As DisciplineID, - subjects.Name As SubjectName, - disciplines.ExamType As ExamType - FROM `disciplines_groups` - INNER JOIN `disciplines` ON disciplines.ID = disciplines_groups.DisciplineID - INNER JOIN `subjects` ON subjects.ID = disciplines.SubjectID - WHERE disciplines_groups.StudyGroupID = GroupID - UNION DISTINCT - SELECT disciplines_students.DisciplineID As DisciplineID, - subjects.Name As SubjectName, - disciplines.ExamType As ExamType - FROM `disciplines_students` - INNER JOIN `students` ON disciplines_students.StudentID = students.ID - INNER JOIN `disciplines` ON disciplines.ID = disciplines_students.DisciplineID - INNER JOIN `subjects` ON subjects.ID = disciplines.SubjectID - WHERE students.StudyGroupID = GroupID; -END // - - -DROP PROCEDURE IF EXISTS GetRatesForStudentsGroup// -CREATE PROCEDURE `GetRatesForStudentsGroup` ( IN `TeacherID` INT, - IN `DisciplineID` INT, - IN `StudyGroupID` INT - ) - NO SQL -BEGIN --- TODO: TeacherID deprecated - SELECT students.ID AS 'ID', - students.LastName AS 'Last', - students.FirstName AS 'First', - students.SecondName AS 'Second', - CONCAT(students.LastName, " ", students.FirstName, " ", students.SecondName) AS 'FullName', - GetRateForDiscSemester(students.ID, DisciplineID) AS 'intermediate', - GetRateForDiscBonus(students.ID, DisciplineID) AS 'bonus', - GetRateForDiscExam(students.ID, DisciplineID) AS 'exam', - GetRateForDisc(students.ID, DisciplineID) AS 'total' - FROM `students` - -- INNER JOIN `study_groups` ON study_groups.ID = students.StudyGroupID - -- LEFT JOIN `modules` ON modules.DisciplineID = DisciplineID AND - -- (modules.Type = 'exam' OR modules.Type = 'extra') - -- LEFT JOIN `submodules` ON submodules.ModuleID = modules.ID - WHERE students.StudyGroupID = StudyGroupID AND - InternalIsStudentAttached(students.ID, DisciplineID) - ORDER BY FullName ASC, ID ASC; - -END // - -DROP PROCEDURE IF EXISTS GetAttestationData// -CREATE PROCEDURE `GetAttestationData` ( IN `DisciplineID` INT, - IN `StudyGroupID` INT -) -NO SQL -BEGIN - SELECT students.ID AS 'StudentID', - rating_table.Rate As 'Rate', - rating_table.Date As 'Date', - submodules.OrderNum As 'OrderNum', - modules.Type As 'Type' - FROM `students` - LEFT JOIN `modules` ON modules.DisciplineID = DisciplineID AND - (modules.Type = 'exam' OR modules.Type = 'extra') - LEFT JOIN `submodules` ON submodules.ModuleID = modules.ID - LEFT JOIN `rating_table` ON rating_table.SubmoduleID = submodules.ID AND - rating_table.StudentID = students.ID - WHERE students.StudyGroupID = StudyGroupID AND - InternalIsStudentAttached(students.ID, DisciplineID) - ORDER BY CONCAT(students.LastName, " ", students.FirstName, " ", students.SecondName) ASC, - students.ID ASC, modules.Type = 'exam' ASC, submodules.OrderNum ASC; - -END // - - -DROP PROCEDURE IF EXISTS GetFinalFormInfo// -CREATE PROCEDURE `GetFinalFormInfo` ( IN `DisciplineID` INT, - IN `StudyGroupID` INT - ) - NO SQL -BEGIN - DECLARE curSem INT; - SET curSem = @CurrentSemesterID; - - SELECT study_groups.GroupNum AS 'GroupNum', - study_groups.Name AS 'GroupName', - grades.ID AS 'GradeID', - grades.Num AS 'GradeNum', - grades.Degree AS 'Degree', - specializations.ID AS 'SpecID', - specializations.Name AS 'SpecName', - specializations.Abbr AS 'SpecAbbr', - specializations.Code AS 'SpecCode', - faculties.ID AS 'FacultyID', - faculties.Name AS 'FacultyName', - faculties.Abbr AS 'FacultyAbbr', - disciplines.ExamType AS 'ExamType', - subjects.ID AS 'SubjectID', - subjects.Name AS 'SubjectName', - subjects.Abbr AS 'SubjectAbbr', - teachers.ID AS 'AuthorID', - teachers.LastName AS 'LastName', - teachers.FirstName AS 'FirstName', - teachers.SecondName AS 'SecondName', - job_positions.Name AS 'JobPosition', - departments.ID AS 'DepID', - departments.Name AS 'DepName', - semesters.Year AS 'Year', - semesters.Num AS 'SemesterNum' - - FROM `study_groups` - INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID - INNER JOIN `grades` ON study_groups.GradeID = grades.ID - INNER JOIN `faculties` ON faculties.ID = specializations.FacultyID - INNER JOIN `disciplines` ON disciplines.ID = DisciplineID - INNER JOIN `subjects` ON disciplines.SubjectID = subjects.ID - INNER JOIN `teachers` ON teachers.ID = disciplines.AuthorID - INNER JOIN `departments` ON departments.ID = teachers.DepartmentID - INNER JOIN `job_positions` ON job_positions.ID = teachers.JobPositionID - INNER JOIN `semesters` ON semesters.ID = curSem - WHERE study_groups.ID = StudyGroupID - LIMIT 1; -END // - --- -1 - РЅРµ сотрудник деканата Рё РЅРµ преподаватель дисциплины --- 0 - только чтение --- 1 - редактирование -DROP FUNCTION IF EXISTS GetEditRightsForTeacher// -CREATE FUNCTION `GetEditRightsForTeacher` ( `TeacherID` INT, - `DisciplineID` INT - ) RETURNS int(11) - NO SQL -BEGIN - DECLARE userRole INT; - DECLARE countDiscTeacher INT; - - SELECT UserRoleID INTO userRole - FROM teachers - JOIN accounts ON teachers.AccountID=accounts.ID - WHERE teachers.ID=TeacherID; - - - SELECT COUNT(*) INTO countDiscTeacher - FROM disciplines_teachers - WHERE disciplines_teachers.DisciplineID=DisciplineID AND - disciplines_teachers.TeacherID=TeacherID; - - if userRole=4 AND countDiscTeacher=0 THEN -- 4 - сотрудник деканата - RETURN 0; - END IF; - - IF countDiscTeacher=0 THEN - return -1; - END IF; - - RETURN 1; -END // - -DROP PROCEDURE IF EXISTS CreateFaculty // -CREATE PROCEDURE CreateFaculty (IN pFacultyName VARCHAR(100) CHARSET utf8, IN pFacultyAbbr VARCHAR(20) CHARSET utf8) - NO SQL -BEGIN - INSERT INTO faculties (Name, Abbr) - VALUES(pFacultyName, pFacultyAbbr); -END // - -DROP PROCEDURE IF EXISTS GetSession // -CREATE PROCEDURE GetSession (IN pID INT(11), OUT pSessionID VARCHAR(40), OUT pUserLogin VARCHAR(50) CHARSET utf8, OUT pUserPassword VARCHAR(64)) - NO SQL -BEGIN - - SELECT SessionID, Login, Password - INTO pSessionID, pUserLogin, pUserPassword - FROM sessions - WHERE sessions.ID=pID; -END // - -DROP FUNCTION IF EXISTS DeleteSubject // -CREATE FUNCTION DeleteSubject (pSubjectID INT) RETURNS INT(11) - NO SQL -BEGIN - DECLARE discCount INT; - SELECT COUNT(*) INTO discCount - FROM disciplines - WHERE disciplines.SubjectID=pSubjectID; - IF discCount>0 THEN - RETURN -1; -- "Удаляемый предмет используется РІ disciplines."; - END IF; - DELETE FROM subjects_faculties - WHERE subjects_faculties.SubjectID=pSubjectID; - DELETE FROM subjects - WHERE subjects.ID=pSubjectID; - RETURN 0; -- "Успешно удалено."; -END // - -DROP FUNCTION IF EXISTS CreateDepartment // -CREATE FUNCTION CreateDepartment(pName VARCHAR(200) CHARSET utf8, pFacultyID INT(11)) RETURNS INT(11) - NO SQL -BEGIN - DECLARE facultyExist INT; - SELECT COUNT(*) INTO facultyExist - FROM faculties - WHERE faculties.ID=pFacultyID; - IF facultyExist>0 THEN - INSERT INTO departments (Name, FacultyID) VALUES(pName, pFacultyID); - RETURN 0; - END IF; - RETURN -1; -END // - -DROP FUNCTION IF EXISTS SaveSession // -CREATE FUNCTION SaveSession(pSessionID VARCHAR(40), pUserLogin VARCHAR(50) CHARSET utf8, pUserPassword VARCHAR(64)) RETURNS INT(11) - NO SQL -BEGIN - INSERT INTO sessions (SessionID, Login, Password) - VALUES(pSessionID, pUserLogin, pUserPassword); - RETURN LAST_INSERT_ID();; -END // - DELIMITER ; \ No newline at end of file diff --git a/db/Structure.sql b/db/Structure.sql index 8b47593d7e457c389550dc24c127e4934f27f400..b2f78647d2bb42a570f44fedc49232de4319ed9e 100644 --- a/db/Structure.sql +++ b/db/Structure.sql @@ -30,12 +30,12 @@ SET time_zone = "+00:00"; CREATE TABLE IF NOT EXISTS `accounts` ( `ID` int(11) NOT NULL AUTO_INCREMENT, - `Login` varchar(50) DEFAULT NULL, - `Password` varchar(64) DEFAULT NULL, - `EMail` varchar(255) DEFAULT NULL, + `Login` varchar(50) CHARACTER SET utf8 DEFAULT NULL, + `Password` varchar(64) CHARACTER SET utf8 DEFAULT NULL, + `EMail` varchar(255) CHARACTER SET utf8 DEFAULT NULL, `UserRoleID` int(11) NOT NULL, - `ActivationCode` varchar(40) DEFAULT NULL, - `isEnabled` tinyint(1) NOT NULL DEFAULT '1', + `ActivationCode` varchar(40) CHARACTER SET utf8 DEFAULT NULL, + `IsEnabled` tinyint(1) NOT NULL DEFAULT '1', `UserAgent` text, `Notification` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`ID`), @@ -53,7 +53,7 @@ CREATE TABLE IF NOT EXISTS `accounts` ( CREATE TABLE IF NOT EXISTS `job_positions` ( `ID` int(11) NOT NULL AUTO_INCREMENT, - `Name` varchar(200) NOT NULL, + `Name` varchar(200) CHARACTER SET utf8 NOT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `Name` (`Name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -66,7 +66,7 @@ CREATE TABLE IF NOT EXISTS `job_positions` ( CREATE TABLE IF NOT EXISTS `departments` ( `ID` int(11) NOT NULL AUTO_INCREMENT, - `Name` varchar(200) NULL, + `Name` varchar(200) CHARACTER SET utf8 NULL, `FacultyID` int(11) NOT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `Name` (`Name`,`FacultyID`), @@ -87,11 +87,11 @@ CREATE TABLE IF NOT EXISTS `disciplines` ( `ExamType` enum('exam','credit') NOT NULL, `SemesterID` int(11) NOT NULL, `PracticeCount` int(11) NOT NULL DEFAULT '0', - `LectionCount` int(11) NOT NULL DEFAULT '0', + `LectureCount` int(11) NOT NULL DEFAULT '0', `LabCount` int(11) NOT NULL DEFAULT '0', `FacultyID` int(11) NOT NULL, -- isLocked (for editing structure) - `isLocked` tinyint(1) NOT NULL DEFAULT '0', + `IsLocked` tinyint(1) NOT NULL DEFAULT '0', -- isOver semester time (or is session time) `isMilestone` tinyint(1) NOT NULL DEFAULT '0', `MilestoneDate` DATE NULL DEFAULT NULL, @@ -112,11 +112,11 @@ CREATE TABLE IF NOT EXISTS `disciplines` ( CREATE TABLE IF NOT EXISTS `disciplines_groups` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `DisciplineID` int(11) NOT NULL, - `StudyGroupID` int(11) NOT NULL, + `GroupID` int(11) NOT NULL, PRIMARY KEY (`ID`), - UNIQUE KEY `DisciplineID_2` (`DisciplineID`,`StudyGroupID`), + UNIQUE KEY `DisciplineID_2` (`DisciplineID`,`GroupID`), KEY `DisciplineID` (`DisciplineID`), - KEY `StudyGroupID` (`StudyGroupID`) + KEY `GroupID` (`GroupID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- @@ -160,8 +160,8 @@ CREATE TABLE IF NOT EXISTS `disciplines_teachers` ( CREATE TABLE IF NOT EXISTS `faculties` ( `ID` int(11) NOT NULL AUTO_INCREMENT, - `Name` varchar(100) NOT NULL, - `Abbr` varchar(20) NOT NULL, + `Name` varchar(100) CHARACTER SET utf8 NOT NULL, + `Abbr` varchar(20) CHARACTER SET utf8 NOT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `Name` (`Name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -175,7 +175,8 @@ CREATE TABLE IF NOT EXISTS `faculties` ( CREATE TABLE IF NOT EXISTS `general_settings` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `Val` int(11) DEFAULT NULL, - `ValS` varchar(300) DEFAULT NULL, + `ValS` varchar(300) CHARACTER SET utf8 DEFAULT NULL, + `Name` varchar(50) CHARACTER SET utf8 NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -227,7 +228,7 @@ CREATE TABLE IF NOT EXISTS `logs_signin` ( CREATE TABLE IF NOT EXISTS `modules` ( `ID` int(11) NOT NULL AUTO_INCREMENT, - `Name` varchar(200) NOT NULL, + `Name` varchar(200) CHARACTER SET utf8 NOT NULL, `OrderNum` int(11) NOT NULL, `DisciplineID` int(11) NOT NULL, `Type` enum('regular','exam', 'bonus', 'extra') NOT NULL DEFAULT 'regular', @@ -244,7 +245,7 @@ CREATE TABLE IF NOT EXISTS `modules` ( CREATE TABLE IF NOT EXISTS `page_access` ( `ID` int(11) NOT NULL AUTO_INCREMENT, - `Pagename` text NOT NULL, + `Pagename` text CHARACTER SET utf8 NOT NULL, `Bitmask` int(11) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -279,8 +280,8 @@ CREATE TABLE IF NOT EXISTS `rating_table` ( CREATE TABLE IF NOT EXISTS `requests` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `AccountID` int(11) DEFAULT NULL, - `Title` varchar(50) NULL DEFAULT NULL, - `Description` text NOT NULL, + `Title` varchar(50) CHARACTER SET utf8 NULL DEFAULT NULL, + `Description` text CHARACTER SET utf8 NOT NULL, `Date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `Status` enum('opened','processed','closed') NOT NULL DEFAULT 'opened', PRIMARY KEY (`ID`), @@ -346,9 +347,9 @@ CREATE TABLE IF NOT EXISTS `semesters` ( CREATE TABLE IF NOT EXISTS `specializations` ( `ID` int(11) NOT NULL AUTO_INCREMENT, - `Name` varchar(50) NULL, - `Abbr` varchar(20) NULL, - `Code` varchar(12) NULL, + `Name` varchar(200) CHARACTER SET utf8 NULL, + `Abbr` varchar(20) CHARACTER SET utf8 NULL, + `Code` varchar(12) CHARACTER SET utf8 NULL, `FacultyID` int(11) NOT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `Name` (`Name`,`FacultyID`), @@ -363,13 +364,11 @@ CREATE TABLE IF NOT EXISTS `specializations` ( CREATE TABLE IF NOT EXISTS `students` ( `ID` int(11) NOT NULL AUTO_INCREMENT, - `StudyGroupID` int(11) NOT NULL, `AccountID` int(11) NOT NULL, - `LastName` varchar(30) NOT NULL, - `FirstName` varchar(30) NOT NULL, - `SecondName` varchar(30) DEFAULT NULL, + `LastName` varchar(30) CHARACTER SET utf8 NOT NULL, + `FirstName` varchar(30) CHARACTER SET utf8 NOT NULL, + `SecondName` varchar(30) CHARACTER SET utf8 DEFAULT NULL, PRIMARY KEY (`ID`), - KEY `StudyGroupID` (`StudyGroupID`), KEY `AccountID` (`AccountID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -384,11 +383,11 @@ CREATE TABLE IF NOT EXISTS `study_groups` ( `GradeID` int(11) NOT NULL, `GroupNum` int(11) NOT NULL, `SpecializationID` int(11) NOT NULL, - `Name` varchar(50) DEFAULT NULL, + `Name` varchar(50) CHARACTER SET utf8 DEFAULT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `GradeID_2` (`GradeID`,`GroupNum`,`SpecializationID`), KEY `GradeID` (`GradeID`), - KEY `SpecializtionID` (`SpecializationID`) + KEY `SpecializationID` (`SpecializationID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -------------------------------------------------------- @@ -399,8 +398,8 @@ CREATE TABLE IF NOT EXISTS `study_groups` ( CREATE TABLE IF NOT EXISTS `subjects` ( `ID` int(11) NOT NULL AUTO_INCREMENT, - `Name` varchar(200) NOT NULL, - `Abbr` varchar(20) DEFAULT NULL, + `Name` varchar(200) CHARACTER SET utf8 NOT NULL, + `Abbr` varchar(20) CHARACTER SET utf8 DEFAULT NULL, PRIMARY KEY (`ID`), UNIQUE KEY `Name` (`Name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -434,8 +433,8 @@ CREATE TABLE IF NOT EXISTS `submodules` ( `MaxRate` int(11) NOT NULL, `OrderNum` int(11) NOT NULL, `Name` varchar(200) NOT NULL, - `Description` varchar(200) DEFAULT NULL, - `isUsed` tinyint(1) NOT NULL DEFAULT 0, + `Description` varchar(200) CHARACTER SET utf8 DEFAULT NULL, + `IsUsed` tinyint(1) NOT NULL DEFAULT 0, `Type` enum('CurrentControl','LandmarkControl') NOT NULL DEFAULT 'CurrentControl', PRIMARY KEY (`ID`), UNIQUE KEY `ModuleID_2` (`ModuleID`,`OrderNum`), @@ -468,9 +467,9 @@ CREATE TABLE IF NOT EXISTS `grades` ( CREATE TABLE IF NOT EXISTS `teachers` ( `ID` int(11) NOT NULL AUTO_INCREMENT, - `LastName` varchar(30) NOT NULL, - `FirstName` varchar(30) NOT NULL, - `SecondName` varchar(30) DEFAULT NULL, + `LastName` varchar(30) CHARACTER SET utf8 NOT NULL, + `FirstName` varchar(30) CHARACTER SET utf8 NOT NULL, + `SecondName` varchar(30) CHARACTER SET utf8 DEFAULT NULL, `JobPositionID` int(11) NOT NULL, `DepartmentID` int(11) NULL, `AccountID` int(11) NOT NULL, @@ -486,10 +485,11 @@ CREATE TABLE IF NOT EXISTS `teachers` ( -- Структура таблицы `user_roles` -- +# TODO: just name CREATE TABLE IF NOT EXISTS `user_roles` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `Type` enum('student','teacher') NOT NULL, - `RoleName` varchar(30) NOT NULL, + `RoleName` varchar(30) CHARACTER SET utf8 NOT NULL, `Mark` int(11) NOT NULL, PRIMARY KEY (`ID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -505,8 +505,8 @@ CREATE TABLE IF NOT EXISTS `recovery_tokens` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `AccountID` int(11) NOT NULL, `Date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `Token` varchar(100) NOT NULL, - `isUsed` tinyint(1) NOT NULL DEFAULT '0', + `Token` varchar(100) CHARACTER SET utf8 NOT NULL, + `IsUsed` tinyint(1) NOT NULL DEFAULT '0', PRIMARY KEY (`ID`), KEY `AccountID` (`AccountID`), UNIQUE KEY `Token` (`Token`) @@ -514,6 +514,27 @@ CREATE TABLE IF NOT EXISTS `recovery_tokens` ( +-- -------------------------------------------------------- + +-- +-- Структура таблицы `students_groups` +-- +CREATE TABLE IF NOT EXISTS `students_groups` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `StudentID` int(11) NOT NULL, + `GroupID` int(11) NOT NULL, + `SemesterID` int(11) NOT NULL, + `IsStudyLeave` tinyint(1) NOT NULL DEFAULT '0', + `Date` date NULL DEFAULT NULL, + PRIMARY KEY (`ID`), + UNIQUE KEY `StudentID_2` (`StudentID`,`GroupID`,`SemesterID`), + KEY `SemesterID` (`SemesterID`), + KEY `StudentID` (`StudentID`), + KEY `GroupID` (`GroupID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + + -- -- Дамп данных таблицы `user_roles` -- @@ -600,7 +621,7 @@ ALTER TABLE `disciplines` -- ALTER TABLE `disciplines_groups` ADD CONSTRAINT `disciplines_groups_ibfk_1` FOREIGN KEY (`DisciplineID`) REFERENCES `disciplines` (`ID`), - ADD CONSTRAINT `disciplines_groups_ibfk_2` FOREIGN KEY (`StudyGroupID`) REFERENCES `study_groups` (`ID`); + ADD CONSTRAINT `disciplines_groups_ibfk_2` FOREIGN KEY (`GroupID`) REFERENCES `study_groups` (`ID`); -- -- Ограничения внешнего ключа таблицы `disciplines_students` @@ -672,7 +693,6 @@ ALTER TABLE `specializations` -- Ограничения внешнего ключа таблицы `students` -- ALTER TABLE `students` - ADD CONSTRAINT `students_ibfk_1` FOREIGN KEY (`StudyGroupID`) REFERENCES `study_groups` (`ID`), ADD CONSTRAINT `students_ibfk_2` FOREIGN KEY (`AccountID`) REFERENCES `accounts` (`ID`); -- @@ -705,6 +725,15 @@ ALTER TABLE `subjects_faculties` ADD CONSTRAINT `subjects_faculties_ibfk_2` FOREIGN KEY (`SubjectID`) REFERENCES `subjects` (`ID`); +-- +-- Ограничения внешнего ключа таблицы `students_groups` +-- +ALTER TABLE `students_groups` + ADD CONSTRAINT `students_groups_ibfk_1` FOREIGN KEY (`StudentID`) REFERENCES `students` (`ID`), + ADD CONSTRAINT `students_groups_ibfk_2` FOREIGN KEY (`GroupID`) REFERENCES `study_groups` (`ID`), + ADD CONSTRAINT `students_groups_ibfk_3` FOREIGN KEY (`SemesterID`) REFERENCES `semesters` (`ID`); + + /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; diff --git a/db/Views.sql b/db/Views.sql new file mode 100644 index 0000000000000000000000000000000000000000..7f1b77da8becdcbfc88c37fef9cd82e629fe4860 --- /dev/null +++ b/db/Views.sql @@ -0,0 +1,158 @@ + + + +CREATE OR REPLACE VIEW `view_groups` AS + SELECT study_groups.ID AS 'GroupID', + study_groups.GroupNum AS 'GroupNum', + study_groups.Name AS 'GroupName', + grades.ID AS 'GradeID', + grades.Num AS 'GradeNum', + grades.Degree AS 'Degree', + specializations.ID AS 'SpecID', + specializations.Name AS 'SpecName', + specializations.Abbr AS 'SpecAbbr', + specializations.Code AS 'SpecCode', + faculties.ID AS 'FacultyID', + faculties.Name AS 'FacultyName', + faculties.Abbr AS 'FacultyAbbr' + FROM `study_groups` + INNER JOIN `specializations` ON study_groups.SpecializationID = specializations.ID + INNER JOIN `grades` ON study_groups.GradeID = grades.ID + INNER JOIN `faculties` ON faculties.ID = specializations.FacultyID; + + +CREATE OR REPLACE VIEW `view_teachers` AS + SELECT teachers.ID AS 'TeacherID', + teachers.LastName, + teachers.FirstName, + teachers.SecondName, + teachers.AccountID, + job_positions.ID AS 'JobPositionID', + job_positions.Name AS 'JobPositionName', + departments.ID AS 'DepID', + departments.Name AS 'DepName', + faculties.ID AS 'FacultyID', + faculties.Name AS 'FacultyName', + faculties.Abbr AS 'FacultyAbbr' + FROM `teachers` + INNER JOIN `departments` ON departments.ID = teachers.DepartmentID + INNER JOIN `faculties` ON departments.FacultyID = faculties.ID + INNER JOIN `job_positions` ON job_positions.ID = teachers.JobPositionID; + + +CREATE OR REPLACE VIEW `view_students` AS + SELECT students.ID AS 'StudentID', + students.LastName, + students.FirstName, + students.SecondName, + students.AccountID, + students_groups.SemesterID, + view_groups.* + FROM `students` + LEFT JOIN `students_groups` ON students_groups.StudentID = students.ID + INNER JOIN `view_groups` ON view_groups.GroupID = students_groups.GroupID; + + +CREATE OR REPLACE VIEW `view_disciplines` AS + SELECT disciplines.ID AS 'DisciplineID', + disciplines.AuthorID, + disciplines.ExamType, + disciplines.LectureCount, + disciplines.PracticeCount, + disciplines.LabCount, + disciplines.SemesterID, + disciplines.IsLocked, + disciplines.isMilestone, + grades.ID AS 'GradeID', + grades.Num AS 'GradeNum', + grades.Degree, + subjects.ID AS 'SubjectID', + subjects.Name AS 'SubjectName', + subjects.Abbr AS 'SubjectAbbr', + faculties.ID AS 'FacultyID', + faculties.Name AS 'FacultyName', + faculties.Abbr AS 'FacultyAbbr' + FROM `disciplines` + INNER JOIN `subjects` ON subjects.ID = disciplines.SubjectID + INNER JOIN `faculties` ON faculties.ID = disciplines.FacultyID + INNER JOIN `grades` ON grades.ID = disciplines.GradeID; + + +CREATE OR REPLACE VIEW `view_disciplines_results` AS + SELECT disciplines.ID AS 'DisciplineID', + SUM(submodules.MaxRate) AS 'DisciplineRateMax', + SUM(submodules.MaxRate*submodules.IsUsed) AS 'DisciplineRateCur' + FROM `submodules` + INNER JOIN `modules` ON modules.ID = submodules.ModuleID + RIGHT JOIN `disciplines` ON disciplines.ID = modules.DisciplineID + WHERE (modules.Type = 'regular') OR (modules.Type = 'exam' AND submodules.OrderNum = 1) + GROUP BY disciplines.ID; + + +CREATE OR REPLACE VIEW `view_disciplines_teachers` AS + SELECT view_disciplines.DisciplineID, + view_teachers.*, + (view_disciplines.AuthorID = view_teachers.TeacherID) AS 'IsAuthor' + FROM `view_disciplines` + LEFT JOIN `disciplines_teachers` ON disciplines_teachers.DisciplineID = view_disciplines.DisciplineID + INNER JOIN `view_teachers` ON view_teachers.TeacherID = disciplines_teachers.TeacherID; + + +CREATE OR REPLACE VIEW `view_disciplines_students` AS + (SELECT disciplines_students.DisciplineID, + disciplines_students.Type AS 'AttachType', + view_students.* + FROM `disciplines_students` + INNER JOIN `view_students` ON view_students.StudentID = disciplines_students.StudentID + ) UNION + (SELECT disciplines_groups.DisciplineID, + NULL AS 'AttachType', + view_students.* + FROM `disciplines_groups` + LEFT JOIN `view_students` ON view_students.GroupID = disciplines_groups.GroupID + WHERE NOT EXISTS + (SELECT disciplines_students.StudentID + FROM `disciplines_students` + WHERE disciplines_students.DisciplineID = disciplines_groups.DisciplineID AND + disciplines_students.StudentID = view_students.StudentID + ) + ); + + +CREATE OR REPLACE VIEW `view_roadmap` AS + SELECT modules.DisciplineID, + modules.ID AS 'ModuleID', + modules.Name AS 'ModuleName', + modules.OrderNum AS 'ModuleOrderNum', + modules.Type AS 'ModuleType', + # enum('regular','exam', 'bonus', 'extra') + submodules.ID AS 'SubmoduleID', + submodules.Name AS 'SubmoduleName', + submodules.OrderNum AS 'SubmoduleOrderNum', + submodules.MaxRate AS 'SubmoduleRate', + submodules.Type AS 'SubmoduleType', + # enum('CurrentControl','LandmarkControl') + submodules.IsUsed AS 'SubmoduleIsUsed' + FROM `modules` + LEFT JOIN `submodules` ON submodules.ModuleID = modules.ID; + + +# without students, that haven't any rate +CREATE OR REPLACE VIEW `view_rating_result` AS + SELECT rating_table.StudentID, + view_roadmap.DisciplineID, + SUM(rating_table.Rate*(view_roadmap.ModuleType = 'regular')) AS 'RateRegular', + SUM(rating_table.Rate*(view_roadmap.ModuleType = 'extra')) AS 'RateExtra', + SUM(rating_table.Rate*(view_roadmap.ModuleType = 'bonus')) AS 'RateBonus', + (SELECT rating_table.Rate*(view_roadmap.ModuleType = 'exam') + ORDER BY view_roadmap.ModuleType = 'exam' DESC, + (rating_table.Rate IS NULL) ASC, + view_roadmap.SubmoduleOrderNum DESC + LIMIT 1 + ) AS 'RateExam' + FROM `rating_table` + LEFT JOIN `view_roadmap` ON view_roadmap.SubmoduleID = rating_table.SubmoduleID + GROUP BY rating_table.StudentID, view_roadmap.DisciplineID; + + + diff --git a/db/duplicate.sql b/db/duplicate.sql new file mode 100644 index 0000000000000000000000000000000000000000..a1f2cff3e5b3b4392dbb59f9a247ad26c5465d45 --- /dev/null +++ b/db/duplicate.sql @@ -0,0 +1,49 @@ +# Выборка всех студентов, СЃ повторяющимися именами +SELECT distinct st1.* +FROM students as st1 +WHERE ( + SELECT count(*) from students as st + where CONCAT( st.LastName, st.FirstName, st.SecondName ) + LIKE CONCAT( st1.LastName, st1.FirstName, st1.SecondName) + ) > 1 +ORDER BY LastName + + +# выборка всех оценок для студента (СЃ учетом повторений) +SELECT students.ID AS "StudentID", students.LastName, rating_table . * + FROM students + LEFT JOIN rating_table ON rating_table.StudentID = students.ID + WHERE CONCAT( students.LastName, students.FirstName, students.SecondName ) LIKE ( + SELECT CONCAT( st.LastName, st.FirstName, st.SecondName ) + FROM students AS st + WHERE st.id =133 + ) +ORDER BY SubmoduleID + + + +# студенты, повторно привязанные Рє дисциплинам +SELECT students.ID as "StudentID", + students.LastName, + disciplines_students.ID as "disciplines_studentsID" +FROM students +left join disciplines_students on disciplines_students.StudentID = students.ID +WHERE CONCAT( students.LastName, students.FirstName, students.SecondName) LIKE ( + SELECT CONCAT( st.LastName, st.FirstName, st.SecondName ) + from students as st + where st.id = 133 + ) + + +# дублирование оценок +SELECT distinct st1.*, rating_table.SubmoduleID, count(*) as "cnt" +FROM students as st1 +LEFT JOIN rating_table on rating_table.StudentID = st1.ID +WHERE CONCAT( st1.LastName, st1.FirstName, st1.SecondName ) LIKE ( + SELECT CONCAT( st.LastName, st.FirstName, st.SecondName ) + FROM students AS st + WHERE st.id = # studentID + ) +GROUP BY st1.LastName, rating_table.SubmoduleID +ORDER BY cnt desc + diff --git a/db/fix.sql b/db/fix.sql index 3d6f5397af826e2a11f84196f382572c600073fd..462e6ca338056b64dfd6111f78af9b288267375d 100644 --- a/db/fix.sql +++ b/db/fix.sql @@ -1,5 +1,88 @@ -DELETE FROM `submodules` WHERE submodules.ModuleID IN - ( SELECT modules.ID - from `modules` - where (modules.Type = 'exam' OR modules.Type = 'extra') - ) AND submodules.OrderNum > 3 +# 5.03.15 - db refactoring + +ALTER TABLE `disciplines` CHANGE LectionCount LectureCount int(11) NOT NULL DEFAULT '0'; + +ALTER TABLE students DROP FOREIGN KEY students_ibfk_1; +ALTER TABLE disciplines_groups DROP FOREIGN KEY disciplines_groups_ibfk_2; + +ALTER TABLE students DROP KEY StudyGroupID; +ALTER TABLE disciplines_groups DROP KEY DisciplineID_2; +ALTER TABLE disciplines_groups DROP KEY StudyGroupID; + +ALTER TABLE `students` CHANGE StudyGroupID GroupID int(11) NOT NULL; +ALTER TABLE `disciplines_groups` CHANGE StudyGroupID GroupID int(11) NOT NULL; + +ALTER TABLE `students` ADD INDEX `GroupID` (`GroupID`); +ALTER TABLE `disciplines_groups` ADD INDEX `GroupID` (`GroupID`); +ALTER TABLE `disciplines_groups` ADD UNIQUE KEY `DisciplineID_2` (`DisciplineID`,`GroupID`); + + +ALTER TABLE `disciplines_groups` +ADD CONSTRAINT `disciplines_groups_ibfk_2` FOREIGN KEY (`GroupID`) REFERENCES `study_groups` (`ID`); +ALTER TABLE `students` +ADD CONSTRAINT `students_ibfk_1` FOREIGN KEY (`GroupID`) REFERENCES `study_groups` (`ID`); + + +ALTER TABLE `page_access` +CHANGE `Pagename` `Pagename` VARCHAR(150) CHARACTER SET utf8 NOT NULL ; + +ALTER TABLE `page_access` ADD UNIQUE (`Pagename`); +ALTER TABLE `accounts` ADD UNIQUE (`ActivationCode`); + + +ALTER TABLE `general_settings` ADD `Name` VARCHAR(50) CHARACTER SET utf8 NOT NULL ; +UPDATE `general_settings` SET general_settings.Name = 'SemesterID' WHERE general_settings.ID = 1; +UPDATE `general_settings` SET general_settings.Name = 'HashKey' WHERE general_settings.ID = 2; +ALTER TABLE `general_settings` ADD UNIQUE (`Name`); + +# just for fun :/ +UPDATE `modules` +SET modules.OrderNum = 3141592 +WHERE modules.OrderNum = 3141692; + + + + +# 15.03.15 - student's groups memorization + +CREATE TABLE IF NOT EXISTS `students_groups` ( + `ID` int(11) NOT NULL AUTO_INCREMENT, + `StudentID` int(11) NOT NULL, + `GroupID` int(11) NOT NULL, + `SemesterID` int(11) NOT NULL, + `IsStudyLeave` tinyint(1) NOT NULL DEFAULT '0', + `Date` date NULL, + PRIMARY KEY (`ID`), + UNIQUE KEY `StudentID_2` (`StudentID`,`GroupID`,`SemesterID`), + KEY `SemesterID` (`SemesterID`), + KEY `StudentID` (`StudentID`), + KEY `GroupID` (`GroupID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + +# constraints +ALTER TABLE `students_groups` + ADD CONSTRAINT `students_groups_ibfk_1` FOREIGN KEY (`StudentID`) REFERENCES `students` (`ID`), + ADD CONSTRAINT `students_groups_ibfk_2` FOREIGN KEY (`GroupID`) REFERENCES `study_groups` (`ID`), + ADD CONSTRAINT `students_groups_ibfk_3` FOREIGN KEY (`SemesterID`) REFERENCES `semesters` (`ID`); + +# save groups +INSERT INTO `students_groups` (StudentID, GroupID, SemesterID) +SELECT DISTINCT students.ID, students.GroupID, semesters.ID + FROM `students` + CROSS JOIN `semesters`; + +# clear useless data +ALTER TABLE `students` DROP FOREIGN KEY `students_ibfk_1` ; +ALTER TABLE `students` DROP INDEX `GroupID` ; +ALTER TABLE `students` DROP `GroupID` ; + + +# 13.04.15 + +ALTER TABLE `students_groups` CHANGE IsStudyLeave `IsStudyLeave` tinyint(1) NOT NULL DEFAULT '0' ; + +# 11.05.15 + +ALTER TABLE `specializations` CHANGE Name `Name` varchar(200) CHARACTER SET utf8 NULL; + diff --git a/db/release_gen_mmcs_sg.sql b/db/release_gen_mmcs_sg.sql index da3b0e776cf2ba34c4740ca9855d2cde38494eea..e234dfef4f4515ff5f0b3cd0aca78c0c4350ff0b 100644 --- a/db/release_gen_mmcs_sg.sql +++ b/db/release_gen_mmcs_sg.sql @@ -1,4 +1,4 @@ -INSERT INTO `grades` (`ID`, `Grade`, `Degree`) VALUES +INSERT INTO `grades` (`ID`, `Num`, `Degree`) VALUES (1, 1, 'bachelor'), (2, 2, 'bachelor'), (3, 3, 'bachelor'), @@ -341,7 +341,7 @@ INSERT INTO `subjects_faculties` (`SubjectID`, `FacultyID`) VALUES -INSERT INTO `accounts` (`ID`, `Login`, `Password`, `EMail`, `UserRoleID`, `ActivationCode`, `isEnabled`, `UserAgent`) VALUES +INSERT INTO `accounts` (`ID`, `Login`, `Password`, `EMail`, `UserRoleID`, `ActivationCode`, `IsEnabled`, `UserAgent`) VALUES (1, NULL, NULL, NULL, 3, 'code', 1, NULL); INSERT INTO `teachers` (`ID`, `LastName`, `FirstName`, `SecondName`, `JobPositionID`, `DepartmentID`, `AccountID`) VALUES diff --git a/doc/dev/index.html b/doc/dev/index.html new file mode 100644 index 0000000000000000000000000000000000000000..70387ac416533088e54a775f7e2c6a048adddee3 --- /dev/null +++ b/doc/dev/index.html @@ -0,0 +1,897 @@ +<!DOCTYPE html><html><head><meta charset="utf-8"><style>body { + width: 45em; + border: 1px solid #ddd; + outline: 1300px solid #fff; + margin: 16px auto; +} + +body .markdown-body +{ + padding: 30px; +} + +@font-face { + font-family: octicons-anchor; + src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff'); +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + color: #333; + overflow: hidden; + font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; + font-size: 16px; + line-height: 1.6; + word-wrap: break-word; +} + +.markdown-body a { + background: transparent; +} + +.markdown-body a:active, +.markdown-body a:hover { + outline: 0; +} + +.markdown-body strong { + font-weight: bold; +} + +.markdown-body h1 { + font-size: 2em; + margin: 0.67em 0; +} + +.markdown-body img { + border: 0; +} + +.markdown-body hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +.markdown-body pre { + overflow: auto; +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre { + font-family: monospace, monospace; + font-size: 1em; +} + +.markdown-body input { + color: inherit; + font: inherit; + margin: 0; +} + +.markdown-body html input[disabled] { + cursor: default; +} + +.markdown-body input { + line-height: normal; +} + +.markdown-body input[type="checkbox"] { + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +.markdown-body table { + border-collapse: collapse; + border-spacing: 0; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body * { + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body input { + font: 13px/1.4 Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; +} + +.markdown-body a { + color: #4183c4; + text-decoration: none; +} + +.markdown-body a:hover, +.markdown-body a:focus, +.markdown-body a:active { + text-decoration: underline; +} + +.markdown-body hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #ddd; +} + +.markdown-body hr:before { + display: table; + content: ""; +} + +.markdown-body hr:after { + display: table; + clear: both; + content: ""; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 15px; + margin-bottom: 15px; + line-height: 1.1; +} + +.markdown-body h1 { + font-size: 30px; +} + +.markdown-body h2 { + font-size: 21px; +} + +.markdown-body h3 { + font-size: 16px; +} + +.markdown-body h4 { + font-size: 14px; +} + +.markdown-body h5 { + font-size: 12px; +} + +.markdown-body h6 { + font-size: 11px; +} + +.markdown-body blockquote { + margin: 0; +} + +.markdown-body ul, +.markdown-body ol { + padding: 0; + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ul ul ol, +.markdown-body ul ol ol, +.markdown-body ol ul ol, +.markdown-body ol ol ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body code { + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body .octicon { + font: normal normal 16px octicons-anchor; + line-height: 1; + display: inline-block; + text-decoration: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.markdown-body .octicon-link:before { + content: '\f05c'; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +.markdown-body .anchor { + position: absolute; + top: 0; + bottom: 0; + left: 0; + display: block; + padding-right: 6px; + padding-left: 30px; + margin-left: -30px; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + position: relative; + margin-top: 1em; + margin-bottom: 16px; + font-weight: bold; + line-height: 1.4; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + display: none; + color: #000; + vertical-align: middle; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + padding-left: 8px; + margin-left: -30px; + line-height: 1; + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + display: inline-block; +} + +.markdown-body h1 { + padding-bottom: 0.3em; + font-size: 2.25em; + line-height: 1.2; + border-bottom: 1px solid #eee; +} + +.markdown-body h2 { + padding-bottom: 0.3em; + font-size: 1.75em; + line-height: 1.225; + border-bottom: 1px solid #eee; +} + +.markdown-body h3 { + font-size: 1.5em; + line-height: 1.43; +} + +.markdown-body h4 { + font-size: 1.25em; +} + +.markdown-body h5 { + font-size: 1em; +} + +.markdown-body h6 { + font-size: 1em; + color: #777; +} + +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body hr { + height: 4px; + padding: 0; + margin: 16px 0; + background-color: #e7e7e7; + border: 0 none; +} + +.markdown-body ul, +.markdown-body ol { + padding-left: 2em; +} + +.markdown-body ul ul, +.markdown-body ul ol, +.markdown-body ol ol, +.markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: bold; +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body blockquote { + padding: 0 15px; + color: #777; + border-left: 4px solid #ddd; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body table { + display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; +} + +.markdown-body table th { + font-weight: bold; +} + +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid #ddd; +} + +.markdown-body table tr { + background-color: #fff; + border-top: 1px solid #ccc; +} + +.markdown-body table tr:nth-child(2n) { + background-color: #f8f8f8; +} + +.markdown-body img { + max-width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body code { + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + margin: 0; + font-size: 85%; + background-color: rgba(0,0,0,0.04); + border-radius: 3px; +} + +.markdown-body code:before, +.markdown-body code:after { + letter-spacing: -0.2em; + content: "\00a0"; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + font-size: 100%; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + border-radius: 3px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body pre { + word-wrap: normal; +} + +.markdown-body pre code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +.markdown-body pre code:before, +.markdown-body pre code:after { + content: normal; +} + +.markdown-body .highlight { + background: #fff; +} + +.markdown-body .highlight .h { + color: #333; + font-style: normal; + font-weight: normal; +} + +.markdown-body .highlight .mf, +.markdown-body .highlight .mh, +.markdown-body .highlight .mi, +.markdown-body .highlight .mo, +.markdown-body .highlight .il, +.markdown-body .highlight .m { + color: #945277; +} + +.markdown-body .highlight .s, +.markdown-body .highlight .sb, +.markdown-body .highlight .sc, +.markdown-body .highlight .sd, +.markdown-body .highlight .s2, +.markdown-body .highlight .se, +.markdown-body .highlight .sh, +.markdown-body .highlight .si, +.markdown-body .highlight .sx, +.markdown-body .highlight .s1 { + color: #df5000; +} + +.markdown-body .highlight .kc, +.markdown-body .highlight .kd, +.markdown-body .highlight .kn, +.markdown-body .highlight .kp, +.markdown-body .highlight .kr, +.markdown-body .highlight .kt, +.markdown-body .highlight .k, +.markdown-body .highlight .o { + font-weight: bold; +} + +.markdown-body .highlight .kt { + color: #458; +} + +.markdown-body .highlight .c, +.markdown-body .highlight .cm, +.markdown-body .highlight .c1 { + color: #998; + font-style: italic; +} + +.markdown-body .highlight .cp, +.markdown-body .highlight .cs, +.markdown-body .highlight .cp .h { + color: #999; + font-weight: bold; +} + +.markdown-body .highlight .cs { + font-style: italic; +} + +.markdown-body .highlight .n { + color: #333; +} + +.markdown-body .highlight .na, +.markdown-body .highlight .nv, +.markdown-body .highlight .vc, +.markdown-body .highlight .vg, +.markdown-body .highlight .vi { + color: #008080; +} + +.markdown-body .highlight .nb { + color: #0086B3; +} + +.markdown-body .highlight .nc { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .no { + color: #094e99; +} + +.markdown-body .highlight .ni { + color: #800080; +} + +.markdown-body .highlight .ne { + color: #990000; + font-weight: bold; +} + +.markdown-body .highlight .nf { + color: #945277; + font-weight: bold; +} + +.markdown-body .highlight .nn { + color: #555; +} + +.markdown-body .highlight .nt { + color: #000080; +} + +.markdown-body .highlight .err { + color: #a61717; + background-color: #e3d2d2; +} + +.markdown-body .highlight .gd { + color: #000; + background-color: #fdd; +} + +.markdown-body .highlight .gd .x { + color: #000; + background-color: #faa; +} + +.markdown-body .highlight .ge { + font-style: italic; +} + +.markdown-body .highlight .gr { + color: #aa0000; +} + +.markdown-body .highlight .gh { + color: #999; +} + +.markdown-body .highlight .gi { + color: #000; + background-color: #dfd; +} + +.markdown-body .highlight .gi .x { + color: #000; + background-color: #afa; +} + +.markdown-body .highlight .go { + color: #888; +} + +.markdown-body .highlight .gp { + color: #555; +} + +.markdown-body .highlight .gs { + font-weight: bold; +} + +.markdown-body .highlight .gu { + color: #800080; + font-weight: bold; +} + +.markdown-body .highlight .gt { + color: #aa0000; +} + +.markdown-body .highlight .ow { + font-weight: bold; +} + +.markdown-body .highlight .w { + color: #bbb; +} + +.markdown-body .highlight .sr { + color: #017936; +} + +.markdown-body .highlight .ss { + color: #8b467f; +} + +.markdown-body .highlight .bp { + color: #999; +} + +.markdown-body .highlight .gc { + color: #999; + background-color: #EAF2F5; +} + +.markdown-body kbd { + background-color: #e7e7e7; + background-image: -webkit-linear-gradient(#fefefe, #e7e7e7); + background-image: linear-gradient(#fefefe, #e7e7e7); + background-repeat: repeat-x; + display: inline-block; + padding: 3px 5px; + font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; + line-height: 10px; + color: #000; + border: 1px solid #cfcfcf; + border-radius: 2px; +} + +.markdown-body .highlight .pl-coc, +.markdown-body .highlight .pl-entm, +.markdown-body .highlight .pl-eoa, +.markdown-body .highlight .pl-mai .pl-sf, +.markdown-body .highlight .pl-pdv, +.markdown-body .highlight .pl-sc, +.markdown-body .highlight .pl-sr, +.markdown-body .highlight .pl-v, +.markdown-body .highlight .pl-vpf { + color: #0086b3; +} + +.markdown-body .highlight .pl-eoac, +.markdown-body .highlight .pl-mdht, +.markdown-body .highlight .pl-mi1, +.markdown-body .highlight .pl-mri, +.markdown-body .highlight .pl-va, +.markdown-body .highlight .pl-vpu { + color: #008080; +} + +.markdown-body .highlight .pl-c, +.markdown-body .highlight .pl-pdc { + color: #b4b7b4; + font-style: italic; +} + +.markdown-body .highlight .pl-k, +.markdown-body .highlight .pl-ko, +.markdown-body .highlight .pl-kolp, +.markdown-body .highlight .pl-mc, +.markdown-body .highlight .pl-mr, +.markdown-body .highlight .pl-ms, +.markdown-body .highlight .pl-s, +.markdown-body .highlight .pl-sok, +.markdown-body .highlight .pl-st { + color: #6e5494; +} + +.markdown-body .highlight .pl-ef, +.markdown-body .highlight .pl-enf, +.markdown-body .highlight .pl-enm, +.markdown-body .highlight .pl-entc, +.markdown-body .highlight .pl-eoi, +.markdown-body .highlight .pl-sf, +.markdown-body .highlight .pl-smc { + color: #d12089; +} + +.markdown-body .highlight .pl-ens, +.markdown-body .highlight .pl-eoai, +.markdown-body .highlight .pl-kos, +.markdown-body .highlight .pl-mh .pl-pdh, +.markdown-body .highlight .pl-mp, +.markdown-body .highlight .pl-pde, +.markdown-body .highlight .pl-stp { + color: #458; +} + +.markdown-body .highlight .pl-enti { + color: #d12089; + font-weight: bold; +} + +.markdown-body .highlight .pl-cce, +.markdown-body .highlight .pl-enc, +.markdown-body .highlight .pl-kou, +.markdown-body .highlight .pl-mq { + color: #f93; +} + +.markdown-body .highlight .pl-mp1 .pl-sf { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .pl-cos, +.markdown-body .highlight .pl-ent, +.markdown-body .highlight .pl-md, +.markdown-body .highlight .pl-mdhf, +.markdown-body .highlight .pl-ml, +.markdown-body .highlight .pl-pdc1, +.markdown-body .highlight .pl-pds, +.markdown-body .highlight .pl-s1, +.markdown-body .highlight .pl-scp, +.markdown-body .highlight .pl-sol { + color: #df5000; +} + +.markdown-body .highlight .pl-c1, +.markdown-body .highlight .pl-cn, +.markdown-body .highlight .pl-pse, +.markdown-body .highlight .pl-pse .pl-s2, +.markdown-body .highlight .pl-vi { + color: #a31515; +} + +.markdown-body .highlight .pl-mb, +.markdown-body .highlight .pl-pdb { + color: #df5000; + font-weight: bold; +} + +.markdown-body .highlight .pl-mi, +.markdown-body .highlight .pl-pdi { + color: #6e5494; + font-style: italic; +} + +.markdown-body .highlight .pl-ms1 { + background-color: #f5f5f5; +} + +.markdown-body .highlight .pl-mdh, +.markdown-body .highlight .pl-mdi { + font-weight: bold; +} + +.markdown-body .highlight .pl-mdr { + color: #0086b3; + font-weight: bold; +} + +.markdown-body .highlight .pl-s2 { + color: #333; +} + +.markdown-body .highlight .pl-ii { + background-color: #df5000; + color: #fff; +} + +.markdown-body .highlight .pl-ib { + background-color: #f93; +} + +.markdown-body .highlight .pl-id { + background-color: #a31515; + color: #fff; +} + +.markdown-body .highlight .pl-iu { + background-color: #b4b7b4; +} + +.markdown-body .highlight .pl-mo { + color: #969896; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 3px; +} + +.markdown-body .task-list-item input { + float: left; + margin: 0.3em 0 0.25em -1.6em; + vertical-align: middle; +}</style><title>index</title></head><body><article class="markdown-body"><h1 id="readme"> +<a id="user-content-readme" class="anchor" href="#readme" aria-hidden="true"><span class="octicon octicon-link"></span></a>README</h1> + +<h2 id="%D0%BF%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BA%D0%B0"> +<a id="user-content-Подготовка" class="anchor" href="#%D0%9F%D0%BE%D0%B4%D0%B3%D0%BE%D1%82%D0%BE%D0%B2%D0%BA%D0%B0" aria-hidden="true"><span class="octicon octicon-link"></span></a>Подготовка</h2> + +<ul> +<li><a href="installation.html#%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%B0">Настройка доступа</a></li> +<li><a href="%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-%D0%BF%D0%BE">Настройка РџРћ</a></li> +<li><a href="%D0%BA%D0%B0%D0%BA-%D0%BF%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-dev_rating">Как поставить dev_rating?</a></li> +</ul> + +<h2 id="unittest"> +<a id="user-content-unittest" class="anchor" href="#unittest" aria-hidden="true"><span class="octicon octicon-link"></span></a>UnitTest</h2> + +<h5 id="phpunit"> +<a id="user-content-phpunit" class="anchor" href="#phpunit" aria-hidden="true"><span class="octicon octicon-link"></span></a>PHPUnit</h5> + +<ul> +<li><a href="testing/phpunit.html">Unit testing</a></li> +<li><a href="testing/phpunit.html#composer">Composer</a></li> +<li><a href="testing/phpunit.html#%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D0%B2%D0%BD%D0%B5-%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B0">Установка РІРЅРµ проекта</a></li> +<li><a href="testing/phpunit.html#%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8F-%D1%81-phpstorm">Рнтеграция СЃ PHPStorm</a></li> +</ul> + +<h5 id="kohana-integration"> +<a id="user-content-kohana-integration" class="anchor" href="#kohana-integration" aria-hidden="true"><span class="octicon octicon-link"></span></a>Kohana integration</h5> + +<ul> +<li><a href="testing/kohana/mockobjects.html#mock-objects">Mock Objects</a></li> +<li><a href="testing/kohana/usage.html#usage">Usage</a></li> +<li><a href="testing/kohana/testing_workflows.html#testing-workflows">Testing workflows</a></li> +<li><a href="testing/kohana/troubleshooting.html#troubleshooting">Troubleshooting</a></li> +</ul> +</article></body></html> \ No newline at end of file diff --git a/doc/dev/index.md b/doc/dev/index.md new file mode 100644 index 0000000000000000000000000000000000000000..64106e5702bef81f66b48c47898fc590615a427f --- /dev/null +++ b/doc/dev/index.md @@ -0,0 +1,22 @@ + +# README + +## Подготовка + +- [Настройка доступа](installation.html#%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%B0) +- [Настройка РџРћ](%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-%D0%BF%D0%BE) +- [Как поставить dev_rating?](%D0%BA%D0%B0%D0%BA-%D0%BF%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-dev_rating) + +## UnitTest + +##### PHPUnit +- [Unit testing](testing/phpunit.html) +- [Composer](testing/phpunit.html#composer) +- [Установка РІРЅРµ проекта](testing/phpunit.html#%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D0%B2%D0%BD%D0%B5-%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B0) +- [Рнтеграция СЃ PHPStorm](testing/phpunit.html#%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8F-%D1%81-phpstorm) + +##### Kohana integration +- [Mock Objects](testing/kohana/mockobjects.html#mock-objects) +- [Usage](testing/kohana/usage.html#usage) +- [Testing workflows](testing/kohana/testing_workflows.html#testing-workflows) +- [Troubleshooting](testing/kohana/troubleshooting.html#troubleshooting) diff --git a/doc/dev/installation.html b/doc/dev/installation.html new file mode 100644 index 0000000000000000000000000000000000000000..b49f7bb10a689a24baaf7b2150ec02710f81bc86 --- /dev/null +++ b/doc/dev/installation.html @@ -0,0 +1,949 @@ +<!DOCTYPE html><html><head><meta charset="utf-8"><style>body { + width: 45em; + border: 1px solid #ddd; + outline: 1300px solid #fff; + margin: 16px auto; +} + +body .markdown-body +{ + padding: 30px; +} + +@font-face { + font-family: octicons-anchor; + src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff'); +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + color: #333; + overflow: hidden; + font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; + font-size: 16px; + line-height: 1.6; + word-wrap: break-word; +} + +.markdown-body a { + background: transparent; +} + +.markdown-body a:active, +.markdown-body a:hover { + outline: 0; +} + +.markdown-body strong { + font-weight: bold; +} + +.markdown-body h1 { + font-size: 2em; + margin: 0.67em 0; +} + +.markdown-body img { + border: 0; +} + +.markdown-body hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +.markdown-body pre { + overflow: auto; +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre { + font-family: monospace, monospace; + font-size: 1em; +} + +.markdown-body input { + color: inherit; + font: inherit; + margin: 0; +} + +.markdown-body html input[disabled] { + cursor: default; +} + +.markdown-body input { + line-height: normal; +} + +.markdown-body input[type="checkbox"] { + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +.markdown-body table { + border-collapse: collapse; + border-spacing: 0; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body * { + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body input { + font: 13px/1.4 Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; +} + +.markdown-body a { + color: #4183c4; + text-decoration: none; +} + +.markdown-body a:hover, +.markdown-body a:focus, +.markdown-body a:active { + text-decoration: underline; +} + +.markdown-body hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #ddd; +} + +.markdown-body hr:before { + display: table; + content: ""; +} + +.markdown-body hr:after { + display: table; + clear: both; + content: ""; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 15px; + margin-bottom: 15px; + line-height: 1.1; +} + +.markdown-body h1 { + font-size: 30px; +} + +.markdown-body h2 { + font-size: 21px; +} + +.markdown-body h3 { + font-size: 16px; +} + +.markdown-body h4 { + font-size: 14px; +} + +.markdown-body h5 { + font-size: 12px; +} + +.markdown-body h6 { + font-size: 11px; +} + +.markdown-body blockquote { + margin: 0; +} + +.markdown-body ul, +.markdown-body ol { + padding: 0; + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ul ul ol, +.markdown-body ul ol ol, +.markdown-body ol ul ol, +.markdown-body ol ol ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body code { + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body .octicon { + font: normal normal 16px octicons-anchor; + line-height: 1; + display: inline-block; + text-decoration: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.markdown-body .octicon-link:before { + content: '\f05c'; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +.markdown-body .anchor { + position: absolute; + top: 0; + bottom: 0; + left: 0; + display: block; + padding-right: 6px; + padding-left: 30px; + margin-left: -30px; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + position: relative; + margin-top: 1em; + margin-bottom: 16px; + font-weight: bold; + line-height: 1.4; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + display: none; + color: #000; + vertical-align: middle; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + padding-left: 8px; + margin-left: -30px; + line-height: 1; + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + display: inline-block; +} + +.markdown-body h1 { + padding-bottom: 0.3em; + font-size: 2.25em; + line-height: 1.2; + border-bottom: 1px solid #eee; +} + +.markdown-body h2 { + padding-bottom: 0.3em; + font-size: 1.75em; + line-height: 1.225; + border-bottom: 1px solid #eee; +} + +.markdown-body h3 { + font-size: 1.5em; + line-height: 1.43; +} + +.markdown-body h4 { + font-size: 1.25em; +} + +.markdown-body h5 { + font-size: 1em; +} + +.markdown-body h6 { + font-size: 1em; + color: #777; +} + +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body hr { + height: 4px; + padding: 0; + margin: 16px 0; + background-color: #e7e7e7; + border: 0 none; +} + +.markdown-body ul, +.markdown-body ol { + padding-left: 2em; +} + +.markdown-body ul ul, +.markdown-body ul ol, +.markdown-body ol ol, +.markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: bold; +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body blockquote { + padding: 0 15px; + color: #777; + border-left: 4px solid #ddd; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body table { + display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; +} + +.markdown-body table th { + font-weight: bold; +} + +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid #ddd; +} + +.markdown-body table tr { + background-color: #fff; + border-top: 1px solid #ccc; +} + +.markdown-body table tr:nth-child(2n) { + background-color: #f8f8f8; +} + +.markdown-body img { + max-width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body code { + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + margin: 0; + font-size: 85%; + background-color: rgba(0,0,0,0.04); + border-radius: 3px; +} + +.markdown-body code:before, +.markdown-body code:after { + letter-spacing: -0.2em; + content: "\00a0"; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + font-size: 100%; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + border-radius: 3px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body pre { + word-wrap: normal; +} + +.markdown-body pre code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +.markdown-body pre code:before, +.markdown-body pre code:after { + content: normal; +} + +.markdown-body .highlight { + background: #fff; +} + +.markdown-body .highlight .h { + color: #333; + font-style: normal; + font-weight: normal; +} + +.markdown-body .highlight .mf, +.markdown-body .highlight .mh, +.markdown-body .highlight .mi, +.markdown-body .highlight .mo, +.markdown-body .highlight .il, +.markdown-body .highlight .m { + color: #945277; +} + +.markdown-body .highlight .s, +.markdown-body .highlight .sb, +.markdown-body .highlight .sc, +.markdown-body .highlight .sd, +.markdown-body .highlight .s2, +.markdown-body .highlight .se, +.markdown-body .highlight .sh, +.markdown-body .highlight .si, +.markdown-body .highlight .sx, +.markdown-body .highlight .s1 { + color: #df5000; +} + +.markdown-body .highlight .kc, +.markdown-body .highlight .kd, +.markdown-body .highlight .kn, +.markdown-body .highlight .kp, +.markdown-body .highlight .kr, +.markdown-body .highlight .kt, +.markdown-body .highlight .k, +.markdown-body .highlight .o { + font-weight: bold; +} + +.markdown-body .highlight .kt { + color: #458; +} + +.markdown-body .highlight .c, +.markdown-body .highlight .cm, +.markdown-body .highlight .c1 { + color: #998; + font-style: italic; +} + +.markdown-body .highlight .cp, +.markdown-body .highlight .cs, +.markdown-body .highlight .cp .h { + color: #999; + font-weight: bold; +} + +.markdown-body .highlight .cs { + font-style: italic; +} + +.markdown-body .highlight .n { + color: #333; +} + +.markdown-body .highlight .na, +.markdown-body .highlight .nv, +.markdown-body .highlight .vc, +.markdown-body .highlight .vg, +.markdown-body .highlight .vi { + color: #008080; +} + +.markdown-body .highlight .nb { + color: #0086B3; +} + +.markdown-body .highlight .nc { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .no { + color: #094e99; +} + +.markdown-body .highlight .ni { + color: #800080; +} + +.markdown-body .highlight .ne { + color: #990000; + font-weight: bold; +} + +.markdown-body .highlight .nf { + color: #945277; + font-weight: bold; +} + +.markdown-body .highlight .nn { + color: #555; +} + +.markdown-body .highlight .nt { + color: #000080; +} + +.markdown-body .highlight .err { + color: #a61717; + background-color: #e3d2d2; +} + +.markdown-body .highlight .gd { + color: #000; + background-color: #fdd; +} + +.markdown-body .highlight .gd .x { + color: #000; + background-color: #faa; +} + +.markdown-body .highlight .ge { + font-style: italic; +} + +.markdown-body .highlight .gr { + color: #aa0000; +} + +.markdown-body .highlight .gh { + color: #999; +} + +.markdown-body .highlight .gi { + color: #000; + background-color: #dfd; +} + +.markdown-body .highlight .gi .x { + color: #000; + background-color: #afa; +} + +.markdown-body .highlight .go { + color: #888; +} + +.markdown-body .highlight .gp { + color: #555; +} + +.markdown-body .highlight .gs { + font-weight: bold; +} + +.markdown-body .highlight .gu { + color: #800080; + font-weight: bold; +} + +.markdown-body .highlight .gt { + color: #aa0000; +} + +.markdown-body .highlight .ow { + font-weight: bold; +} + +.markdown-body .highlight .w { + color: #bbb; +} + +.markdown-body .highlight .sr { + color: #017936; +} + +.markdown-body .highlight .ss { + color: #8b467f; +} + +.markdown-body .highlight .bp { + color: #999; +} + +.markdown-body .highlight .gc { + color: #999; + background-color: #EAF2F5; +} + +.markdown-body kbd { + background-color: #e7e7e7; + background-image: -webkit-linear-gradient(#fefefe, #e7e7e7); + background-image: linear-gradient(#fefefe, #e7e7e7); + background-repeat: repeat-x; + display: inline-block; + padding: 3px 5px; + font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; + line-height: 10px; + color: #000; + border: 1px solid #cfcfcf; + border-radius: 2px; +} + +.markdown-body .highlight .pl-coc, +.markdown-body .highlight .pl-entm, +.markdown-body .highlight .pl-eoa, +.markdown-body .highlight .pl-mai .pl-sf, +.markdown-body .highlight .pl-pdv, +.markdown-body .highlight .pl-sc, +.markdown-body .highlight .pl-sr, +.markdown-body .highlight .pl-v, +.markdown-body .highlight .pl-vpf { + color: #0086b3; +} + +.markdown-body .highlight .pl-eoac, +.markdown-body .highlight .pl-mdht, +.markdown-body .highlight .pl-mi1, +.markdown-body .highlight .pl-mri, +.markdown-body .highlight .pl-va, +.markdown-body .highlight .pl-vpu { + color: #008080; +} + +.markdown-body .highlight .pl-c, +.markdown-body .highlight .pl-pdc { + color: #b4b7b4; + font-style: italic; +} + +.markdown-body .highlight .pl-k, +.markdown-body .highlight .pl-ko, +.markdown-body .highlight .pl-kolp, +.markdown-body .highlight .pl-mc, +.markdown-body .highlight .pl-mr, +.markdown-body .highlight .pl-ms, +.markdown-body .highlight .pl-s, +.markdown-body .highlight .pl-sok, +.markdown-body .highlight .pl-st { + color: #6e5494; +} + +.markdown-body .highlight .pl-ef, +.markdown-body .highlight .pl-enf, +.markdown-body .highlight .pl-enm, +.markdown-body .highlight .pl-entc, +.markdown-body .highlight .pl-eoi, +.markdown-body .highlight .pl-sf, +.markdown-body .highlight .pl-smc { + color: #d12089; +} + +.markdown-body .highlight .pl-ens, +.markdown-body .highlight .pl-eoai, +.markdown-body .highlight .pl-kos, +.markdown-body .highlight .pl-mh .pl-pdh, +.markdown-body .highlight .pl-mp, +.markdown-body .highlight .pl-pde, +.markdown-body .highlight .pl-stp { + color: #458; +} + +.markdown-body .highlight .pl-enti { + color: #d12089; + font-weight: bold; +} + +.markdown-body .highlight .pl-cce, +.markdown-body .highlight .pl-enc, +.markdown-body .highlight .pl-kou, +.markdown-body .highlight .pl-mq { + color: #f93; +} + +.markdown-body .highlight .pl-mp1 .pl-sf { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .pl-cos, +.markdown-body .highlight .pl-ent, +.markdown-body .highlight .pl-md, +.markdown-body .highlight .pl-mdhf, +.markdown-body .highlight .pl-ml, +.markdown-body .highlight .pl-pdc1, +.markdown-body .highlight .pl-pds, +.markdown-body .highlight .pl-s1, +.markdown-body .highlight .pl-scp, +.markdown-body .highlight .pl-sol { + color: #df5000; +} + +.markdown-body .highlight .pl-c1, +.markdown-body .highlight .pl-cn, +.markdown-body .highlight .pl-pse, +.markdown-body .highlight .pl-pse .pl-s2, +.markdown-body .highlight .pl-vi { + color: #a31515; +} + +.markdown-body .highlight .pl-mb, +.markdown-body .highlight .pl-pdb { + color: #df5000; + font-weight: bold; +} + +.markdown-body .highlight .pl-mi, +.markdown-body .highlight .pl-pdi { + color: #6e5494; + font-style: italic; +} + +.markdown-body .highlight .pl-ms1 { + background-color: #f5f5f5; +} + +.markdown-body .highlight .pl-mdh, +.markdown-body .highlight .pl-mdi { + font-weight: bold; +} + +.markdown-body .highlight .pl-mdr { + color: #0086b3; + font-weight: bold; +} + +.markdown-body .highlight .pl-s2 { + color: #333; +} + +.markdown-body .highlight .pl-ii { + background-color: #df5000; + color: #fff; +} + +.markdown-body .highlight .pl-ib { + background-color: #f93; +} + +.markdown-body .highlight .pl-id { + background-color: #a31515; + color: #fff; +} + +.markdown-body .highlight .pl-iu { + background-color: #b4b7b4; +} + +.markdown-body .highlight .pl-mo { + color: #969896; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 3px; +} + +.markdown-body .task-list-item input { + float: left; + margin: 0.3em 0 0.25em -1.6em; + vertical-align: middle; +}</style><title>installation</title></head><body><article class="markdown-body"><h2 id="%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%B0"> +<a id="user-content-Настройка-доступа" class="anchor" href="#%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF%D0%B0" aria-hidden="true"><span class="octicon octicon-link"></span></a>Настройка доступа</h2> + +<h4 id="redmine"> +<a id="user-content-redmine" class="anchor" href="#redmine" aria-hidden="true"><span class="octicon octicon-link"></span></a>Redmine</h4> + +<ul> +<li>Регистрируемся РЅР° сайте <a href="http://itlab.mmcs.sfedu.ru/redmine/">http://itlab.mmcs.sfedu.ru/redmine/</a> +</li> +<li>Отправляем РЅР° почту Романа Борисовича <code>romanofficial@ya.ru</code> СЃРІРѕР№ логин</li> +<li>Ждём утверждения учётной записи</li> +</ul> + +<h4 id="gitlab"> +<a id="user-content-gitlab" class="anchor" href="#gitlab" aria-hidden="true"><span class="octicon octicon-link"></span></a>Gitlab</h4> + +<ul> +<li>Пишем <a href="https://twitter.com/ya_dummer">Артёму</a> <em>(email?)</em> +</li> +<li>Отправляем адрес электронной почты, логин, РёРјСЏ</li> +<li>РќР° почту придёт уведомление СЃРѕ ссылкой РЅР° последующую авторизацию</li> +<li>Адрес: <a href="http://gitlab.mmcs.sfedu.ru/">http://gitlab.mmcs.sfedu.ru/</a> +</li> +</ul> + +<p>РќР° данный момент РЅР° Gitlab'e РЅРµ ведётся разработка, РЅРѕ можно будет туда переехать РІ СЃРєРѕСЂРѕРј времени, СЃ появлением автоматического тестирования. Есть возможность создать 10 приватных репозиториев.</p> + +<h4 id="%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF-%D0%BA-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8E"> +<a id="user-content-Доступ-Рє-репозиторию" class="anchor" href="#%D0%94%D0%BE%D1%81%D1%82%D1%83%D0%BF-%D0%BA-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8E" aria-hidden="true"><span class="octicon octicon-link"></span></a>Доступ Рє репозиторию</h4> + +<p>Пара логин / пароль, используемая РІ redmine, также используется Рё РїСЂРё авторизации РІ репозитории.</p> + +<div class="highlight highlight-bash"><pre>$ git clone http://itlab.mmcs.sfedu.ru/git/<span class="pl-k"><</span>project_name<span class="pl-k">></span></pre></div> + +<h2 id="%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-%D0%BF%D0%BE"> +<a id="user-content-Настройка-РџРћ" class="anchor" href="#%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B0-%D0%9F%D0%9E" aria-hidden="true"><span class="octicon octicon-link"></span></a>Настройка РџРћ</h2> + +<p>Комплект РџРћ, СЃ которым РјС‹ работаем РЅР° данный момент: </p> + +<ul> +<li> +<a href="https://www.jetbrains.com/phpstorm/download/">PHPStorm</a> (Community Edition) — профессиональная IDE, альтернатива: NetBeans</li> +<li> +<a href="http://rutracker.org/forum/viewtopic.php?t=4894492">OpenServer</a> (Расширенная редакция) — платформа, создающая виртуальное окружение для Apache, Nginx, MySQL Server</li> +<li> +<a href="http://git-scm.com/downloads">Git</a> — система контроля версий</li> +<li> +<a href="www.sourcetreeapp.com/download/">SourceTree</a> — гипер удобный GUI для git <em>(РїРѕ мнению Штейнберга Р .Р‘.)</em> +</li> +</ul> + +<h4 id="%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8-openserver"> +<a id="user-content-Настройки-openserver" class="anchor" href="#%D0%9D%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8-openserver" aria-hidden="true"><span class="octicon octicon-link"></span></a>Настройки OpenServer</h4> + +<p><strong>Вкладка основные</strong>: поставтье галку РЅР° пункте "Требовать учётную запись Администратора", так как OpenServer работает СЃ файлом HOSTS.</p> + +<p><strong>Вкладка модули</strong>: Apache-2.4 + ngingx, PHP-5.5, MySQL-5.5.</p> + +<p>Откройте каталог <code>OpenServer/domains</code>, Рё <a href="#%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF-%D0%BA-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8E">склонируйте</a> репозиторий проекта РІ него. После перезапуска OpenServer'a РїРѕ адресу подкаталога станет доступен сайт.</p> + +<h2 id="%D0%BA%D0%B0%D0%BA-%D0%BF%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-dev_rating"> +<a id="user-content-Как-поставить-dev_rating" class="anchor" href="#%D0%9A%D0%B0%D0%BA-%D0%BF%D0%BE%D1%81%D1%82%D0%B0%D0%B2%D0%B8%D1%82%D1%8C-dev_rating" aria-hidden="true"><span class="octicon octicon-link"></span></a>Как поставить dev_rating?</h2> + +<ul> +<li><p>Скачать проект РІ папку <code>OpenServer/domains</code> СЃ помощью команды <code>git clone <адрес репозитория></code></p></li> +<li><p>Настроить адрес сайта РІ файлах:</p></li> +</ul> + +<pre><code>./~dev_rating/htaccess +./~dev_rating/application/bootstrap.php +(line ~107: 'base_url' => '/~dev_rating/') +</code></pre> + +<ul> +<li> +<p>Подготовить базу данных</p> + +<ul> +<li>Зайти РІ phpMyAdmin. Правой РєРЅРѕРїРєРѕР№ РїРѕ РёРєРѕРЅРєРµ OpenServer'a -> <em>Дополнительно</em> -> <em>phpMyAdmin</em>. Стандартный логин <code>root</code>, пароль пустой.</li> +<li>Создать базу данных</li> +<li>Последовательно импортировать <code>db/Structure.sql</code>, <code>db/release_gen_mmcs_sg.sql</code>, <code>db/StoredProcedures.sql</code>, <code>db/StoredFunctions.sql</code>, <code>db/Views.sql</code>.</li> +</ul> +</li> +<li><p>Скопировать конфигурационные файлы РёР· <code>./~dev_rating/deployConfig</code> РІ <code>./~dev_rating/application/config/</code></p></li> +<li><p>Настроить конфиг. Как РјРёРЅРёРјСѓРј изменить <code>./~dev_rating/application/config/database.php</code> РїРѕРґ СЃРІРѕСЋ базу.</p></li> +</ul> +</article></body></html> \ No newline at end of file diff --git a/doc/dev/installation.md b/doc/dev/installation.md new file mode 100644 index 0000000000000000000000000000000000000000..1e2bf00875c5efeaa88a953bdcafdaf3a534fcfd --- /dev/null +++ b/doc/dev/installation.md @@ -0,0 +1,65 @@ + + +## Настройка доступа + +#### Redmine + +- Регистрируемся РЅР° сайте http://itlab.mmcs.sfedu.ru/redmine/ +- Отправляем РЅР° почту Романа Борисовича `romanofficial@ya.ru` СЃРІРѕР№ логин +- Ждём утверждения учётной записи + + +#### Gitlab + +- Пишем [Артёму](https://twitter.com/ya_dummer) _(email?)_ +- Отправляем адрес электронной почты, логин, РёРјСЏ +- РќР° почту придёт уведомление СЃРѕ ссылкой РЅР° последующую авторизацию +- Адрес: http://gitlab.mmcs.sfedu.ru/ + +РќР° данный момент РЅР° Gitlab'e РЅРµ ведётся разработка, РЅРѕ можно будет туда переехать РІ СЃРєРѕСЂРѕРј времени, СЃ появлением автоматического тестирования. Есть возможность создать 10 приватных репозиториев. + + +#### Доступ Рє репозиторию + +Пара логин / пароль, используемая РІ redmine, также используется Рё РїСЂРё авторизации РІ репозитории. + +```bash +$ git clone http://itlab.mmcs.sfedu.ru/git/<project_name> +``` + +## Настройка РџРћ + +Комплект РџРћ, СЃ которым РјС‹ работаем РЅР° данный момент: +- [PHPStorm](https://www.jetbrains.com/phpstorm/download/) (Community Edition) — профессиональная IDE, альтернатива: NetBeans +- [OpenServer](http://rutracker.org/forum/viewtopic.php?t=4894492) (Расширенная редакция) — платформа, создающая виртуальное окружение для Apache, Nginx, MySQL Server +- [Git](http://git-scm.com/downloads) — система контроля версий +- [SourceTree](www.sourcetreeapp.com/download/) — гипер удобный GUI для git _(РїРѕ мнению Штейнберга Р .Р‘.)_ + +#### Настройки OpenServer + +**Вкладка основные**: поставтье галку РЅР° пункте "Требовать учётную запись Администратора", так как OpenServer работает СЃ файлом HOSTS. + +**Вкладка модули**: Apache-2.4 + ngingx, PHP-5.5, MySQL-5.5. + +Откройте каталог `OpenServer/domains`, Рё [склонируйте](#%D0%B4%D0%BE%D1%81%D1%82%D1%83%D0%BF-%D0%BA-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8E) репозиторий проекта РІ него. После перезапуска OpenServer'a РїРѕ адресу подкаталога станет доступен сайт. + + +## Как поставить dev_rating? + +- Скачать проект РІ папку `OpenServer/domains` СЃ помощью команды `git clone <адрес репозитория>` + +- Настроить адрес сайта РІ файлах: +``` +./~dev_rating/htaccess +./~dev_rating/application/bootstrap.php +(line ~107: 'base_url' => '/~dev_rating/') +``` + +- Подготовить базу данных + * Зайти РІ phpMyAdmin. Правой РєРЅРѕРїРєРѕР№ РїРѕ РёРєРѕРЅРєРµ OpenServer'a -> _Дополнительно_ -> _phpMyAdmin_. Стандартный логин `root`, пароль пустой. + * Создать базу данных + * Последовательно импортировать `db/Structure.sql`, `db/release_gen_mmcs_sg.sql`, `db/StoredProcedures.sql`, `db/StoredFunctions.sql`, `db/Views.sql`. + +- Скопировать конфигурационные файлы РёР· `./~dev_rating/deployConfig` РІ `./~dev_rating/application/config/` + +- Настроить конфиг. Как РјРёРЅРёРјСѓРј изменить `./~dev_rating/application/config/database.php` РїРѕРґ СЃРІРѕСЋ базу. \ No newline at end of file diff --git a/doc/dev/testing/kohana/mockobjects.html b/doc/dev/testing/kohana/mockobjects.html new file mode 100644 index 0000000000000000000000000000000000000000..df3e76526e80f5be8a11e91cbe673544c4a245b4 --- /dev/null +++ b/doc/dev/testing/kohana/mockobjects.html @@ -0,0 +1,1150 @@ +<!DOCTYPE html><html><head><meta charset="utf-8"><style>body { + width: 45em; + border: 1px solid #ddd; + outline: 1300px solid #fff; + margin: 16px auto; +} + +body .markdown-body +{ + padding: 30px; +} + +@font-face { + font-family: octicons-anchor; + src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff'); +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + color: #333; + overflow: hidden; + font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; + font-size: 16px; + line-height: 1.6; + word-wrap: break-word; +} + +.markdown-body a { + background: transparent; +} + +.markdown-body a:active, +.markdown-body a:hover { + outline: 0; +} + +.markdown-body strong { + font-weight: bold; +} + +.markdown-body h1 { + font-size: 2em; + margin: 0.67em 0; +} + +.markdown-body img { + border: 0; +} + +.markdown-body hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +.markdown-body pre { + overflow: auto; +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre { + font-family: monospace, monospace; + font-size: 1em; +} + +.markdown-body input { + color: inherit; + font: inherit; + margin: 0; +} + +.markdown-body html input[disabled] { + cursor: default; +} + +.markdown-body input { + line-height: normal; +} + +.markdown-body input[type="checkbox"] { + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +.markdown-body table { + border-collapse: collapse; + border-spacing: 0; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body * { + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body input { + font: 13px/1.4 Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; +} + +.markdown-body a { + color: #4183c4; + text-decoration: none; +} + +.markdown-body a:hover, +.markdown-body a:focus, +.markdown-body a:active { + text-decoration: underline; +} + +.markdown-body hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #ddd; +} + +.markdown-body hr:before { + display: table; + content: ""; +} + +.markdown-body hr:after { + display: table; + clear: both; + content: ""; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 15px; + margin-bottom: 15px; + line-height: 1.1; +} + +.markdown-body h1 { + font-size: 30px; +} + +.markdown-body h2 { + font-size: 21px; +} + +.markdown-body h3 { + font-size: 16px; +} + +.markdown-body h4 { + font-size: 14px; +} + +.markdown-body h5 { + font-size: 12px; +} + +.markdown-body h6 { + font-size: 11px; +} + +.markdown-body blockquote { + margin: 0; +} + +.markdown-body ul, +.markdown-body ol { + padding: 0; + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ul ul ol, +.markdown-body ul ol ol, +.markdown-body ol ul ol, +.markdown-body ol ol ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body code { + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body .octicon { + font: normal normal 16px octicons-anchor; + line-height: 1; + display: inline-block; + text-decoration: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.markdown-body .octicon-link:before { + content: '\f05c'; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +.markdown-body .anchor { + position: absolute; + top: 0; + bottom: 0; + left: 0; + display: block; + padding-right: 6px; + padding-left: 30px; + margin-left: -30px; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + position: relative; + margin-top: 1em; + margin-bottom: 16px; + font-weight: bold; + line-height: 1.4; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + display: none; + color: #000; + vertical-align: middle; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + padding-left: 8px; + margin-left: -30px; + line-height: 1; + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + display: inline-block; +} + +.markdown-body h1 { + padding-bottom: 0.3em; + font-size: 2.25em; + line-height: 1.2; + border-bottom: 1px solid #eee; +} + +.markdown-body h2 { + padding-bottom: 0.3em; + font-size: 1.75em; + line-height: 1.225; + border-bottom: 1px solid #eee; +} + +.markdown-body h3 { + font-size: 1.5em; + line-height: 1.43; +} + +.markdown-body h4 { + font-size: 1.25em; +} + +.markdown-body h5 { + font-size: 1em; +} + +.markdown-body h6 { + font-size: 1em; + color: #777; +} + +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body hr { + height: 4px; + padding: 0; + margin: 16px 0; + background-color: #e7e7e7; + border: 0 none; +} + +.markdown-body ul, +.markdown-body ol { + padding-left: 2em; +} + +.markdown-body ul ul, +.markdown-body ul ol, +.markdown-body ol ol, +.markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: bold; +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body blockquote { + padding: 0 15px; + color: #777; + border-left: 4px solid #ddd; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body table { + display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; +} + +.markdown-body table th { + font-weight: bold; +} + +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid #ddd; +} + +.markdown-body table tr { + background-color: #fff; + border-top: 1px solid #ccc; +} + +.markdown-body table tr:nth-child(2n) { + background-color: #f8f8f8; +} + +.markdown-body img { + max-width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body code { + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + margin: 0; + font-size: 85%; + background-color: rgba(0,0,0,0.04); + border-radius: 3px; +} + +.markdown-body code:before, +.markdown-body code:after { + letter-spacing: -0.2em; + content: "\00a0"; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + font-size: 100%; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + border-radius: 3px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body pre { + word-wrap: normal; +} + +.markdown-body pre code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +.markdown-body pre code:before, +.markdown-body pre code:after { + content: normal; +} + +.markdown-body .highlight { + background: #fff; +} + +.markdown-body .highlight .h { + color: #333; + font-style: normal; + font-weight: normal; +} + +.markdown-body .highlight .mf, +.markdown-body .highlight .mh, +.markdown-body .highlight .mi, +.markdown-body .highlight .mo, +.markdown-body .highlight .il, +.markdown-body .highlight .m { + color: #945277; +} + +.markdown-body .highlight .s, +.markdown-body .highlight .sb, +.markdown-body .highlight .sc, +.markdown-body .highlight .sd, +.markdown-body .highlight .s2, +.markdown-body .highlight .se, +.markdown-body .highlight .sh, +.markdown-body .highlight .si, +.markdown-body .highlight .sx, +.markdown-body .highlight .s1 { + color: #df5000; +} + +.markdown-body .highlight .kc, +.markdown-body .highlight .kd, +.markdown-body .highlight .kn, +.markdown-body .highlight .kp, +.markdown-body .highlight .kr, +.markdown-body .highlight .kt, +.markdown-body .highlight .k, +.markdown-body .highlight .o { + font-weight: bold; +} + +.markdown-body .highlight .kt { + color: #458; +} + +.markdown-body .highlight .c, +.markdown-body .highlight .cm, +.markdown-body .highlight .c1 { + color: #998; + font-style: italic; +} + +.markdown-body .highlight .cp, +.markdown-body .highlight .cs, +.markdown-body .highlight .cp .h { + color: #999; + font-weight: bold; +} + +.markdown-body .highlight .cs { + font-style: italic; +} + +.markdown-body .highlight .n { + color: #333; +} + +.markdown-body .highlight .na, +.markdown-body .highlight .nv, +.markdown-body .highlight .vc, +.markdown-body .highlight .vg, +.markdown-body .highlight .vi { + color: #008080; +} + +.markdown-body .highlight .nb { + color: #0086B3; +} + +.markdown-body .highlight .nc { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .no { + color: #094e99; +} + +.markdown-body .highlight .ni { + color: #800080; +} + +.markdown-body .highlight .ne { + color: #990000; + font-weight: bold; +} + +.markdown-body .highlight .nf { + color: #945277; + font-weight: bold; +} + +.markdown-body .highlight .nn { + color: #555; +} + +.markdown-body .highlight .nt { + color: #000080; +} + +.markdown-body .highlight .err { + color: #a61717; + background-color: #e3d2d2; +} + +.markdown-body .highlight .gd { + color: #000; + background-color: #fdd; +} + +.markdown-body .highlight .gd .x { + color: #000; + background-color: #faa; +} + +.markdown-body .highlight .ge { + font-style: italic; +} + +.markdown-body .highlight .gr { + color: #aa0000; +} + +.markdown-body .highlight .gh { + color: #999; +} + +.markdown-body .highlight .gi { + color: #000; + background-color: #dfd; +} + +.markdown-body .highlight .gi .x { + color: #000; + background-color: #afa; +} + +.markdown-body .highlight .go { + color: #888; +} + +.markdown-body .highlight .gp { + color: #555; +} + +.markdown-body .highlight .gs { + font-weight: bold; +} + +.markdown-body .highlight .gu { + color: #800080; + font-weight: bold; +} + +.markdown-body .highlight .gt { + color: #aa0000; +} + +.markdown-body .highlight .ow { + font-weight: bold; +} + +.markdown-body .highlight .w { + color: #bbb; +} + +.markdown-body .highlight .sr { + color: #017936; +} + +.markdown-body .highlight .ss { + color: #8b467f; +} + +.markdown-body .highlight .bp { + color: #999; +} + +.markdown-body .highlight .gc { + color: #999; + background-color: #EAF2F5; +} + +.markdown-body kbd { + background-color: #e7e7e7; + background-image: -webkit-linear-gradient(#fefefe, #e7e7e7); + background-image: linear-gradient(#fefefe, #e7e7e7); + background-repeat: repeat-x; + display: inline-block; + padding: 3px 5px; + font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; + line-height: 10px; + color: #000; + border: 1px solid #cfcfcf; + border-radius: 2px; +} + +.markdown-body .highlight .pl-coc, +.markdown-body .highlight .pl-entm, +.markdown-body .highlight .pl-eoa, +.markdown-body .highlight .pl-mai .pl-sf, +.markdown-body .highlight .pl-pdv, +.markdown-body .highlight .pl-sc, +.markdown-body .highlight .pl-sr, +.markdown-body .highlight .pl-v, +.markdown-body .highlight .pl-vpf { + color: #0086b3; +} + +.markdown-body .highlight .pl-eoac, +.markdown-body .highlight .pl-mdht, +.markdown-body .highlight .pl-mi1, +.markdown-body .highlight .pl-mri, +.markdown-body .highlight .pl-va, +.markdown-body .highlight .pl-vpu { + color: #008080; +} + +.markdown-body .highlight .pl-c, +.markdown-body .highlight .pl-pdc { + color: #b4b7b4; + font-style: italic; +} + +.markdown-body .highlight .pl-k, +.markdown-body .highlight .pl-ko, +.markdown-body .highlight .pl-kolp, +.markdown-body .highlight .pl-mc, +.markdown-body .highlight .pl-mr, +.markdown-body .highlight .pl-ms, +.markdown-body .highlight .pl-s, +.markdown-body .highlight .pl-sok, +.markdown-body .highlight .pl-st { + color: #6e5494; +} + +.markdown-body .highlight .pl-ef, +.markdown-body .highlight .pl-enf, +.markdown-body .highlight .pl-enm, +.markdown-body .highlight .pl-entc, +.markdown-body .highlight .pl-eoi, +.markdown-body .highlight .pl-sf, +.markdown-body .highlight .pl-smc { + color: #d12089; +} + +.markdown-body .highlight .pl-ens, +.markdown-body .highlight .pl-eoai, +.markdown-body .highlight .pl-kos, +.markdown-body .highlight .pl-mh .pl-pdh, +.markdown-body .highlight .pl-mp, +.markdown-body .highlight .pl-pde, +.markdown-body .highlight .pl-stp { + color: #458; +} + +.markdown-body .highlight .pl-enti { + color: #d12089; + font-weight: bold; +} + +.markdown-body .highlight .pl-cce, +.markdown-body .highlight .pl-enc, +.markdown-body .highlight .pl-kou, +.markdown-body .highlight .pl-mq { + color: #f93; +} + +.markdown-body .highlight .pl-mp1 .pl-sf { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .pl-cos, +.markdown-body .highlight .pl-ent, +.markdown-body .highlight .pl-md, +.markdown-body .highlight .pl-mdhf, +.markdown-body .highlight .pl-ml, +.markdown-body .highlight .pl-pdc1, +.markdown-body .highlight .pl-pds, +.markdown-body .highlight .pl-s1, +.markdown-body .highlight .pl-scp, +.markdown-body .highlight .pl-sol { + color: #df5000; +} + +.markdown-body .highlight .pl-c1, +.markdown-body .highlight .pl-cn, +.markdown-body .highlight .pl-pse, +.markdown-body .highlight .pl-pse .pl-s2, +.markdown-body .highlight .pl-vi { + color: #a31515; +} + +.markdown-body .highlight .pl-mb, +.markdown-body .highlight .pl-pdb { + color: #df5000; + font-weight: bold; +} + +.markdown-body .highlight .pl-mi, +.markdown-body .highlight .pl-pdi { + color: #6e5494; + font-style: italic; +} + +.markdown-body .highlight .pl-ms1 { + background-color: #f5f5f5; +} + +.markdown-body .highlight .pl-mdh, +.markdown-body .highlight .pl-mdi { + font-weight: bold; +} + +.markdown-body .highlight .pl-mdr { + color: #0086b3; + font-weight: bold; +} + +.markdown-body .highlight .pl-s2 { + color: #333; +} + +.markdown-body .highlight .pl-ii { + background-color: #df5000; + color: #fff; +} + +.markdown-body .highlight .pl-ib { + background-color: #f93; +} + +.markdown-body .highlight .pl-id { + background-color: #a31515; + color: #fff; +} + +.markdown-body .highlight .pl-iu { + background-color: #b4b7b4; +} + +.markdown-body .highlight .pl-mo { + color: #969896; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 3px; +} + +.markdown-body .task-list-item input { + float: left; + margin: 0.3em 0 0.25em -1.6em; + vertical-align: middle; +}</style><title>mockobjects</title></head><body><article class="markdown-body"><h1 id="mock-objects"> +<a id="user-content-mock-objects" class="anchor" href="#mock-objects" aria-hidden="true"><span class="octicon octicon-link"></span></a>Mock objects</h1> + +<p>Sometimes when writing tests you need to test something that depends on an object being in a certain state.</p> + +<p>Say for example you're testing a model - you want to make sure that the model is running the correct query, but you don't want it to run on a real database server. You can create a mock database connection which responds in the way the model expects, but doesn't actually connect to a physical database.</p> + +<p>PHPUnit has a built in mock object creator which can generate mocks for classes (inc. abstract ones) on the fly.<br> +It creates a class that extends the one you want to mock. You can also tell PHPUnit to override certain functions to return set values / assert that they're called in a specific way.</p> + +<h2 id="creating-an-instance-of-a-mock-class"> +<a id="user-content-creating-an-instance-of-a-mock-class" class="anchor" href="#creating-an-instance-of-a-mock-class" aria-hidden="true"><span class="octicon octicon-link"></span></a>Creating an instance of a mock class</h2> + +<p>You create mocks from within testcases using the getMock() function, which is defined in <code>PHPUnit_Framework_TestCase</code> like so:</p> + +<pre><code> getMock($originalClassName, $methods = array(), array $arguments = array(), $mockClassName = '', $callOriginalConstructor = TRUE, $callOriginalClone = TRUE, $callAutoload = TRUE) +</code></pre> + +<p><code>$originalClassName</code> +: The name of the class that you want to mock</p> + +<p><code>$methods</code> +: The methods of $originalClassName that you want to mock.<br> + You need to tell PHPUnit in advance because PHP doesn't allow you to extend an object once it's been initialised.</p> + +<p><code>$arguments</code> +: An array of arguments to pass to the mock's constructor</p> + +<p><code>$mockClassName</code> +: Allows you to specify the name that will be given to the mock</p> + +<p><code>$callOriginalConstructor</code> +: Should the mock call its parent's constructor automatically?</p> + +<p><code>$callOriginalClone</code> +: Should the mock call its parent's clone method?</p> + +<p>Most of the time you'll only need to use the first two parameters, i.e.:</p> + +<pre><code>$mock = $this->getMock('ORM'); +</code></pre> + +<p><code>$mock</code> now contains a mock of ORM and can be handled as though it were a vanilla instance of <code>ORM</code></p> + +<pre><code>$mock = $this->getMock('ORM', array('check')); +</code></pre> + +<p><code>$mock</code> now contains a mock of ORM, but this time we're also mocking the check() method.</p> + +<h2 id="mocking-methods"> +<a id="user-content-mocking-methods" class="anchor" href="#mocking-methods" aria-hidden="true"><span class="octicon octicon-link"></span></a>Mocking methods</h2> + +<p>Assuming we've created a mock object like so:</p> + +<pre><code>$mock = $this->getMock('ORM', array('check')); +</code></pre> + +<p>We now need to tell PHPUnit how to mock the check function when its called.</p> + +<h3 id="how-many-times-should-it-be-called"> +<a id="user-content-how-many-times-should-it-be-called" class="anchor" href="#how-many-times-should-it-be-called" aria-hidden="true"><span class="octicon octicon-link"></span></a>How many times should it be called?</h3> + +<p>You start off by telling PHPUnit how many times the method should be called by calling expects() on the mock object:</p> + +<pre><code>$mock->expects($matcher); +</code></pre> + +<p><code>expects()</code> takes one argument, an invoker matcher which you can create using factory methods defined in <code>PHPUnit_Framework_TestCase</code>:</p> + +<h4 id="possible-invoker-matchers"> +<a id="user-content-possible-invoker-matchers" class="anchor" href="#possible-invoker-matchers" aria-hidden="true"><span class="octicon octicon-link"></span></a>Possible invoker matchers:</h4> + +<p><code>$this->any()</code> +: Returns a matcher that allows the method to be called any number of times</p> + +<p><code>$this->never()</code> +: Returns a matcher that asserts that the method is never called</p> + +<p><code>$this->once()</code> +: Returns a matcher that asserts that the method is only called once</p> + +<p><code>$this->atLeastOnce()</code> +: Returns a matcher that asserts that the method is called at least once</p> + +<p><code>$this->exactly($count)</code> +: Returns a matcher that asserts that the method is called at least <code>$count</code> times</p> + +<p><code>$this->at($index)</code> +: Returns a matcher that matches when the method it is evaluated for is invoked at the given $index.</p> + +<p>In our example we want <code>check()</code> to be called once on our mock object, so if we update it accordingly:</p> + +<pre><code>$mock = $this->getMock('ORM', array('check')); + +$mock->expects($this->once()); +</code></pre> + +<h3 id="what-is-the-method-were-mocking"> +<a id="user-content-what-is-the-method-were-mocking" class="anchor" href="#what-is-the-method-were-mocking" aria-hidden="true"><span class="octicon octicon-link"></span></a>What is the method we're mocking?</h3> + +<p>Although we told PHPUnit what methods we want to mock, we haven't actually told it what method these rules we're specifiying apply to.<br> +You do this by calling <code>method()</code> on the returned from <code>expects()</code>:</p> + +<pre><code>$mock->expects($matcher) + ->method($methodName); +</code></pre> + +<p>As you can probably guess, <code>method()</code> takes one parameter, the name of the method you're mocking.<br> +There's nothing very fancy about this function.</p> + +<pre><code>$mock = $this->GetMock('ORM', array('check')); + +$mock->expects($this->once()) + ->method('check'); +</code></pre> + +<h3 id="what-parameters-should-our-mock-method-expect"> +<a id="user-content-what-parameters-should-our-mock-method-expect" class="anchor" href="#what-parameters-should-our-mock-method-expect" aria-hidden="true"><span class="octicon octicon-link"></span></a>What parameters should our mock method expect?</h3> + +<p>There are two ways to do this, either</p> + +<ul> +<li>Tell the method to accept any parameters</li> +<li>Tell the method to accept a specific set of parameters</li> +</ul> + +<p>The former can be achieved by calling <code>withAnyParameters()</code> on the object returned from <code>method()</code></p> + +<pre><code>$mock->expects($matcher) + ->method($methodName) + ->withAnyParameters(); +</code></pre> + +<p>To only allow specific parameters you can use the <code>with()</code> method which accepts any number of parameters.<br> +The order in which you define the parameters is the order that it expects them to be in when called.</p> + +<pre><code>$mock->expects($matcher) + ->method($methodName) + ->with($param1, $param2); +</code></pre> + +<p>Calling <code>with()</code> without any parameters will force the mock method to accept no parameters.</p> + +<p>PHPUnit has a fairly complex way of comparing parameters passed to the mock method with the expected values, which can be summarised like so - </p> + +<ul> +<li>If the values are identical, they are equal</li> +<li>If the values are of different types they are not equal</li> +<li>If the values are numbers they they are considered equal if their difference is equal to zero (this level of accuracy can be changed)</li> +<li>If the values are objects then they are converted to arrays and are compared as arrays</li> +<li>If the values are arrays then any sub-arrays deeper than x levels (default 10) are ignored in the comparision</li> +<li>If the values are arrays and one contains more than elements that the other (at any depth up to the max depth), then they are not equal</li> +</ul> + +<h4 id="more-advanced-parameter-comparisions"> +<a id="user-content-more-advanced-parameter-comparisions" class="anchor" href="#more-advanced-parameter-comparisions" aria-hidden="true"><span class="octicon octicon-link"></span></a>More advanced parameter comparisions</h4> + +<p>Sometimes you need to be more specific about how PHPUnit should compare parameters, i.e. if you want to make sure that one of the parameters is an instance of an object, yet isn't necessarily identical to a particular instance.</p> + +<p>In PHPUnit, the logic for validating objects and datatypes has been refactored into "constraint objects". If you look in any of the assertX() methods you can see that they are nothing more than wrappers for associating constraint objects with tests.</p> + +<p>If a parameter passed to <code>with()</code> is not an instance of a constraint object (one which extends <code>PHPUnit_Framework_Constraint</code>) then PHPUnit creates a new <code>IsEqual</code> comparision object for it.</p> + +<p>i.e., the following methods produce the same result:</p> + +<pre><code>->with('foo', 1); + +->with($this->equalTo('foo'), $this->equalTo(1)); +</code></pre> + +<p>Here are some of the wrappers PHPUnit provides for creating constraint objects:</p> + +<p><code>$this->arrayHasKey($key)</code> +: Asserts that the parameter will have an element with index <code>$key</code></p> + +<p><code>$this->attribute(PHPUnit_Framework_Constraint $constraint, $attributeName)</code> +: Asserts that object attribute <code>$attributeName</code> of the parameter will satisfy <code>$constraint</code>, where constraint is an instance of a constraint (i.e. <code>$this->equalTo()</code>)</p> + +<p><code>$this->fileExists()</code> +: Accepts no parameters, asserts that the parameter is a path to a valid file (i.e. <code>file_exists() === TRUE</code>)</p> + +<p><code>$this->greaterThan($value)</code> +: Asserts that the parameter is greater than <code>$value</code></p> + +<p><code>$this->anything()</code> +: Returns TRUE regardless of what the parameter is</p> + +<p><code>$this->equalTo($value, $delta = 0, $canonicalizeEOL = FALSE, $ignoreCase = False)</code> +: Asserts that the parameter is equal to <code>$value</code> (same as not passing a constraint object to <code>with()</code>) +: <code>$delta</code> is the degree of accuracy to use when comparing numbers. i.e. 0 means numbers need to be identical, 1 means numbers can be within a distance of one from each other +: If <code>$canonicalizeEOL</code> is TRUE then all newlines in string values will be converted to <code>\n</code> before comparision +: If <code>$ignoreCase</code> is TRUE then both strings will be converted to lowercase before comparision</p> + +<p><code>$this->identicalTo($value)</code> +: Asserts that the parameter is identical to <code>$value</code></p> + +<p><code>$this->isType($type)</code> +: Asserts that the parameter is of type <code>$type</code>, where <code>$type</code> is a string representation of the core PHP data types</p> + +<p><code>$this->isInstanceOf($className)</code> +: Asserts that the parameter is an instance of <code>$className</code></p> + +<p><code>$this->lessThan($value)</code> +: Asserts that the parameter is less than <code>$value</code></p> + +<p><code>$this->objectHasAttribute($attribute)</code> +: Asserts that the paramater (which is assumed to be an object) has an attribute <code>$attribute</code></p> + +<p><code>$this->matchesRegularExpression($pattern)</code> +: Asserts that the parameter matches the PCRE pattern <code>$pattern</code> (using <code>preg_match()</code>)</p> + +<p><code>$this->stringContains($string, $ignoreCase = FALSE)</code> +: Asserts that the parameter contains the string <code>$string</code>. If <code>$ignoreCase</code> is TRUE then a case insensitive comparision is done</p> + +<p><code>$this->stringEndsWith($suffix)</code> +: Asserts that the parameter ends with <code>$suffix</code> (assumes parameter is a string)</p> + +<p><code>$this->stringStartsWith($prefix)</code> +: Asserts that the parameter starts with <code>$prefix</code> (assumes parameter is a string)</p> + +<p><code>$this->contains($value)</code> +: Asserts that the parameter contains at least one value that is identical to <code>$value</code> (assumes parameter is array or <code>SplObjectStorage</code>)</p> + +<p><code>$this->containsOnly($type, $isNativeType = TRUE)</code> +: Asserts that the parameter only contains items of type <code>$type</code>. <code>$isNativeType</code> should be set to TRUE when <code>$type</code> refers to a built in PHP data type (i.e. int, string etc.) (assumes parameter is array)</p> + +<p>There are more constraint objects than listed here, look in <code>PHPUnit_Framework_Assert</code> and <code>PHPUnit/Framework/Constraint</code> if you need more constraints.</p> + +<p>If we continue our example, we have the following: </p> + +<pre><code>$mock->expects($this->once()) + ->method('check') + ->with(); +</code></pre> + +<p>So far PHPUnit knows that we want the <code>check()</code> method to be called once, with no parameters. Now we just need to get it to return something...</p> + +<h3 id="what-should-the-method-return"> +<a id="user-content-what-should-the-method-return" class="anchor" href="#what-should-the-method-return" aria-hidden="true"><span class="octicon octicon-link"></span></a>What should the method return?</h3> + +<p>This is the final stage of mocking a method.</p> + +<p>By default PHPUnit can return either</p> + +<ul> +<li>A fixed value</li> +<li>One of the parameters that were passed to it</li> +<li>The return value of a specified callback</li> +</ul> + +<p>Specifying a return value is easy, just call <code>will()</code> on the object returned by either <code>method()</code> or <code>with()</code>.</p> + +<p>The function is defined like so:</p> + +<pre><code>public function will(PHPUnit_Framework_MockObject_Stub $stub) +</code></pre> + +<p>PHPUnit provides some MockObject stubs out of the box, you can access them via (when called from a testcase):</p> + +<p><code>$this->returnValue($value)</code> +: Returns <code>$value</code> when the mocked method is called</p> + +<p><code>$this->returnArgument($argumentIndex)</code> +: Returns the <code>$argumentIndex</code>th argument that was passed to the mocked method</p> + +<p><code>$this->returnCallback($callback)</code> +: Returns the value of the callback, useful for more complicated mocking.<br> +: <code>$callback</code> should a valid callback (i.e. <code>is_callable($callback) === TRUE</code>). PHPUnit will pass the callback all of the parameters that the mocked method was passed, in the same order / argument index (i.e. the callback is invoked by <code>call_user_func_array()</code>). +: You can usually create the callback in your testcase, as long as doesn't begin with "test"</p> + +<p>Obviously if you really want to you can create your own MockObject stub, but these three should cover most situations.</p> + +<p>Updating our example gives:</p> + +<pre><code>$mock->expects($this->once()) + ->method('check') + ->with() + ->will($this->returnValue(TRUE)); +</code></pre> + +<p>And we're done!</p> + +<p>If you now call <code>$mock->check()</code> the value TRUE should be returned.</p> + +<p>If you don't call a mocked method and PHPUnit expects it to be called then the test the mock was generated for will fail.</p> + + +</article></body></html> \ No newline at end of file diff --git a/~dev_rating/modules/unittest/guide/unittest/mockobjects.md b/doc/dev/testing/kohana/mockobjects.md similarity index 100% rename from ~dev_rating/modules/unittest/guide/unittest/mockobjects.md rename to doc/dev/testing/kohana/mockobjects.md diff --git a/doc/dev/testing/kohana/testing_workflows.html b/doc/dev/testing/kohana/testing_workflows.html new file mode 100644 index 0000000000000000000000000000000000000000..fbebf0db7f7b4dea40c337261cace6c9fc0eae9c --- /dev/null +++ b/doc/dev/testing/kohana/testing_workflows.html @@ -0,0 +1,909 @@ +<!DOCTYPE html><html><head><meta charset="utf-8"><style>body { + width: 45em; + border: 1px solid #ddd; + outline: 1300px solid #fff; + margin: 16px auto; +} + +body .markdown-body +{ + padding: 30px; +} + +@font-face { + font-family: octicons-anchor; + src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff'); +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + color: #333; + overflow: hidden; + font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; + font-size: 16px; + line-height: 1.6; + word-wrap: break-word; +} + +.markdown-body a { + background: transparent; +} + +.markdown-body a:active, +.markdown-body a:hover { + outline: 0; +} + +.markdown-body strong { + font-weight: bold; +} + +.markdown-body h1 { + font-size: 2em; + margin: 0.67em 0; +} + +.markdown-body img { + border: 0; +} + +.markdown-body hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +.markdown-body pre { + overflow: auto; +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre { + font-family: monospace, monospace; + font-size: 1em; +} + +.markdown-body input { + color: inherit; + font: inherit; + margin: 0; +} + +.markdown-body html input[disabled] { + cursor: default; +} + +.markdown-body input { + line-height: normal; +} + +.markdown-body input[type="checkbox"] { + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +.markdown-body table { + border-collapse: collapse; + border-spacing: 0; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body * { + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body input { + font: 13px/1.4 Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; +} + +.markdown-body a { + color: #4183c4; + text-decoration: none; +} + +.markdown-body a:hover, +.markdown-body a:focus, +.markdown-body a:active { + text-decoration: underline; +} + +.markdown-body hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #ddd; +} + +.markdown-body hr:before { + display: table; + content: ""; +} + +.markdown-body hr:after { + display: table; + clear: both; + content: ""; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 15px; + margin-bottom: 15px; + line-height: 1.1; +} + +.markdown-body h1 { + font-size: 30px; +} + +.markdown-body h2 { + font-size: 21px; +} + +.markdown-body h3 { + font-size: 16px; +} + +.markdown-body h4 { + font-size: 14px; +} + +.markdown-body h5 { + font-size: 12px; +} + +.markdown-body h6 { + font-size: 11px; +} + +.markdown-body blockquote { + margin: 0; +} + +.markdown-body ul, +.markdown-body ol { + padding: 0; + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ul ul ol, +.markdown-body ul ol ol, +.markdown-body ol ul ol, +.markdown-body ol ol ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body code { + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body .octicon { + font: normal normal 16px octicons-anchor; + line-height: 1; + display: inline-block; + text-decoration: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.markdown-body .octicon-link:before { + content: '\f05c'; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +.markdown-body .anchor { + position: absolute; + top: 0; + bottom: 0; + left: 0; + display: block; + padding-right: 6px; + padding-left: 30px; + margin-left: -30px; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + position: relative; + margin-top: 1em; + margin-bottom: 16px; + font-weight: bold; + line-height: 1.4; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + display: none; + color: #000; + vertical-align: middle; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + padding-left: 8px; + margin-left: -30px; + line-height: 1; + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + display: inline-block; +} + +.markdown-body h1 { + padding-bottom: 0.3em; + font-size: 2.25em; + line-height: 1.2; + border-bottom: 1px solid #eee; +} + +.markdown-body h2 { + padding-bottom: 0.3em; + font-size: 1.75em; + line-height: 1.225; + border-bottom: 1px solid #eee; +} + +.markdown-body h3 { + font-size: 1.5em; + line-height: 1.43; +} + +.markdown-body h4 { + font-size: 1.25em; +} + +.markdown-body h5 { + font-size: 1em; +} + +.markdown-body h6 { + font-size: 1em; + color: #777; +} + +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body hr { + height: 4px; + padding: 0; + margin: 16px 0; + background-color: #e7e7e7; + border: 0 none; +} + +.markdown-body ul, +.markdown-body ol { + padding-left: 2em; +} + +.markdown-body ul ul, +.markdown-body ul ol, +.markdown-body ol ol, +.markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: bold; +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body blockquote { + padding: 0 15px; + color: #777; + border-left: 4px solid #ddd; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body table { + display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; +} + +.markdown-body table th { + font-weight: bold; +} + +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid #ddd; +} + +.markdown-body table tr { + background-color: #fff; + border-top: 1px solid #ccc; +} + +.markdown-body table tr:nth-child(2n) { + background-color: #f8f8f8; +} + +.markdown-body img { + max-width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body code { + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + margin: 0; + font-size: 85%; + background-color: rgba(0,0,0,0.04); + border-radius: 3px; +} + +.markdown-body code:before, +.markdown-body code:after { + letter-spacing: -0.2em; + content: "\00a0"; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + font-size: 100%; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + border-radius: 3px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body pre { + word-wrap: normal; +} + +.markdown-body pre code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +.markdown-body pre code:before, +.markdown-body pre code:after { + content: normal; +} + +.markdown-body .highlight { + background: #fff; +} + +.markdown-body .highlight .h { + color: #333; + font-style: normal; + font-weight: normal; +} + +.markdown-body .highlight .mf, +.markdown-body .highlight .mh, +.markdown-body .highlight .mi, +.markdown-body .highlight .mo, +.markdown-body .highlight .il, +.markdown-body .highlight .m { + color: #945277; +} + +.markdown-body .highlight .s, +.markdown-body .highlight .sb, +.markdown-body .highlight .sc, +.markdown-body .highlight .sd, +.markdown-body .highlight .s2, +.markdown-body .highlight .se, +.markdown-body .highlight .sh, +.markdown-body .highlight .si, +.markdown-body .highlight .sx, +.markdown-body .highlight .s1 { + color: #df5000; +} + +.markdown-body .highlight .kc, +.markdown-body .highlight .kd, +.markdown-body .highlight .kn, +.markdown-body .highlight .kp, +.markdown-body .highlight .kr, +.markdown-body .highlight .kt, +.markdown-body .highlight .k, +.markdown-body .highlight .o { + font-weight: bold; +} + +.markdown-body .highlight .kt { + color: #458; +} + +.markdown-body .highlight .c, +.markdown-body .highlight .cm, +.markdown-body .highlight .c1 { + color: #998; + font-style: italic; +} + +.markdown-body .highlight .cp, +.markdown-body .highlight .cs, +.markdown-body .highlight .cp .h { + color: #999; + font-weight: bold; +} + +.markdown-body .highlight .cs { + font-style: italic; +} + +.markdown-body .highlight .n { + color: #333; +} + +.markdown-body .highlight .na, +.markdown-body .highlight .nv, +.markdown-body .highlight .vc, +.markdown-body .highlight .vg, +.markdown-body .highlight .vi { + color: #008080; +} + +.markdown-body .highlight .nb { + color: #0086B3; +} + +.markdown-body .highlight .nc { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .no { + color: #094e99; +} + +.markdown-body .highlight .ni { + color: #800080; +} + +.markdown-body .highlight .ne { + color: #990000; + font-weight: bold; +} + +.markdown-body .highlight .nf { + color: #945277; + font-weight: bold; +} + +.markdown-body .highlight .nn { + color: #555; +} + +.markdown-body .highlight .nt { + color: #000080; +} + +.markdown-body .highlight .err { + color: #a61717; + background-color: #e3d2d2; +} + +.markdown-body .highlight .gd { + color: #000; + background-color: #fdd; +} + +.markdown-body .highlight .gd .x { + color: #000; + background-color: #faa; +} + +.markdown-body .highlight .ge { + font-style: italic; +} + +.markdown-body .highlight .gr { + color: #aa0000; +} + +.markdown-body .highlight .gh { + color: #999; +} + +.markdown-body .highlight .gi { + color: #000; + background-color: #dfd; +} + +.markdown-body .highlight .gi .x { + color: #000; + background-color: #afa; +} + +.markdown-body .highlight .go { + color: #888; +} + +.markdown-body .highlight .gp { + color: #555; +} + +.markdown-body .highlight .gs { + font-weight: bold; +} + +.markdown-body .highlight .gu { + color: #800080; + font-weight: bold; +} + +.markdown-body .highlight .gt { + color: #aa0000; +} + +.markdown-body .highlight .ow { + font-weight: bold; +} + +.markdown-body .highlight .w { + color: #bbb; +} + +.markdown-body .highlight .sr { + color: #017936; +} + +.markdown-body .highlight .ss { + color: #8b467f; +} + +.markdown-body .highlight .bp { + color: #999; +} + +.markdown-body .highlight .gc { + color: #999; + background-color: #EAF2F5; +} + +.markdown-body kbd { + background-color: #e7e7e7; + background-image: -webkit-linear-gradient(#fefefe, #e7e7e7); + background-image: linear-gradient(#fefefe, #e7e7e7); + background-repeat: repeat-x; + display: inline-block; + padding: 3px 5px; + font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; + line-height: 10px; + color: #000; + border: 1px solid #cfcfcf; + border-radius: 2px; +} + +.markdown-body .highlight .pl-coc, +.markdown-body .highlight .pl-entm, +.markdown-body .highlight .pl-eoa, +.markdown-body .highlight .pl-mai .pl-sf, +.markdown-body .highlight .pl-pdv, +.markdown-body .highlight .pl-sc, +.markdown-body .highlight .pl-sr, +.markdown-body .highlight .pl-v, +.markdown-body .highlight .pl-vpf { + color: #0086b3; +} + +.markdown-body .highlight .pl-eoac, +.markdown-body .highlight .pl-mdht, +.markdown-body .highlight .pl-mi1, +.markdown-body .highlight .pl-mri, +.markdown-body .highlight .pl-va, +.markdown-body .highlight .pl-vpu { + color: #008080; +} + +.markdown-body .highlight .pl-c, +.markdown-body .highlight .pl-pdc { + color: #b4b7b4; + font-style: italic; +} + +.markdown-body .highlight .pl-k, +.markdown-body .highlight .pl-ko, +.markdown-body .highlight .pl-kolp, +.markdown-body .highlight .pl-mc, +.markdown-body .highlight .pl-mr, +.markdown-body .highlight .pl-ms, +.markdown-body .highlight .pl-s, +.markdown-body .highlight .pl-sok, +.markdown-body .highlight .pl-st { + color: #6e5494; +} + +.markdown-body .highlight .pl-ef, +.markdown-body .highlight .pl-enf, +.markdown-body .highlight .pl-enm, +.markdown-body .highlight .pl-entc, +.markdown-body .highlight .pl-eoi, +.markdown-body .highlight .pl-sf, +.markdown-body .highlight .pl-smc { + color: #d12089; +} + +.markdown-body .highlight .pl-ens, +.markdown-body .highlight .pl-eoai, +.markdown-body .highlight .pl-kos, +.markdown-body .highlight .pl-mh .pl-pdh, +.markdown-body .highlight .pl-mp, +.markdown-body .highlight .pl-pde, +.markdown-body .highlight .pl-stp { + color: #458; +} + +.markdown-body .highlight .pl-enti { + color: #d12089; + font-weight: bold; +} + +.markdown-body .highlight .pl-cce, +.markdown-body .highlight .pl-enc, +.markdown-body .highlight .pl-kou, +.markdown-body .highlight .pl-mq { + color: #f93; +} + +.markdown-body .highlight .pl-mp1 .pl-sf { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .pl-cos, +.markdown-body .highlight .pl-ent, +.markdown-body .highlight .pl-md, +.markdown-body .highlight .pl-mdhf, +.markdown-body .highlight .pl-ml, +.markdown-body .highlight .pl-pdc1, +.markdown-body .highlight .pl-pds, +.markdown-body .highlight .pl-s1, +.markdown-body .highlight .pl-scp, +.markdown-body .highlight .pl-sol { + color: #df5000; +} + +.markdown-body .highlight .pl-c1, +.markdown-body .highlight .pl-cn, +.markdown-body .highlight .pl-pse, +.markdown-body .highlight .pl-pse .pl-s2, +.markdown-body .highlight .pl-vi { + color: #a31515; +} + +.markdown-body .highlight .pl-mb, +.markdown-body .highlight .pl-pdb { + color: #df5000; + font-weight: bold; +} + +.markdown-body .highlight .pl-mi, +.markdown-body .highlight .pl-pdi { + color: #6e5494; + font-style: italic; +} + +.markdown-body .highlight .pl-ms1 { + background-color: #f5f5f5; +} + +.markdown-body .highlight .pl-mdh, +.markdown-body .highlight .pl-mdi { + font-weight: bold; +} + +.markdown-body .highlight .pl-mdr { + color: #0086b3; + font-weight: bold; +} + +.markdown-body .highlight .pl-s2 { + color: #333; +} + +.markdown-body .highlight .pl-ii { + background-color: #df5000; + color: #fff; +} + +.markdown-body .highlight .pl-ib { + background-color: #f93; +} + +.markdown-body .highlight .pl-id { + background-color: #a31515; + color: #fff; +} + +.markdown-body .highlight .pl-iu { + background-color: #b4b7b4; +} + +.markdown-body .highlight .pl-mo { + color: #969896; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 3px; +} + +.markdown-body .task-list-item input { + float: left; + margin: 0.3em 0 0.25em -1.6em; + vertical-align: middle; +}</style><title>testing_workflows</title></head><body><article class="markdown-body"><h1 id="testing-workflows"> +<a id="user-content-testing-workflows" class="anchor" href="#testing-workflows" aria-hidden="true"><span class="octicon octicon-link"></span></a>Testing workflows</h1> + +<p>Having unittests for your application is a nice idea, but unless you actually use them they're about as useful as a chocolate firegaurd. There are quite a few ways of getting tests "into" your development process and this guide aims to cover a few of them.</p> + +<h2 id="integrating-with-ides"> +<a id="user-content-integrating-with-ides" class="anchor" href="#integrating-with-ides" aria-hidden="true"><span class="octicon octicon-link"></span></a>Integrating with IDEs</h2> + +<p>Modern IDEs have come a long way in the last couple of years and ones like netbeans have pretty decent PHP / PHPUnit support.</p> + +<h3 id="netbeans-68"> +<a id="user-content-netbeans-68" class="anchor" href="#netbeans-68" aria-hidden="true"><span class="octicon octicon-link"></span></a>Netbeans (6.8+)</h3> + +<p><em>Note:</em> Netbeans runs under the assumption that you only have one tests folder per project.<br> +If you want to run tests across multiple modules it might be best creating a separate project for each module.</p> + +<ol> +<li><p>Install the unittest module</p></li> +<li><p>Open the project which you want to enable phpunit testing for.</p></li> +<li><p>Now open the project's properties dialouge and in the "Tests Dir" field enter the path to your module's (or application's) test directory.<br> +In this case the only tests in this project are within the unittest module</p></li> +<li><p>Select the phpunit section from the left hand pane and in the area labelled bootstrap enter the path to your app's index.php file</p></li> +</ol> + +<p>You can also specify a custom test suite loader (enter the path to your tests.php file) and/or a custom configuration file (enter the path to your phpunit.xml file)</p> + +<h2 id="looping-shell"> +<a id="user-content-looping-shell" class="anchor" href="#looping-shell" aria-hidden="true"><span class="octicon octicon-link"></span></a>Looping shell</h2> + +<p>If you're developing in a text editor such as textmate, vim, gedit etc. chances are phpunit support isn't natively supported by your editor.</p> + +<p>In such situations you can run a simple bash script to loop over the tests every X seconds, here's an example script:</p> + +<pre><code>while(true) do clear; phpunit; sleep 8; done; +</code></pre> + +<p>You will probably need to adjust the timeout (<code>sleep 8</code>) to suit your own workflow, but 8 seconds seems to be about enough time to see what's erroring before the tests are re-run.</p> + +<p>In the above example we're using a phpunit.xml config file to specify all the unit testing settings & to reduce the complexity of the looping script.</p> + +<h2 id="continuous-integration-ci"> +<a id="user-content-continuous-integration-ci" class="anchor" href="#continuous-integration-ci" aria-hidden="true"><span class="octicon octicon-link"></span></a>Continuous Integration (CI)</h2> + +<p>Continuous integration is a team based tool which enables developers to keep tabs on whether changes committed to a project break the application. If a commit causes a test to fail then the build is classed as "broken" and the CI server then alerts developers by email, RSS, IM or glowing (bears|lava lamps) to the fact that someone has broken the build and that all hell's broken lose.</p> + +<p>The two more popular CI servers are <a href="https://hudson.dev.java.net/">Hudson</a> and <a href="http://www.phpundercontrol.org/about.html">phpUnderControl</a>, both of which use <a href="http://phing.info/">Phing</a> to run the build tasks for your application.</p> +</article></body></html> \ No newline at end of file diff --git a/~dev_rating/modules/unittest/guide/unittest/testing_workflows.md b/doc/dev/testing/kohana/testing_workflows.md similarity index 100% rename from ~dev_rating/modules/unittest/guide/unittest/testing_workflows.md rename to doc/dev/testing/kohana/testing_workflows.md diff --git a/doc/dev/testing/kohana/troubleshooting.html b/doc/dev/testing/kohana/troubleshooting.html new file mode 100644 index 0000000000000000000000000000000000000000..4c8010d80f130aea4dd5703805a0ff61f6cbac22 --- /dev/null +++ b/doc/dev/testing/kohana/troubleshooting.html @@ -0,0 +1,890 @@ +<!DOCTYPE html><html><head><meta charset="utf-8"><style>body { + width: 45em; + border: 1px solid #ddd; + outline: 1300px solid #fff; + margin: 16px auto; +} + +body .markdown-body +{ + padding: 30px; +} + +@font-face { + font-family: octicons-anchor; + src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff'); +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + color: #333; + overflow: hidden; + font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; + font-size: 16px; + line-height: 1.6; + word-wrap: break-word; +} + +.markdown-body a { + background: transparent; +} + +.markdown-body a:active, +.markdown-body a:hover { + outline: 0; +} + +.markdown-body strong { + font-weight: bold; +} + +.markdown-body h1 { + font-size: 2em; + margin: 0.67em 0; +} + +.markdown-body img { + border: 0; +} + +.markdown-body hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +.markdown-body pre { + overflow: auto; +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre { + font-family: monospace, monospace; + font-size: 1em; +} + +.markdown-body input { + color: inherit; + font: inherit; + margin: 0; +} + +.markdown-body html input[disabled] { + cursor: default; +} + +.markdown-body input { + line-height: normal; +} + +.markdown-body input[type="checkbox"] { + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +.markdown-body table { + border-collapse: collapse; + border-spacing: 0; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body * { + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body input { + font: 13px/1.4 Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; +} + +.markdown-body a { + color: #4183c4; + text-decoration: none; +} + +.markdown-body a:hover, +.markdown-body a:focus, +.markdown-body a:active { + text-decoration: underline; +} + +.markdown-body hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #ddd; +} + +.markdown-body hr:before { + display: table; + content: ""; +} + +.markdown-body hr:after { + display: table; + clear: both; + content: ""; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 15px; + margin-bottom: 15px; + line-height: 1.1; +} + +.markdown-body h1 { + font-size: 30px; +} + +.markdown-body h2 { + font-size: 21px; +} + +.markdown-body h3 { + font-size: 16px; +} + +.markdown-body h4 { + font-size: 14px; +} + +.markdown-body h5 { + font-size: 12px; +} + +.markdown-body h6 { + font-size: 11px; +} + +.markdown-body blockquote { + margin: 0; +} + +.markdown-body ul, +.markdown-body ol { + padding: 0; + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ul ul ol, +.markdown-body ul ol ol, +.markdown-body ol ul ol, +.markdown-body ol ol ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body code { + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body .octicon { + font: normal normal 16px octicons-anchor; + line-height: 1; + display: inline-block; + text-decoration: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.markdown-body .octicon-link:before { + content: '\f05c'; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +.markdown-body .anchor { + position: absolute; + top: 0; + bottom: 0; + left: 0; + display: block; + padding-right: 6px; + padding-left: 30px; + margin-left: -30px; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + position: relative; + margin-top: 1em; + margin-bottom: 16px; + font-weight: bold; + line-height: 1.4; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + display: none; + color: #000; + vertical-align: middle; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + padding-left: 8px; + margin-left: -30px; + line-height: 1; + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + display: inline-block; +} + +.markdown-body h1 { + padding-bottom: 0.3em; + font-size: 2.25em; + line-height: 1.2; + border-bottom: 1px solid #eee; +} + +.markdown-body h2 { + padding-bottom: 0.3em; + font-size: 1.75em; + line-height: 1.225; + border-bottom: 1px solid #eee; +} + +.markdown-body h3 { + font-size: 1.5em; + line-height: 1.43; +} + +.markdown-body h4 { + font-size: 1.25em; +} + +.markdown-body h5 { + font-size: 1em; +} + +.markdown-body h6 { + font-size: 1em; + color: #777; +} + +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body hr { + height: 4px; + padding: 0; + margin: 16px 0; + background-color: #e7e7e7; + border: 0 none; +} + +.markdown-body ul, +.markdown-body ol { + padding-left: 2em; +} + +.markdown-body ul ul, +.markdown-body ul ol, +.markdown-body ol ol, +.markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: bold; +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body blockquote { + padding: 0 15px; + color: #777; + border-left: 4px solid #ddd; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body table { + display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; +} + +.markdown-body table th { + font-weight: bold; +} + +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid #ddd; +} + +.markdown-body table tr { + background-color: #fff; + border-top: 1px solid #ccc; +} + +.markdown-body table tr:nth-child(2n) { + background-color: #f8f8f8; +} + +.markdown-body img { + max-width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body code { + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + margin: 0; + font-size: 85%; + background-color: rgba(0,0,0,0.04); + border-radius: 3px; +} + +.markdown-body code:before, +.markdown-body code:after { + letter-spacing: -0.2em; + content: "\00a0"; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + font-size: 100%; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + border-radius: 3px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body pre { + word-wrap: normal; +} + +.markdown-body pre code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +.markdown-body pre code:before, +.markdown-body pre code:after { + content: normal; +} + +.markdown-body .highlight { + background: #fff; +} + +.markdown-body .highlight .h { + color: #333; + font-style: normal; + font-weight: normal; +} + +.markdown-body .highlight .mf, +.markdown-body .highlight .mh, +.markdown-body .highlight .mi, +.markdown-body .highlight .mo, +.markdown-body .highlight .il, +.markdown-body .highlight .m { + color: #945277; +} + +.markdown-body .highlight .s, +.markdown-body .highlight .sb, +.markdown-body .highlight .sc, +.markdown-body .highlight .sd, +.markdown-body .highlight .s2, +.markdown-body .highlight .se, +.markdown-body .highlight .sh, +.markdown-body .highlight .si, +.markdown-body .highlight .sx, +.markdown-body .highlight .s1 { + color: #df5000; +} + +.markdown-body .highlight .kc, +.markdown-body .highlight .kd, +.markdown-body .highlight .kn, +.markdown-body .highlight .kp, +.markdown-body .highlight .kr, +.markdown-body .highlight .kt, +.markdown-body .highlight .k, +.markdown-body .highlight .o { + font-weight: bold; +} + +.markdown-body .highlight .kt { + color: #458; +} + +.markdown-body .highlight .c, +.markdown-body .highlight .cm, +.markdown-body .highlight .c1 { + color: #998; + font-style: italic; +} + +.markdown-body .highlight .cp, +.markdown-body .highlight .cs, +.markdown-body .highlight .cp .h { + color: #999; + font-weight: bold; +} + +.markdown-body .highlight .cs { + font-style: italic; +} + +.markdown-body .highlight .n { + color: #333; +} + +.markdown-body .highlight .na, +.markdown-body .highlight .nv, +.markdown-body .highlight .vc, +.markdown-body .highlight .vg, +.markdown-body .highlight .vi { + color: #008080; +} + +.markdown-body .highlight .nb { + color: #0086B3; +} + +.markdown-body .highlight .nc { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .no { + color: #094e99; +} + +.markdown-body .highlight .ni { + color: #800080; +} + +.markdown-body .highlight .ne { + color: #990000; + font-weight: bold; +} + +.markdown-body .highlight .nf { + color: #945277; + font-weight: bold; +} + +.markdown-body .highlight .nn { + color: #555; +} + +.markdown-body .highlight .nt { + color: #000080; +} + +.markdown-body .highlight .err { + color: #a61717; + background-color: #e3d2d2; +} + +.markdown-body .highlight .gd { + color: #000; + background-color: #fdd; +} + +.markdown-body .highlight .gd .x { + color: #000; + background-color: #faa; +} + +.markdown-body .highlight .ge { + font-style: italic; +} + +.markdown-body .highlight .gr { + color: #aa0000; +} + +.markdown-body .highlight .gh { + color: #999; +} + +.markdown-body .highlight .gi { + color: #000; + background-color: #dfd; +} + +.markdown-body .highlight .gi .x { + color: #000; + background-color: #afa; +} + +.markdown-body .highlight .go { + color: #888; +} + +.markdown-body .highlight .gp { + color: #555; +} + +.markdown-body .highlight .gs { + font-weight: bold; +} + +.markdown-body .highlight .gu { + color: #800080; + font-weight: bold; +} + +.markdown-body .highlight .gt { + color: #aa0000; +} + +.markdown-body .highlight .ow { + font-weight: bold; +} + +.markdown-body .highlight .w { + color: #bbb; +} + +.markdown-body .highlight .sr { + color: #017936; +} + +.markdown-body .highlight .ss { + color: #8b467f; +} + +.markdown-body .highlight .bp { + color: #999; +} + +.markdown-body .highlight .gc { + color: #999; + background-color: #EAF2F5; +} + +.markdown-body kbd { + background-color: #e7e7e7; + background-image: -webkit-linear-gradient(#fefefe, #e7e7e7); + background-image: linear-gradient(#fefefe, #e7e7e7); + background-repeat: repeat-x; + display: inline-block; + padding: 3px 5px; + font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; + line-height: 10px; + color: #000; + border: 1px solid #cfcfcf; + border-radius: 2px; +} + +.markdown-body .highlight .pl-coc, +.markdown-body .highlight .pl-entm, +.markdown-body .highlight .pl-eoa, +.markdown-body .highlight .pl-mai .pl-sf, +.markdown-body .highlight .pl-pdv, +.markdown-body .highlight .pl-sc, +.markdown-body .highlight .pl-sr, +.markdown-body .highlight .pl-v, +.markdown-body .highlight .pl-vpf { + color: #0086b3; +} + +.markdown-body .highlight .pl-eoac, +.markdown-body .highlight .pl-mdht, +.markdown-body .highlight .pl-mi1, +.markdown-body .highlight .pl-mri, +.markdown-body .highlight .pl-va, +.markdown-body .highlight .pl-vpu { + color: #008080; +} + +.markdown-body .highlight .pl-c, +.markdown-body .highlight .pl-pdc { + color: #b4b7b4; + font-style: italic; +} + +.markdown-body .highlight .pl-k, +.markdown-body .highlight .pl-ko, +.markdown-body .highlight .pl-kolp, +.markdown-body .highlight .pl-mc, +.markdown-body .highlight .pl-mr, +.markdown-body .highlight .pl-ms, +.markdown-body .highlight .pl-s, +.markdown-body .highlight .pl-sok, +.markdown-body .highlight .pl-st { + color: #6e5494; +} + +.markdown-body .highlight .pl-ef, +.markdown-body .highlight .pl-enf, +.markdown-body .highlight .pl-enm, +.markdown-body .highlight .pl-entc, +.markdown-body .highlight .pl-eoi, +.markdown-body .highlight .pl-sf, +.markdown-body .highlight .pl-smc { + color: #d12089; +} + +.markdown-body .highlight .pl-ens, +.markdown-body .highlight .pl-eoai, +.markdown-body .highlight .pl-kos, +.markdown-body .highlight .pl-mh .pl-pdh, +.markdown-body .highlight .pl-mp, +.markdown-body .highlight .pl-pde, +.markdown-body .highlight .pl-stp { + color: #458; +} + +.markdown-body .highlight .pl-enti { + color: #d12089; + font-weight: bold; +} + +.markdown-body .highlight .pl-cce, +.markdown-body .highlight .pl-enc, +.markdown-body .highlight .pl-kou, +.markdown-body .highlight .pl-mq { + color: #f93; +} + +.markdown-body .highlight .pl-mp1 .pl-sf { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .pl-cos, +.markdown-body .highlight .pl-ent, +.markdown-body .highlight .pl-md, +.markdown-body .highlight .pl-mdhf, +.markdown-body .highlight .pl-ml, +.markdown-body .highlight .pl-pdc1, +.markdown-body .highlight .pl-pds, +.markdown-body .highlight .pl-s1, +.markdown-body .highlight .pl-scp, +.markdown-body .highlight .pl-sol { + color: #df5000; +} + +.markdown-body .highlight .pl-c1, +.markdown-body .highlight .pl-cn, +.markdown-body .highlight .pl-pse, +.markdown-body .highlight .pl-pse .pl-s2, +.markdown-body .highlight .pl-vi { + color: #a31515; +} + +.markdown-body .highlight .pl-mb, +.markdown-body .highlight .pl-pdb { + color: #df5000; + font-weight: bold; +} + +.markdown-body .highlight .pl-mi, +.markdown-body .highlight .pl-pdi { + color: #6e5494; + font-style: italic; +} + +.markdown-body .highlight .pl-ms1 { + background-color: #f5f5f5; +} + +.markdown-body .highlight .pl-mdh, +.markdown-body .highlight .pl-mdi { + font-weight: bold; +} + +.markdown-body .highlight .pl-mdr { + color: #0086b3; + font-weight: bold; +} + +.markdown-body .highlight .pl-s2 { + color: #333; +} + +.markdown-body .highlight .pl-ii { + background-color: #df5000; + color: #fff; +} + +.markdown-body .highlight .pl-ib { + background-color: #f93; +} + +.markdown-body .highlight .pl-id { + background-color: #a31515; + color: #fff; +} + +.markdown-body .highlight .pl-iu { + background-color: #b4b7b4; +} + +.markdown-body .highlight .pl-mo { + color: #969896; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 3px; +} + +.markdown-body .task-list-item input { + float: left; + margin: 0.3em 0 0.25em -1.6em; + vertical-align: middle; +}</style><title>troubleshooting</title></head><body><article class="markdown-body"><h1 id="troubleshooting"> +<a id="user-content-troubleshooting" class="anchor" href="#troubleshooting" aria-hidden="true"><span class="octicon octicon-link"></span></a>Troubleshooting</h1> + +<h2 id="i-get-the-error-class-kohana_tests-could-not-be-found-when-testing-from-the-cli"> +<a id="user-content-i-get-the-error-class-kohana_tests-could-not-be-found-when-testing-from-the-cli" class="anchor" href="#i-get-the-error-class-kohana_tests-could-not-be-found-when-testing-from-the-cli" aria-hidden="true"><span class="octicon octicon-link"></span></a>I get the error "Class Kohana_Tests could not be found" when testing from the CLI</h2> + +<p>You need to running PHPUnit >= 3.4, there is a bug in 3.3 which causes this.</p> + +<h2 id="some-of-my-classes-arent-getting-whitelisted-for-code-coverage-even-though-their-module-is"> +<a id="user-content-some-of-my-classes-arent-getting-whitelisted-for-code-coverage-even-though-their-module-is" class="anchor" href="#some-of-my-classes-arent-getting-whitelisted-for-code-coverage-even-though-their-module-is" aria-hidden="true"><span class="octicon octicon-link"></span></a>Some of my classes aren't getting whitelisted for code coverage even though their module is</h2> + +<p>Only the "highest" files in the cascading filesystem are whitelisted for code coverage.</p> + +<p>To test your module's file, remove the higher file from the cascading filesystem by disabling their respective module.</p> + +<p>A good way of testing is to create a "vanilla" testing environment for your module, devoid of anything that isn't required by the module.</p> + +<h2 id="i-get-a-blank-page-when-trying-to-generate-a-code-coverage-report"> +<a id="user-content-i-get-a-blank-page-when-trying-to-generate-a-code-coverage-report" class="anchor" href="#i-get-a-blank-page-when-trying-to-generate-a-code-coverage-report" aria-hidden="true"><span class="octicon octicon-link"></span></a>I get a blank page when trying to generate a code coverage report</h2> + +<p>Try the following:</p> + +<ol> +<li>Generate a html report from the command line using <code>phpunit {bootstrap info} --coverage-html ./report {insert path to tests.php}</code>. If any error messages show up, fix them and try to generate the report again</li> +<li>Increase the php memory limit</li> +<li>Make sure that display_errors is set to "on" in your php.ini config file (this value can sometimes be overriden in a .htaccess file)</li> +</ol> +</article></body></html> \ No newline at end of file diff --git a/~dev_rating/modules/unittest/guide/unittest/troubleshooting.md b/doc/dev/testing/kohana/troubleshooting.md similarity index 100% rename from ~dev_rating/modules/unittest/guide/unittest/troubleshooting.md rename to doc/dev/testing/kohana/troubleshooting.md diff --git a/doc/dev/testing/kohana/usage.html b/doc/dev/testing/kohana/usage.html new file mode 100644 index 0000000000000000000000000000000000000000..1afb7ff33a2d0b7e8c2cdcffca84f8b51666579e --- /dev/null +++ b/doc/dev/testing/kohana/usage.html @@ -0,0 +1,994 @@ +<!DOCTYPE html><html><head><meta charset="utf-8"><style>body { + width: 45em; + border: 1px solid #ddd; + outline: 1300px solid #fff; + margin: 16px auto; +} + +body .markdown-body +{ + padding: 30px; +} + +@font-face { + font-family: octicons-anchor; + src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff'); +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + color: #333; + overflow: hidden; + font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; + font-size: 16px; + line-height: 1.6; + word-wrap: break-word; +} + +.markdown-body a { + background: transparent; +} + +.markdown-body a:active, +.markdown-body a:hover { + outline: 0; +} + +.markdown-body strong { + font-weight: bold; +} + +.markdown-body h1 { + font-size: 2em; + margin: 0.67em 0; +} + +.markdown-body img { + border: 0; +} + +.markdown-body hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +.markdown-body pre { + overflow: auto; +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre { + font-family: monospace, monospace; + font-size: 1em; +} + +.markdown-body input { + color: inherit; + font: inherit; + margin: 0; +} + +.markdown-body html input[disabled] { + cursor: default; +} + +.markdown-body input { + line-height: normal; +} + +.markdown-body input[type="checkbox"] { + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +.markdown-body table { + border-collapse: collapse; + border-spacing: 0; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body * { + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body input { + font: 13px/1.4 Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; +} + +.markdown-body a { + color: #4183c4; + text-decoration: none; +} + +.markdown-body a:hover, +.markdown-body a:focus, +.markdown-body a:active { + text-decoration: underline; +} + +.markdown-body hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #ddd; +} + +.markdown-body hr:before { + display: table; + content: ""; +} + +.markdown-body hr:after { + display: table; + clear: both; + content: ""; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 15px; + margin-bottom: 15px; + line-height: 1.1; +} + +.markdown-body h1 { + font-size: 30px; +} + +.markdown-body h2 { + font-size: 21px; +} + +.markdown-body h3 { + font-size: 16px; +} + +.markdown-body h4 { + font-size: 14px; +} + +.markdown-body h5 { + font-size: 12px; +} + +.markdown-body h6 { + font-size: 11px; +} + +.markdown-body blockquote { + margin: 0; +} + +.markdown-body ul, +.markdown-body ol { + padding: 0; + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ul ul ol, +.markdown-body ul ol ol, +.markdown-body ol ul ol, +.markdown-body ol ol ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body code { + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body .octicon { + font: normal normal 16px octicons-anchor; + line-height: 1; + display: inline-block; + text-decoration: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.markdown-body .octicon-link:before { + content: '\f05c'; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +.markdown-body .anchor { + position: absolute; + top: 0; + bottom: 0; + left: 0; + display: block; + padding-right: 6px; + padding-left: 30px; + margin-left: -30px; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + position: relative; + margin-top: 1em; + margin-bottom: 16px; + font-weight: bold; + line-height: 1.4; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + display: none; + color: #000; + vertical-align: middle; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + padding-left: 8px; + margin-left: -30px; + line-height: 1; + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + display: inline-block; +} + +.markdown-body h1 { + padding-bottom: 0.3em; + font-size: 2.25em; + line-height: 1.2; + border-bottom: 1px solid #eee; +} + +.markdown-body h2 { + padding-bottom: 0.3em; + font-size: 1.75em; + line-height: 1.225; + border-bottom: 1px solid #eee; +} + +.markdown-body h3 { + font-size: 1.5em; + line-height: 1.43; +} + +.markdown-body h4 { + font-size: 1.25em; +} + +.markdown-body h5 { + font-size: 1em; +} + +.markdown-body h6 { + font-size: 1em; + color: #777; +} + +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body hr { + height: 4px; + padding: 0; + margin: 16px 0; + background-color: #e7e7e7; + border: 0 none; +} + +.markdown-body ul, +.markdown-body ol { + padding-left: 2em; +} + +.markdown-body ul ul, +.markdown-body ul ol, +.markdown-body ol ol, +.markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: bold; +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body blockquote { + padding: 0 15px; + color: #777; + border-left: 4px solid #ddd; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body table { + display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; +} + +.markdown-body table th { + font-weight: bold; +} + +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid #ddd; +} + +.markdown-body table tr { + background-color: #fff; + border-top: 1px solid #ccc; +} + +.markdown-body table tr:nth-child(2n) { + background-color: #f8f8f8; +} + +.markdown-body img { + max-width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body code { + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + margin: 0; + font-size: 85%; + background-color: rgba(0,0,0,0.04); + border-radius: 3px; +} + +.markdown-body code:before, +.markdown-body code:after { + letter-spacing: -0.2em; + content: "\00a0"; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + font-size: 100%; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + border-radius: 3px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body pre { + word-wrap: normal; +} + +.markdown-body pre code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +.markdown-body pre code:before, +.markdown-body pre code:after { + content: normal; +} + +.markdown-body .highlight { + background: #fff; +} + +.markdown-body .highlight .h { + color: #333; + font-style: normal; + font-weight: normal; +} + +.markdown-body .highlight .mf, +.markdown-body .highlight .mh, +.markdown-body .highlight .mi, +.markdown-body .highlight .mo, +.markdown-body .highlight .il, +.markdown-body .highlight .m { + color: #945277; +} + +.markdown-body .highlight .s, +.markdown-body .highlight .sb, +.markdown-body .highlight .sc, +.markdown-body .highlight .sd, +.markdown-body .highlight .s2, +.markdown-body .highlight .se, +.markdown-body .highlight .sh, +.markdown-body .highlight .si, +.markdown-body .highlight .sx, +.markdown-body .highlight .s1 { + color: #df5000; +} + +.markdown-body .highlight .kc, +.markdown-body .highlight .kd, +.markdown-body .highlight .kn, +.markdown-body .highlight .kp, +.markdown-body .highlight .kr, +.markdown-body .highlight .kt, +.markdown-body .highlight .k, +.markdown-body .highlight .o { + font-weight: bold; +} + +.markdown-body .highlight .kt { + color: #458; +} + +.markdown-body .highlight .c, +.markdown-body .highlight .cm, +.markdown-body .highlight .c1 { + color: #998; + font-style: italic; +} + +.markdown-body .highlight .cp, +.markdown-body .highlight .cs, +.markdown-body .highlight .cp .h { + color: #999; + font-weight: bold; +} + +.markdown-body .highlight .cs { + font-style: italic; +} + +.markdown-body .highlight .n { + color: #333; +} + +.markdown-body .highlight .na, +.markdown-body .highlight .nv, +.markdown-body .highlight .vc, +.markdown-body .highlight .vg, +.markdown-body .highlight .vi { + color: #008080; +} + +.markdown-body .highlight .nb { + color: #0086B3; +} + +.markdown-body .highlight .nc { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .no { + color: #094e99; +} + +.markdown-body .highlight .ni { + color: #800080; +} + +.markdown-body .highlight .ne { + color: #990000; + font-weight: bold; +} + +.markdown-body .highlight .nf { + color: #945277; + font-weight: bold; +} + +.markdown-body .highlight .nn { + color: #555; +} + +.markdown-body .highlight .nt { + color: #000080; +} + +.markdown-body .highlight .err { + color: #a61717; + background-color: #e3d2d2; +} + +.markdown-body .highlight .gd { + color: #000; + background-color: #fdd; +} + +.markdown-body .highlight .gd .x { + color: #000; + background-color: #faa; +} + +.markdown-body .highlight .ge { + font-style: italic; +} + +.markdown-body .highlight .gr { + color: #aa0000; +} + +.markdown-body .highlight .gh { + color: #999; +} + +.markdown-body .highlight .gi { + color: #000; + background-color: #dfd; +} + +.markdown-body .highlight .gi .x { + color: #000; + background-color: #afa; +} + +.markdown-body .highlight .go { + color: #888; +} + +.markdown-body .highlight .gp { + color: #555; +} + +.markdown-body .highlight .gs { + font-weight: bold; +} + +.markdown-body .highlight .gu { + color: #800080; + font-weight: bold; +} + +.markdown-body .highlight .gt { + color: #aa0000; +} + +.markdown-body .highlight .ow { + font-weight: bold; +} + +.markdown-body .highlight .w { + color: #bbb; +} + +.markdown-body .highlight .sr { + color: #017936; +} + +.markdown-body .highlight .ss { + color: #8b467f; +} + +.markdown-body .highlight .bp { + color: #999; +} + +.markdown-body .highlight .gc { + color: #999; + background-color: #EAF2F5; +} + +.markdown-body kbd { + background-color: #e7e7e7; + background-image: -webkit-linear-gradient(#fefefe, #e7e7e7); + background-image: linear-gradient(#fefefe, #e7e7e7); + background-repeat: repeat-x; + display: inline-block; + padding: 3px 5px; + font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; + line-height: 10px; + color: #000; + border: 1px solid #cfcfcf; + border-radius: 2px; +} + +.markdown-body .highlight .pl-coc, +.markdown-body .highlight .pl-entm, +.markdown-body .highlight .pl-eoa, +.markdown-body .highlight .pl-mai .pl-sf, +.markdown-body .highlight .pl-pdv, +.markdown-body .highlight .pl-sc, +.markdown-body .highlight .pl-sr, +.markdown-body .highlight .pl-v, +.markdown-body .highlight .pl-vpf { + color: #0086b3; +} + +.markdown-body .highlight .pl-eoac, +.markdown-body .highlight .pl-mdht, +.markdown-body .highlight .pl-mi1, +.markdown-body .highlight .pl-mri, +.markdown-body .highlight .pl-va, +.markdown-body .highlight .pl-vpu { + color: #008080; +} + +.markdown-body .highlight .pl-c, +.markdown-body .highlight .pl-pdc { + color: #b4b7b4; + font-style: italic; +} + +.markdown-body .highlight .pl-k, +.markdown-body .highlight .pl-ko, +.markdown-body .highlight .pl-kolp, +.markdown-body .highlight .pl-mc, +.markdown-body .highlight .pl-mr, +.markdown-body .highlight .pl-ms, +.markdown-body .highlight .pl-s, +.markdown-body .highlight .pl-sok, +.markdown-body .highlight .pl-st { + color: #6e5494; +} + +.markdown-body .highlight .pl-ef, +.markdown-body .highlight .pl-enf, +.markdown-body .highlight .pl-enm, +.markdown-body .highlight .pl-entc, +.markdown-body .highlight .pl-eoi, +.markdown-body .highlight .pl-sf, +.markdown-body .highlight .pl-smc { + color: #d12089; +} + +.markdown-body .highlight .pl-ens, +.markdown-body .highlight .pl-eoai, +.markdown-body .highlight .pl-kos, +.markdown-body .highlight .pl-mh .pl-pdh, +.markdown-body .highlight .pl-mp, +.markdown-body .highlight .pl-pde, +.markdown-body .highlight .pl-stp { + color: #458; +} + +.markdown-body .highlight .pl-enti { + color: #d12089; + font-weight: bold; +} + +.markdown-body .highlight .pl-cce, +.markdown-body .highlight .pl-enc, +.markdown-body .highlight .pl-kou, +.markdown-body .highlight .pl-mq { + color: #f93; +} + +.markdown-body .highlight .pl-mp1 .pl-sf { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .pl-cos, +.markdown-body .highlight .pl-ent, +.markdown-body .highlight .pl-md, +.markdown-body .highlight .pl-mdhf, +.markdown-body .highlight .pl-ml, +.markdown-body .highlight .pl-pdc1, +.markdown-body .highlight .pl-pds, +.markdown-body .highlight .pl-s1, +.markdown-body .highlight .pl-scp, +.markdown-body .highlight .pl-sol { + color: #df5000; +} + +.markdown-body .highlight .pl-c1, +.markdown-body .highlight .pl-cn, +.markdown-body .highlight .pl-pse, +.markdown-body .highlight .pl-pse .pl-s2, +.markdown-body .highlight .pl-vi { + color: #a31515; +} + +.markdown-body .highlight .pl-mb, +.markdown-body .highlight .pl-pdb { + color: #df5000; + font-weight: bold; +} + +.markdown-body .highlight .pl-mi, +.markdown-body .highlight .pl-pdi { + color: #6e5494; + font-style: italic; +} + +.markdown-body .highlight .pl-ms1 { + background-color: #f5f5f5; +} + +.markdown-body .highlight .pl-mdh, +.markdown-body .highlight .pl-mdi { + font-weight: bold; +} + +.markdown-body .highlight .pl-mdr { + color: #0086b3; + font-weight: bold; +} + +.markdown-body .highlight .pl-s2 { + color: #333; +} + +.markdown-body .highlight .pl-ii { + background-color: #df5000; + color: #fff; +} + +.markdown-body .highlight .pl-ib { + background-color: #f93; +} + +.markdown-body .highlight .pl-id { + background-color: #a31515; + color: #fff; +} + +.markdown-body .highlight .pl-iu { + background-color: #b4b7b4; +} + +.markdown-body .highlight .pl-mo { + color: #969896; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 3px; +} + +.markdown-body .task-list-item input { + float: left; + margin: 0.3em 0 0.25em -1.6em; + vertical-align: middle; +}</style><title>usage</title></head><body><article class="markdown-body"><h1 id="usage"> +<a id="user-content-usage" class="anchor" href="#usage" aria-hidden="true"><span class="octicon octicon-link"></span></a>Usage</h1> + +<pre><code>$ phpunit --bootstrap=modules/unittest/bootstrap.php modules/unittest/tests.php +</code></pre> + +<p>Alternatively you can use a phpunit.xml to have a more fine grained control over which tests are included and which files are whitelisted.</p> + +<p>Make sure you only whitelist the highest files in the cascading filesystem, else you could end up with a lot of "class cannot be redefined" errors.</p> + +<p>If you use the tests.php testsuite loader then it will only whitelist the highest files. see config/unittest.php for details on configuring the tests.php whitelist.</p> + +<h2 id="writing-tests"> +<a id="user-content-writing-tests" class="anchor" href="#writing-tests" aria-hidden="true"><span class="octicon octicon-link"></span></a>Writing tests</h2> + +<p>If you're writing a test for your application, place it in "application/tests". Similarly, if you're writing a test for a module place it in modules/[modulefolder]/tests</p> + +<p>Rather than tell you how to write tests I'll point you in the direction of the <a href="http://www.phpunit.de/manual/3.4/en/index.html">PHPUnit Manual</a>. One thing you should bear in mind when writing tests is that testcases should extend Unittest_Testcase rather than PHPUnit_Framework_TestCase, doing so gives you access to useful kohana specific helpers such as <code>setEnvironment()</code>.</p> + +<p>Here's a taster of some of the cool things you can do with phpunit:</p> + +<h3 id="data-providers"> +<a id="user-content-data-providers" class="anchor" href="#data-providers" aria-hidden="true"><span class="octicon octicon-link"></span></a>Data Providers</h3> + +<p>Sometimes you want to be able to run a specific test with different sets of data to try and test every eventuality</p> + +<p>Ordinarily you could use a foreach loop to iterate over an array of test data, however PHPUnit already can take care of this for us rather easily using "Data Providers". A data provider is a function that returns an array of arguments that can be passed to a test.</p> + +<pre><code><?php + +Class ReallyCoolTest extends Unittest_TestCase +{ + function providerStrLen() + { + return array( + array('One set of testcase data', 24), + array('This is a different one', 23), + ); + } + + /** + * @dataProvider providerStrLen + */ + function testStrLen($string, $length) + { + $this->assertSame( + $length, + strlen($string) + ); + } +} +</code></pre> + +<p>The key thing to notice is the <code>@dataProvider</code> tag in the doccomment, this is what tells PHPUnit to use a data provider. The provider prefix is totally optional but it's a nice standard to identify providers.</p> + +<p>For more info see:</p> + +<ul> +<li><a href="http://sebastian-bergmann.de/archives/702-Data-Providers-in-PHPUnit-3.2.html">Data Providers in PHPUnit 3.2</a></li> +<li><a href="http://www.phpunit.de/manual/3.4/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers">Data Providers</a></li> +</ul> + +<h3 id="grouping-tests"> +<a id="user-content-grouping-tests" class="anchor" href="#grouping-tests" aria-hidden="true"><span class="octicon octicon-link"></span></a>Grouping tests</h3> + +<p>To allow users to selectively run tests you need to organise your tests into groups. Here's an example test showing how to do this:</p> + +<pre><code><?php + +/** + * This is a description for my testcase + * + * @group somegroup + * @group somegroup.morespecific + */ +Class AnotherReallyCoolTest extends Unittest_TestCase +{ + /** + * Tests can also be grouped too! + * + * @group somegroup.morespecific.annoyingstuff + */ + function testSomeAnnoyingCase() + { + // CODE!! + } +} +</code></pre> + +<p>Our convention is to use lowercase group names, with more specific levels in a group seperated by periods. i.e. The Validate helper tests are part of the following groups:</p> + +<pre><code>kohana +kohana.validation +kohana.validation.helpers +</code></pre> + +<p>To actually limit your testing to the "somegroup" group, use:</p> + +<pre><code>$ phpunit --boostrap=index.php --group=somegroup modules/unittest/tests.php +</code></pre> + +<p>This functionality can be used to record which bug reports a test is for:</p> + +<pre><code>/** + * + * @group bugs.1477 + */ +function testAccountCannotGoBelowZero() +{ + // Some arbitary code +} +</code></pre> + +<p>To see all groups that are available in your code run:</p> + +<pre><code>$ phpunit --boostrap=modules/unittest/bootstrap.php --list-groups modules/unittest/tests.php +</code></pre> + +<p><em>Note:</em> the <code>--list-groups</code> switch should appear before the path to the test suite loader</p> + +<p>You can also exclude groups while testing using the <code>--exclude-group</code> switch. This can be useful if you want to ignore all kohana tests:</p> + +<pre><code>$ phpunit --bootstrap=modules/unittest/bootstrap.php --exclude-group=kohana modules/unittest/tests.php +</code></pre> + +<p>For more info see:</p> + +<ul> +<li><a href="http://mikenaberezny.com/2007/09/04/better-phpunit-group-annotations/">Better PHPUnit Group Annotations</a></li> +<li><a href="http://sebastian-bergmann.de/archives/697-TestNG-style-Grouping-of-Tests.html">TestNG style Grouping of Tests in PHPUnit 3.2</a></li> +</ul> +</article></body></html> \ No newline at end of file diff --git a/~dev_rating/modules/unittest/guide/unittest/testing.md b/doc/dev/testing/kohana/usage.md similarity index 100% rename from ~dev_rating/modules/unittest/guide/unittest/testing.md rename to doc/dev/testing/kohana/usage.md diff --git a/doc/dev/testing/phpunit.html b/doc/dev/testing/phpunit.html new file mode 100644 index 0000000000000000000000000000000000000000..598f1ba9f0dc8842f6ad409046a392afdbf65a9d --- /dev/null +++ b/doc/dev/testing/phpunit.html @@ -0,0 +1,930 @@ +<!DOCTYPE html><html><head><meta charset="utf-8"><style>body { + width: 45em; + border: 1px solid #ddd; + outline: 1300px solid #fff; + margin: 16px auto; +} + +body .markdown-body +{ + padding: 30px; +} + +@font-face { + font-family: octicons-anchor; + src: url(data:font/woff;charset=utf-8;base64,d09GRgABAAAAAAYcAA0AAAAACjQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABMAAAABwAAAAca8vGTk9TLzIAAAFMAAAARAAAAFZG1VHVY21hcAAAAZAAAAA+AAABQgAP9AdjdnQgAAAB0AAAAAQAAAAEACICiGdhc3AAAAHUAAAACAAAAAj//wADZ2x5ZgAAAdwAAADRAAABEKyikaNoZWFkAAACsAAAAC0AAAA2AtXoA2hoZWEAAALgAAAAHAAAACQHngNFaG10eAAAAvwAAAAQAAAAEAwAACJsb2NhAAADDAAAAAoAAAAKALIAVG1heHAAAAMYAAAAHwAAACABEAB2bmFtZQAAAzgAAALBAAAFu3I9x/Nwb3N0AAAF/AAAAB0AAAAvaoFvbwAAAAEAAAAAzBdyYwAAAADP2IQvAAAAAM/bz7t4nGNgZGFgnMDAysDB1Ml0hoGBoR9CM75mMGLkYGBgYmBlZsAKAtJcUxgcPsR8iGF2+O/AEMPsznAYKMwIkgMA5REMOXicY2BgYGaAYBkGRgYQsAHyGMF8FgYFIM0ChED+h5j//yEk/3KoSgZGNgYYk4GRCUgwMaACRoZhDwCs7QgGAAAAIgKIAAAAAf//AAJ4nHWMMQrCQBBF/0zWrCCIKUQsTDCL2EXMohYGSSmorScInsRGL2DOYJe0Ntp7BK+gJ1BxF1stZvjz/v8DRghQzEc4kIgKwiAppcA9LtzKLSkdNhKFY3HF4lK69ExKslx7Xa+vPRVS43G98vG1DnkDMIBUgFN0MDXflU8tbaZOUkXUH0+U27RoRpOIyCKjbMCVejwypzJJG4jIwb43rfl6wbwanocrJm9XFYfskuVC5K/TPyczNU7b84CXcbxks1Un6H6tLH9vf2LRnn8Ax7A5WQAAAHicY2BkYGAA4teL1+yI57f5ysDNwgAC529f0kOmWRiYVgEpDgYmEA8AUzEKsQAAAHicY2BkYGB2+O/AEMPCAAJAkpEBFbAAADgKAe0EAAAiAAAAAAQAAAAEAAAAAAAAKgAqACoAiAAAeJxjYGRgYGBhsGFgYgABEMkFhAwM/xn0QAIAD6YBhwB4nI1Ty07cMBS9QwKlQapQW3VXySvEqDCZGbGaHULiIQ1FKgjWMxknMfLEke2A+IJu+wntrt/QbVf9gG75jK577Lg8K1qQPCfnnnt8fX1NRC/pmjrk/zprC+8D7tBy9DHgBXoWfQ44Av8t4Bj4Z8CLtBL9CniJluPXASf0Lm4CXqFX8Q84dOLnMB17N4c7tBo1AS/Qi+hTwBH4rwHHwN8DXqQ30XXAS7QaLwSc0Gn8NuAVWou/gFmnjLrEaEh9GmDdDGgL3B4JsrRPDU2hTOiMSuJUIdKQQayiAth69r6akSSFqIJuA19TrzCIaY8sIoxyrNIrL//pw7A2iMygkX5vDj+G+kuoLdX4GlGK/8Lnlz6/h9MpmoO9rafrz7ILXEHHaAx95s9lsI7AHNMBWEZHULnfAXwG9/ZqdzLI08iuwRloXE8kfhXYAvE23+23DU3t626rbs8/8adv+9DWknsHp3E17oCf+Z48rvEQNZ78paYM38qfk3v/u3l3u3GXN2Dmvmvpf1Srwk3pB/VSsp512bA/GG5i2WJ7wu430yQ5K3nFGiOqgtmSB5pJVSizwaacmUZzZhXLlZTq8qGGFY2YcSkqbth6aW1tRmlaCFs2016m5qn36SbJrqosG4uMV4aP2PHBmB3tjtmgN2izkGQyLWprekbIntJFing32a5rKWCN/SdSoga45EJykyQ7asZvHQ8PTm6cslIpwyeyjbVltNikc2HTR7YKh9LBl9DADC0U/jLcBZDKrMhUBfQBvXRzLtFtjU9eNHKin0x5InTqb8lNpfKv1s1xHzTXRqgKzek/mb7nB8RZTCDhGEX3kK/8Q75AmUM/eLkfA+0Hi908Kx4eNsMgudg5GLdRD7a84npi+YxNr5i5KIbW5izXas7cHXIMAau1OueZhfj+cOcP3P8MNIWLyYOBuxL6DRylJ4cAAAB4nGNgYoAALjDJyIAOWMCiTIxMLDmZedkABtIBygAAAA==) format('woff'); +} + +.markdown-body { + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + color: #333; + overflow: hidden; + font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, freesans, sans-serif; + font-size: 16px; + line-height: 1.6; + word-wrap: break-word; +} + +.markdown-body a { + background: transparent; +} + +.markdown-body a:active, +.markdown-body a:hover { + outline: 0; +} + +.markdown-body strong { + font-weight: bold; +} + +.markdown-body h1 { + font-size: 2em; + margin: 0.67em 0; +} + +.markdown-body img { + border: 0; +} + +.markdown-body hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +.markdown-body pre { + overflow: auto; +} + +.markdown-body code, +.markdown-body kbd, +.markdown-body pre { + font-family: monospace, monospace; + font-size: 1em; +} + +.markdown-body input { + color: inherit; + font: inherit; + margin: 0; +} + +.markdown-body html input[disabled] { + cursor: default; +} + +.markdown-body input { + line-height: normal; +} + +.markdown-body input[type="checkbox"] { + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} + +.markdown-body table { + border-collapse: collapse; + border-spacing: 0; +} + +.markdown-body td, +.markdown-body th { + padding: 0; +} + +.markdown-body * { + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body input { + font: 13px/1.4 Helvetica, arial, freesans, clean, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; +} + +.markdown-body a { + color: #4183c4; + text-decoration: none; +} + +.markdown-body a:hover, +.markdown-body a:focus, +.markdown-body a:active { + text-decoration: underline; +} + +.markdown-body hr { + height: 0; + margin: 15px 0; + overflow: hidden; + background: transparent; + border: 0; + border-bottom: 1px solid #ddd; +} + +.markdown-body hr:before { + display: table; + content: ""; +} + +.markdown-body hr:after { + display: table; + clear: both; + content: ""; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + margin-top: 15px; + margin-bottom: 15px; + line-height: 1.1; +} + +.markdown-body h1 { + font-size: 30px; +} + +.markdown-body h2 { + font-size: 21px; +} + +.markdown-body h3 { + font-size: 16px; +} + +.markdown-body h4 { + font-size: 14px; +} + +.markdown-body h5 { + font-size: 12px; +} + +.markdown-body h6 { + font-size: 11px; +} + +.markdown-body blockquote { + margin: 0; +} + +.markdown-body ul, +.markdown-body ol { + padding: 0; + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body ol ol, +.markdown-body ul ol { + list-style-type: lower-roman; +} + +.markdown-body ul ul ol, +.markdown-body ul ol ol, +.markdown-body ol ul ol, +.markdown-body ol ol ol { + list-style-type: lower-alpha; +} + +.markdown-body dd { + margin-left: 0; +} + +.markdown-body code { + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body pre { + margin-top: 0; + margin-bottom: 0; + font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; +} + +.markdown-body .octicon { + font: normal normal 16px octicons-anchor; + line-height: 1; + display: inline-block; + text-decoration: none; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +.markdown-body .octicon-link:before { + content: '\f05c'; +} + +.markdown-body>*:first-child { + margin-top: 0 !important; +} + +.markdown-body>*:last-child { + margin-bottom: 0 !important; +} + +.markdown-body .anchor { + position: absolute; + top: 0; + bottom: 0; + left: 0; + display: block; + padding-right: 6px; + padding-left: 30px; + margin-left: -30px; +} + +.markdown-body .anchor:focus { + outline: none; +} + +.markdown-body h1, +.markdown-body h2, +.markdown-body h3, +.markdown-body h4, +.markdown-body h5, +.markdown-body h6 { + position: relative; + margin-top: 1em; + margin-bottom: 16px; + font-weight: bold; + line-height: 1.4; +} + +.markdown-body h1 .octicon-link, +.markdown-body h2 .octicon-link, +.markdown-body h3 .octicon-link, +.markdown-body h4 .octicon-link, +.markdown-body h5 .octicon-link, +.markdown-body h6 .octicon-link { + display: none; + color: #000; + vertical-align: middle; +} + +.markdown-body h1:hover .anchor, +.markdown-body h2:hover .anchor, +.markdown-body h3:hover .anchor, +.markdown-body h4:hover .anchor, +.markdown-body h5:hover .anchor, +.markdown-body h6:hover .anchor { + padding-left: 8px; + margin-left: -30px; + line-height: 1; + text-decoration: none; +} + +.markdown-body h1:hover .anchor .octicon-link, +.markdown-body h2:hover .anchor .octicon-link, +.markdown-body h3:hover .anchor .octicon-link, +.markdown-body h4:hover .anchor .octicon-link, +.markdown-body h5:hover .anchor .octicon-link, +.markdown-body h6:hover .anchor .octicon-link { + display: inline-block; +} + +.markdown-body h1 { + padding-bottom: 0.3em; + font-size: 2.25em; + line-height: 1.2; + border-bottom: 1px solid #eee; +} + +.markdown-body h2 { + padding-bottom: 0.3em; + font-size: 1.75em; + line-height: 1.225; + border-bottom: 1px solid #eee; +} + +.markdown-body h3 { + font-size: 1.5em; + line-height: 1.43; +} + +.markdown-body h4 { + font-size: 1.25em; +} + +.markdown-body h5 { + font-size: 1em; +} + +.markdown-body h6 { + font-size: 1em; + color: #777; +} + +.markdown-body p, +.markdown-body blockquote, +.markdown-body ul, +.markdown-body ol, +.markdown-body dl, +.markdown-body table, +.markdown-body pre { + margin-top: 0; + margin-bottom: 16px; +} + +.markdown-body hr { + height: 4px; + padding: 0; + margin: 16px 0; + background-color: #e7e7e7; + border: 0 none; +} + +.markdown-body ul, +.markdown-body ol { + padding-left: 2em; +} + +.markdown-body ul ul, +.markdown-body ul ol, +.markdown-body ol ol, +.markdown-body ol ul { + margin-top: 0; + margin-bottom: 0; +} + +.markdown-body li>p { + margin-top: 16px; +} + +.markdown-body dl { + padding: 0; +} + +.markdown-body dl dt { + padding: 0; + margin-top: 16px; + font-size: 1em; + font-style: italic; + font-weight: bold; +} + +.markdown-body dl dd { + padding: 0 16px; + margin-bottom: 16px; +} + +.markdown-body blockquote { + padding: 0 15px; + color: #777; + border-left: 4px solid #ddd; +} + +.markdown-body blockquote>:first-child { + margin-top: 0; +} + +.markdown-body blockquote>:last-child { + margin-bottom: 0; +} + +.markdown-body table { + display: block; + width: 100%; + overflow: auto; + word-break: normal; + word-break: keep-all; +} + +.markdown-body table th { + font-weight: bold; +} + +.markdown-body table th, +.markdown-body table td { + padding: 6px 13px; + border: 1px solid #ddd; +} + +.markdown-body table tr { + background-color: #fff; + border-top: 1px solid #ccc; +} + +.markdown-body table tr:nth-child(2n) { + background-color: #f8f8f8; +} + +.markdown-body img { + max-width: 100%; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.markdown-body code { + padding: 0; + padding-top: 0.2em; + padding-bottom: 0.2em; + margin: 0; + font-size: 85%; + background-color: rgba(0,0,0,0.04); + border-radius: 3px; +} + +.markdown-body code:before, +.markdown-body code:after { + letter-spacing: -0.2em; + content: "\00a0"; +} + +.markdown-body pre>code { + padding: 0; + margin: 0; + font-size: 100%; + word-break: normal; + white-space: pre; + background: transparent; + border: 0; +} + +.markdown-body .highlight { + margin-bottom: 16px; +} + +.markdown-body .highlight pre, +.markdown-body pre { + padding: 16px; + overflow: auto; + font-size: 85%; + line-height: 1.45; + background-color: #f7f7f7; + border-radius: 3px; +} + +.markdown-body .highlight pre { + margin-bottom: 0; + word-break: normal; +} + +.markdown-body pre { + word-wrap: normal; +} + +.markdown-body pre code { + display: inline; + max-width: initial; + padding: 0; + margin: 0; + overflow: initial; + line-height: inherit; + word-wrap: normal; + background-color: transparent; + border: 0; +} + +.markdown-body pre code:before, +.markdown-body pre code:after { + content: normal; +} + +.markdown-body .highlight { + background: #fff; +} + +.markdown-body .highlight .h { + color: #333; + font-style: normal; + font-weight: normal; +} + +.markdown-body .highlight .mf, +.markdown-body .highlight .mh, +.markdown-body .highlight .mi, +.markdown-body .highlight .mo, +.markdown-body .highlight .il, +.markdown-body .highlight .m { + color: #945277; +} + +.markdown-body .highlight .s, +.markdown-body .highlight .sb, +.markdown-body .highlight .sc, +.markdown-body .highlight .sd, +.markdown-body .highlight .s2, +.markdown-body .highlight .se, +.markdown-body .highlight .sh, +.markdown-body .highlight .si, +.markdown-body .highlight .sx, +.markdown-body .highlight .s1 { + color: #df5000; +} + +.markdown-body .highlight .kc, +.markdown-body .highlight .kd, +.markdown-body .highlight .kn, +.markdown-body .highlight .kp, +.markdown-body .highlight .kr, +.markdown-body .highlight .kt, +.markdown-body .highlight .k, +.markdown-body .highlight .o { + font-weight: bold; +} + +.markdown-body .highlight .kt { + color: #458; +} + +.markdown-body .highlight .c, +.markdown-body .highlight .cm, +.markdown-body .highlight .c1 { + color: #998; + font-style: italic; +} + +.markdown-body .highlight .cp, +.markdown-body .highlight .cs, +.markdown-body .highlight .cp .h { + color: #999; + font-weight: bold; +} + +.markdown-body .highlight .cs { + font-style: italic; +} + +.markdown-body .highlight .n { + color: #333; +} + +.markdown-body .highlight .na, +.markdown-body .highlight .nv, +.markdown-body .highlight .vc, +.markdown-body .highlight .vg, +.markdown-body .highlight .vi { + color: #008080; +} + +.markdown-body .highlight .nb { + color: #0086B3; +} + +.markdown-body .highlight .nc { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .no { + color: #094e99; +} + +.markdown-body .highlight .ni { + color: #800080; +} + +.markdown-body .highlight .ne { + color: #990000; + font-weight: bold; +} + +.markdown-body .highlight .nf { + color: #945277; + font-weight: bold; +} + +.markdown-body .highlight .nn { + color: #555; +} + +.markdown-body .highlight .nt { + color: #000080; +} + +.markdown-body .highlight .err { + color: #a61717; + background-color: #e3d2d2; +} + +.markdown-body .highlight .gd { + color: #000; + background-color: #fdd; +} + +.markdown-body .highlight .gd .x { + color: #000; + background-color: #faa; +} + +.markdown-body .highlight .ge { + font-style: italic; +} + +.markdown-body .highlight .gr { + color: #aa0000; +} + +.markdown-body .highlight .gh { + color: #999; +} + +.markdown-body .highlight .gi { + color: #000; + background-color: #dfd; +} + +.markdown-body .highlight .gi .x { + color: #000; + background-color: #afa; +} + +.markdown-body .highlight .go { + color: #888; +} + +.markdown-body .highlight .gp { + color: #555; +} + +.markdown-body .highlight .gs { + font-weight: bold; +} + +.markdown-body .highlight .gu { + color: #800080; + font-weight: bold; +} + +.markdown-body .highlight .gt { + color: #aa0000; +} + +.markdown-body .highlight .ow { + font-weight: bold; +} + +.markdown-body .highlight .w { + color: #bbb; +} + +.markdown-body .highlight .sr { + color: #017936; +} + +.markdown-body .highlight .ss { + color: #8b467f; +} + +.markdown-body .highlight .bp { + color: #999; +} + +.markdown-body .highlight .gc { + color: #999; + background-color: #EAF2F5; +} + +.markdown-body kbd { + background-color: #e7e7e7; + background-image: -webkit-linear-gradient(#fefefe, #e7e7e7); + background-image: linear-gradient(#fefefe, #e7e7e7); + background-repeat: repeat-x; + display: inline-block; + padding: 3px 5px; + font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; + line-height: 10px; + color: #000; + border: 1px solid #cfcfcf; + border-radius: 2px; +} + +.markdown-body .highlight .pl-coc, +.markdown-body .highlight .pl-entm, +.markdown-body .highlight .pl-eoa, +.markdown-body .highlight .pl-mai .pl-sf, +.markdown-body .highlight .pl-pdv, +.markdown-body .highlight .pl-sc, +.markdown-body .highlight .pl-sr, +.markdown-body .highlight .pl-v, +.markdown-body .highlight .pl-vpf { + color: #0086b3; +} + +.markdown-body .highlight .pl-eoac, +.markdown-body .highlight .pl-mdht, +.markdown-body .highlight .pl-mi1, +.markdown-body .highlight .pl-mri, +.markdown-body .highlight .pl-va, +.markdown-body .highlight .pl-vpu { + color: #008080; +} + +.markdown-body .highlight .pl-c, +.markdown-body .highlight .pl-pdc { + color: #b4b7b4; + font-style: italic; +} + +.markdown-body .highlight .pl-k, +.markdown-body .highlight .pl-ko, +.markdown-body .highlight .pl-kolp, +.markdown-body .highlight .pl-mc, +.markdown-body .highlight .pl-mr, +.markdown-body .highlight .pl-ms, +.markdown-body .highlight .pl-s, +.markdown-body .highlight .pl-sok, +.markdown-body .highlight .pl-st { + color: #6e5494; +} + +.markdown-body .highlight .pl-ef, +.markdown-body .highlight .pl-enf, +.markdown-body .highlight .pl-enm, +.markdown-body .highlight .pl-entc, +.markdown-body .highlight .pl-eoi, +.markdown-body .highlight .pl-sf, +.markdown-body .highlight .pl-smc { + color: #d12089; +} + +.markdown-body .highlight .pl-ens, +.markdown-body .highlight .pl-eoai, +.markdown-body .highlight .pl-kos, +.markdown-body .highlight .pl-mh .pl-pdh, +.markdown-body .highlight .pl-mp, +.markdown-body .highlight .pl-pde, +.markdown-body .highlight .pl-stp { + color: #458; +} + +.markdown-body .highlight .pl-enti { + color: #d12089; + font-weight: bold; +} + +.markdown-body .highlight .pl-cce, +.markdown-body .highlight .pl-enc, +.markdown-body .highlight .pl-kou, +.markdown-body .highlight .pl-mq { + color: #f93; +} + +.markdown-body .highlight .pl-mp1 .pl-sf { + color: #458; + font-weight: bold; +} + +.markdown-body .highlight .pl-cos, +.markdown-body .highlight .pl-ent, +.markdown-body .highlight .pl-md, +.markdown-body .highlight .pl-mdhf, +.markdown-body .highlight .pl-ml, +.markdown-body .highlight .pl-pdc1, +.markdown-body .highlight .pl-pds, +.markdown-body .highlight .pl-s1, +.markdown-body .highlight .pl-scp, +.markdown-body .highlight .pl-sol { + color: #df5000; +} + +.markdown-body .highlight .pl-c1, +.markdown-body .highlight .pl-cn, +.markdown-body .highlight .pl-pse, +.markdown-body .highlight .pl-pse .pl-s2, +.markdown-body .highlight .pl-vi { + color: #a31515; +} + +.markdown-body .highlight .pl-mb, +.markdown-body .highlight .pl-pdb { + color: #df5000; + font-weight: bold; +} + +.markdown-body .highlight .pl-mi, +.markdown-body .highlight .pl-pdi { + color: #6e5494; + font-style: italic; +} + +.markdown-body .highlight .pl-ms1 { + background-color: #f5f5f5; +} + +.markdown-body .highlight .pl-mdh, +.markdown-body .highlight .pl-mdi { + font-weight: bold; +} + +.markdown-body .highlight .pl-mdr { + color: #0086b3; + font-weight: bold; +} + +.markdown-body .highlight .pl-s2 { + color: #333; +} + +.markdown-body .highlight .pl-ii { + background-color: #df5000; + color: #fff; +} + +.markdown-body .highlight .pl-ib { + background-color: #f93; +} + +.markdown-body .highlight .pl-id { + background-color: #a31515; + color: #fff; +} + +.markdown-body .highlight .pl-iu { + background-color: #b4b7b4; +} + +.markdown-body .highlight .pl-mo { + color: #969896; +} + +.markdown-body .task-list-item { + list-style-type: none; +} + +.markdown-body .task-list-item+.task-list-item { + margin-top: 3px; +} + +.markdown-body .task-list-item input { + float: left; + margin: 0.3em 0 0.25em -1.6em; + vertical-align: middle; +}</style><title>phpunit</title></head><body><article class="markdown-body"><h1 id="phpunit"> +<a id="user-content-phpunit" class="anchor" href="#phpunit" aria-hidden="true"><span class="octicon octicon-link"></span></a>PHPUnit</h1> + +<p><a href="https://phpunit.de/">PHPUnit</a> — фреймворк для СЋРЅРёС‚-тестирования приложений. РЎ некоторого времени стал поддерживать Рё поведенческие тесты (BDD РїРѕРґС…РѕРґ). Нужно учитывать, что РёР·-Р·Р° MVC модели Kohana, нужно использовать <em>непрямой</em> доступ Рє классам. Почитать РѕР± этом можно РІ разделе <a href="../index.html#kohana-integration">Kohana integration</a>.</p> + +<blockquote> +<p>Возможно здесь появится иформация Рѕ TDD/BDD Рё прочих штуках</p> +</blockquote> + +<h2 id="composer"> +<a id="user-content-composer" class="anchor" href="#composer" aria-hidden="true"><span class="octicon octicon-link"></span></a>Composer</h2> + +<p><a href="https://getcomposer.org/">Composer</a> — менеджер зависимостей для приложений, написанных РЅР° PHP. Сильно облегчает задачу обновления всех подключенных Рє проекту библиотек Рё фрейморков.</p> + +<p><a href="https://getcomposer.org/Composer-Setup.exe">Скачиваем</a> себе РЅР° машину, РїСЂРё установке указываем путь <code>OpenServer/modules/php/PHP-5.5/php.exe</code> — далее РѕРЅ самостоятельно добавится РІ PATH так, что РІС‹ сможете вызвать его РёР· любой директории.</p> + +<p>Запускаем OpenServer, РІ меню выбираем: <em>Дополнительно</em> | <em>Консоль</em>. Команда <a href="https://getcomposer.org/doc/03-cli.md#self-update"><code>self-update</code></a> РѕР±РЅРѕРІРёС‚ Composer РґРѕ последней версии.</p> + +<pre><code>$ php w:\modules\php\PHP-5.5\composer.phar self-update +</code></pre> + +<h2 id="%D1%83%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D0%B2%D0%BD%D0%B5-%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B0"> +<a id="user-content-Установка-РІРЅРµ-проекта" class="anchor" href="#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0-%D0%B2%D0%BD%D0%B5-%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B0" aria-hidden="true"><span class="octicon octicon-link"></span></a>Установка РІРЅРµ проекта</h2> + +<div class="highlight highlight-bash"><pre>$ composer global require <span class="pl-s"><span class="pl-pds">"</span>phpunit/phpunit=4.5.*<span class="pl-pds">"</span></span></pre></div> + +<p>Composer подключится Рє репозиторию, скачает Рё установит пакеты.</p> + +<p>Открываем <code>OpenServer/modules/php/PHP-5.5/</code>, создаём файл <code>phpunit.bat</code> РІ РєРѕРґРёСЂРѕРІРєРµ CP886 (Cyrillic Windows), СЃРѕ следующим содержимым (<code>%username%</code> — РёРјСЏ пользователя):</p> + +<div class="highlight highlight-bash"><pre>@ECHO OFF +php <span class="pl-s"><span class="pl-pds">"</span>C:/Users/%username%/AppData/Roaming/Composer/vendor/phpunit/phpunit/phpunit<span class="pl-pds">"</span></span> %<span class="pl-k">*</span></pre></div> + +<p>Пробуем работоспособность РІ консоли: <code>$ phpunit</code>. Р’ ответ выпадет СЃРїРёСЃРѕРє параметров Рё строка:</p> + +<pre><code>PHPUnit 4.5.0 by Sebastian Bergmann and contributors. +</code></pre> + +<h4 id="%D0%BA%D0%B0%D0%BA-%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D1%82%D0%B8%D1%82%D1%8C-%D1%82%D0%B5%D1%81%D1%82%D1%8B"> +<a id="user-content-Как-запустить-тесты" class="anchor" href="#%D0%9A%D0%B0%D0%BA-%D0%B7%D0%B0%D0%BF%D1%83%D1%81%D1%82%D0%B8%D1%82%D1%8C-%D1%82%D0%B5%D1%81%D1%82%D1%8B" aria-hidden="true"><span class="octicon octicon-link"></span></a>Как запустить тесты</h4> + +<p>Согласно <a href="https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html">туториалу</a> пишем тест:</p> + +<div class="highlight highlight-php"><pre><span class="pl-pse"><?php</span><span class="pl-s1"></span> +<span class="pl-s1"><span class="pl-k">class</span> <span class="pl-en">FailureTest</span> <span class="pl-k">extends</span> <span class="pl-e">PHPUnit_Framework_TestCase</span></span> +<span class="pl-s1">{</span> +<span class="pl-s1"> <span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">testOne</span>() {</span> +<span class="pl-s1"> <span class="pl-smi">$this</span><span class="pl-k">-></span>assertTrue(<span class="pl-c1">FALSE</span>); <span class="pl-c">// Здесь будет ошибка</span></span> +<span class="pl-s1"> }</span> +<span class="pl-s1">}</span> +<span class="pl-s1"></span><span class="pl-pse"><span class="pl-s1">?</span>></span></pre></div> + +<p>РЇ положил его РІ файл <code>OpenServer/domains/tests.com/test.php</code>, соответственно открываем консоль, переходим РІ директорию СЃ помощью команды <code>cd domains/tests.com</code> Рё запускаем тест: <code>$ phpunit test.php</code>.</p> + +<h2 id="%D0%B8%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8F-%D1%81-phpstorm"> +<a id="user-content-Рнтеграция-СЃ-phpstorm" class="anchor" href="#%D0%98%D0%BD%D1%82%D0%B5%D0%B3%D1%80%D0%B0%D1%86%D0%B8%D1%8F-%D1%81-phpstorm" aria-hidden="true"><span class="octicon octicon-link"></span></a>Рнтеграция СЃ PHPStorm</h2> + +<p>Гайд установки РѕС‚ JetBrains можно почитать <a href="https://www.jetbrains.com/phpstorm/help/enabling-phpunit-support.html">здесь</a>. Краткое содержание:</p> + +<ul> +<li><p>Открываем проект, <em>Tools</em> | <em>Composer</em> | <em>Init Composer</em>, указываем путь <code>./modules/php/PHP-5.5/</code>, РІРѕ второй строке <code>./modules/php/PHP-5.5/composer.pchar</code>.</p></li> +<li><p>PHPUnit <strong>РЅРµ должен</strong> быть РїРѕРґ системой контроля версий. Проверьте наличие папки <code>~dev_rating/modules/unittest/vendor</code>, Рё если её нет, то переходим РІ <em>Tools</em> | <em>Composer</em> | <em>Add dependency</em>. Указываем <code>phpunit/phpunit</code> > <em>Install</em>.</p></li> +<li><p>Далее <em>Settings</em> | <em>PHP</em> | <em>PHPUnit</em> > <em>Local</em> > <em>Use custom autoloader.php</em>: <code>~dev_rating/modules/unittest/vendor/autoload.php</code>.</p></li> +</ul> + +<h4 id="%D0%BD%D0%B0%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-%D1%82%D0%B5%D1%81%D1%82%D0%BE%D0%B2"> +<a id="user-content-Написание-тестов" class="anchor" href="#%D0%9D%D0%B0%D0%BF%D0%B8%D1%81%D0%B0%D0%BD%D0%B8%D0%B5-%D1%82%D0%B5%D1%81%D1%82%D0%BE%D0%B2" aria-hidden="true"><span class="octicon octicon-link"></span></a>Написание тестов</h4> +</article></body></html> \ No newline at end of file diff --git a/doc/dev/testing/phpunit.md b/doc/dev/testing/phpunit.md new file mode 100644 index 0000000000000000000000000000000000000000..d39f03e9f138a6c602c748cf3ba05c229e40ad74 --- /dev/null +++ b/doc/dev/testing/phpunit.md @@ -0,0 +1,71 @@ +# PHPUnit + +[PHPUnit](https://phpunit.de/) — фреймворк для СЋРЅРёС‚-тестирования приложений. РЎ некоторого времени стал поддерживать Рё поведенческие тесты (BDD РїРѕРґС…РѕРґ). Нужно учитывать, что РёР·-Р·Р° MVC модели Kohana, нужно использовать _непрямой_ доступ Рє классам. Почитать РѕР± этом можно РІ разделе [Kohana integration](../index.html#kohana-integration). + +> Возможно здесь появится иформация Рѕ TDD/BDD Рё прочих штуках + +## Composer + +[Composer](https://getcomposer.org/) — менеджер зависимостей для приложений, написанных РЅР° PHP. Сильно облегчает задачу обновления всех подключенных Рє проекту библиотек Рё фрейморков. + +[Скачиваем](https://getcomposer.org/Composer-Setup.exe) себе РЅР° машину, РїСЂРё установке указываем путь `OpenServer/modules/php/PHP-5.5/php.exe` — далее РѕРЅ самостоятельно добавится РІ PATH так, что РІС‹ сможете вызвать его РёР· любой директории. + +Запускаем OpenServer, РІ меню выбираем: _Дополнительно_ | _Консоль_. Команда [`self-update`](https://getcomposer.org/doc/03-cli.md#self-update) РѕР±РЅРѕРІРёС‚ Composer РґРѕ последней версии. + +``` +$ php w:\modules\php\PHP-5.5\composer.phar self-update +``` + +## Установка РІРЅРµ проекта + +```bash +$ composer global require "phpunit/phpunit=4.5.*" +``` + +Composer подключится Рє репозиторию, скачает Рё установит пакеты. + +Открываем `OpenServer/modules/php/PHP-5.5/`, создаём файл `phpunit.bat` РІ РєРѕРґРёСЂРѕРІРєРµ CP886 (Cyrillic Windows), СЃРѕ следующим содержимым (`%username%` — РёРјСЏ пользователя): + +```bash +@ECHO OFF +php "C:/Users/%username%/AppData/Roaming/Composer/vendor/phpunit/phpunit/phpunit" %* +``` + +Пробуем работоспособность РІ консоли: `$ phpunit`. Р’ ответ выпадет СЃРїРёСЃРѕРє параметров Рё строка: + +``` +PHPUnit 4.5.0 by Sebastian Bergmann and contributors. +``` + + +#### Как запустить тесты + +Согласно [туториалу](https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html) пишем тест: + +```php +<?php +class FailureTest extends PHPUnit_Framework_TestCase +{ + public function testOne() { + $this->assertTrue(FALSE); // Здесь будет ошибка + } +} +?> +``` + +РЇ положил его РІ файл `OpenServer/domains/tests.com/test.php`, соответственно открываем консоль, переходим РІ директорию СЃ помощью команды `cd domains/tests.com` Рё запускаем тест: `$ phpunit test.php`. + + +## Рнтеграция СЃ PHPStorm + +Гайд установки РѕС‚ JetBrains можно почитать [здесь](https://www.jetbrains.com/phpstorm/help/enabling-phpunit-support.html). Краткое содержание: + +* Открываем проект, _Tools_ | _Composer_ | _Init Composer_, указываем путь `./modules/php/PHP-5.5/`, РІРѕ второй строке `./modules/php/PHP-5.5/composer.pchar`. + +* PHPUnit **РЅРµ должен** быть РїРѕРґ системой контроля версий. Проверьте наличие папки `~dev_rating/modules/unittest/vendor`, Рё если её нет, то переходим РІ _Tools_ | _Composer_ | _Add dependency_. Указываем `phpunit/phpunit` > _Install_. + +* Далее _Settings_ | _PHP_ | _PHPUnit_ > _Local_ > _Use custom autoloader.php_: `~dev_rating/modules/unittest/vendor/autoload.php`. + + +#### Написание тестов + diff --git a/~dev_rating/application/bootstrap.php b/~dev_rating/application/bootstrap.php index 192a23d4b76e2e6d0a44b178920eb36334d10bda..3553cbf3b97fd9191a1c741d3420e0000044361f 100644 --- a/~dev_rating/application/bootstrap.php +++ b/~dev_rating/application/bootstrap.php @@ -214,7 +214,7 @@ Route::set('student:subject', 'subject/<id>', array('id' => '[0-9]+')) // Внутренние вызовы! Route::set('student:index', 'student/index') - ->filter(function($route, $params, $request){ + ->filter(function($route, $params, Request $request){ if($request->is_initial()) return FALSE; }) @@ -225,7 +225,7 @@ Route::set('student:index', 'student/index') )); Route::set('student:settings', 'student/settings') - ->filter(function($route, $params, $request){ + ->filter(function($route, $params, Request $request){ if($request->is_initial()) return FALSE; }) @@ -236,7 +236,7 @@ Route::set('student:settings', 'student/settings') )); Route::set('student:profile', 'student/profile') - ->filter(function($route, $params, $request){ + ->filter(function($route, $params, Request $request){ if($request->is_initial()) return FALSE; }) @@ -261,28 +261,28 @@ Route::set('teacher:map:discipline', 'discipline/settings/<id>', array('id' => ' 'controller' => 'discipline', 'action' => 'EditSettings' )); - + Route::set('teacher:map:structure', 'discipline/structure/<id>', array('id' => '[0-9]+')) ->defaults(array( 'directory' => 'teacher', 'controller' => 'Discipline', 'action' => 'EditStructure' )); - + Route::set('teacher:map:groups', 'discipline/groups/<id>', array('id' => '[0-9]+')) ->defaults(array( 'directory' => 'teacher', 'controller' => 'Discipline', 'action' => 'EditGroups' )); - + Route::set('teacher:map:students', 'discipline/students/<id>', array('id' => '[0-9]+')) ->defaults(array( 'directory' => 'teacher', 'controller' => 'discipline', 'action' => 'EditStudents' )); - + Route::set('teacher:map:teachers', 'discipline/teachers/<id>', array('id' => '[0-9]+')) ->defaults(array( 'directory' => 'teacher', @@ -305,7 +305,7 @@ Route::set('teacher:exam', 'exam/<id>', array('id' => '[0-9]+')) // Внутренние вызовы! Route::set('teacher:index', 'teacher/index') - ->filter(function($route, $params, $request){ + ->filter(function($route, $params, Request $request){ if($request->is_initial()) return FALSE; }) @@ -314,9 +314,9 @@ Route::set('teacher:index', 'teacher/index') 'controller' => 'index', 'action' => 'index' )); - + Route::set('teacher:settings', 'teacher/settings') - ->filter(function($route, $params, $request){ + ->filter(function($route, $params, Request $request){ if($request->is_initial()) return FALSE; }) @@ -327,7 +327,7 @@ Route::set('teacher:settings', 'teacher/settings') )); Route::set('teacher:profile', 'teacher/profile(/<action>(/<id>))', array('action' => '(student)', 'id' => '[0-9]+')) - ->filter(function($route, $params, $request){ + ->filter(function($route, $params, Request $request){ if($request->is_initial()) return FALSE; }) @@ -345,16 +345,18 @@ Route::set('admin:common', 'admin(/<controller>(/<action>(/<param1>(:<param2>))) 'action' => 'index' )); -/* --------------- Деканат (Ведомости) ---------------- */ -Route::set('dean_office:index', 'dean_office') +/* --------------- Деканат ---------------- */ +Route::set('dean_office:index', 'dean_office(/<controller>(/<action>(/<param1>(:<param2>))))') ->defaults(array( 'directory' => 'DeanOffice', 'controller' => 'index', 'action' => 'index' )); - -/* --------------- Java session provider -------------- */ -Route::set('javaSessionProvider', 'java_authentication') - ->defaults(array( - 'controller' => 'JavaAuthentication', - 'action' => 'authentication',)); \ No newline at end of file + +# http://grade.mmcs.sfedu.ru/students/list +Route::set('dean_office:academic_leaves', 'students/list') + ->defaults([ + 'directory' => 'DeanOffice', + 'controller' => 'Students', + 'action' => 'list' + ]); \ No newline at end of file diff --git a/~dev_rating/application/classes/Controller/Admin/Accounts.php b/~dev_rating/application/classes/Controller/Admin/Accounts.php index 857be7fcef7df6902bc51f60ae3bd4481e632d1c..1c100dedde4aca6f74ab375bff63b1697f2cf043 100644 --- a/~dev_rating/application/classes/Controller/Admin/Accounts.php +++ b/~dev_rating/application/classes/Controller/Admin/Accounts.php @@ -1,44 +1,24 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Admin_Accounts extends Controller_UserEnvi { +class Controller_Admin_Accounts extends Controller_UserEnvironment { public function action_index() { $twig = Twig::factory('admin/accounts/index'); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } - public function action_getCodes() + public function action_getActivationCodes() { - $model = new Model_Admin_Students(); + $model = new Model_Students(); Cookie::set('fD', 'true'); $twig = Twig::factory('admin/accounts/codes'); - $twig->Faculties = DataArray::factory('Faculties')->common()->asArray(); - $twig->Grades = $this->getGrades(); - $twig->User = $this->UserInfo; + $twig->Faculties = Model_Faculties::toArray(); + $twig->Grades = Model_Grades::toStructuredArray(); + $twig->User = $this->user; $this->response->body($twig); - } - - - public function getGrades() { - $grades = DataArray::factory('Grades')->common()->asArray(); - $gradesHandled = array(); $i = $j = 0; $degree = 'null'; - $degrees = array('bachelor' => 'Бакалавр', 'specialist' => 'Специалист', 'master' => 'Магистр'); - foreach($grades as $row) - { - if($degree != $row['Degree']) - { - $degree = $row['Degree'] ; - $i++; $j = 0; - } - $j++; - $gradesHandled[$i]['Title'] = $degrees[$row['Degree']]; - $gradesHandled[$i]['Grades'][$j]['ID'] = $row['ID']; - $gradesHandled[$i]['Grades'][$j]['Num'] = $row['Num']; - } - return $gradesHandled; - } + } } \ No newline at end of file diff --git a/~dev_rating/application/classes/Controller/Admin/Departaments.php b/~dev_rating/application/classes/Controller/Admin/Departments.php similarity index 50% rename from ~dev_rating/application/classes/Controller/Admin/Departaments.php rename to ~dev_rating/application/classes/Controller/Admin/Departments.php index 98d40efa7094073dda02ef7a90b657b564c6ad59..20c6327862c278cca01cbc1da478a36616ad9ecf 100644 --- a/~dev_rating/application/classes/Controller/Admin/Departaments.php +++ b/~dev_rating/application/classes/Controller/Admin/Departments.php @@ -1,20 +1,20 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Admin_Departaments extends Controller_UserEnvi { +class Controller_Admin_Departments extends Controller_UserEnvironment { public function action_index() { - $twig = Twig::factory('admin/departaments/index'); + $twig = Twig::factory('admin/departments/index'); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } public function action_upload() { - $twig = Twig::factory('admin/departaments/upload'); + $twig = Twig::factory('admin/departments/upload'); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } } diff --git a/~dev_rating/application/classes/Controller/Admin/Disciplines.php b/~dev_rating/application/classes/Controller/Admin/Disciplines.php index 388e85a4d978501d6a224f545fe2b68b2114f064..add35ba6122cafda1aceecbdfcc3beeeefad027c 100644 --- a/~dev_rating/application/classes/Controller/Admin/Disciplines.php +++ b/~dev_rating/application/classes/Controller/Admin/Disciplines.php @@ -1,12 +1,12 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Admin_Disciplines extends Controller_UserEnvi { +class Controller_Admin_Disciplines extends Controller_UserEnvironment { public function action_index() { $twig = Twig::factory('admin/disciplines/index'); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } } diff --git a/~dev_rating/application/classes/Controller/Admin/StudyGroups.php b/~dev_rating/application/classes/Controller/Admin/Groups.php similarity index 51% rename from ~dev_rating/application/classes/Controller/Admin/StudyGroups.php rename to ~dev_rating/application/classes/Controller/Admin/Groups.php index abbc11ef0917fd15ccf0f5423da93279a0ddab1d..b18e6573ae0f512fb92276a7ce87c9e4114f6a70 100644 --- a/~dev_rating/application/classes/Controller/Admin/StudyGroups.php +++ b/~dev_rating/application/classes/Controller/Admin/Groups.php @@ -1,12 +1,12 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Admin_StudyGroups extends Controller_UserEnvi { +class Controller_Admin_Groups extends Controller_UserEnvironment { public function action_index() { - $twig = Twig::factory('admin/studyGroups/index'); + $twig = Twig::factory('admin/groups/index'); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } } diff --git a/~dev_rating/application/classes/Controller/Admin/Index.php b/~dev_rating/application/classes/Controller/Admin/Index.php index 737552bfba606634ccd0ef3a941590ee6e6e414f..7b2bd6b3bad027297cc172e66e937141a5e36fb3 100644 --- a/~dev_rating/application/classes/Controller/Admin/Index.php +++ b/~dev_rating/application/classes/Controller/Admin/Index.php @@ -1,12 +1,12 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Admin_Index extends Controller_UserEnvi { +class Controller_Admin_Index extends Controller_UserEnvironment { public function action_index() { $twig = Twig::factory('admin/index'); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } } diff --git a/~dev_rating/application/classes/Controller/Admin/Profile.php b/~dev_rating/application/classes/Controller/Admin/Profile.php index b391b5da9feae3ca97522a7cc6a43ac8558dce65..2a1c3f758214e6863cba7b6e422957f3de3fbae7 100644 --- a/~dev_rating/application/classes/Controller/Admin/Profile.php +++ b/~dev_rating/application/classes/Controller/Admin/Profile.php @@ -1,18 +1,17 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Admin_Profile extends Controller_UserEnvi { +class Controller_Admin_Profile extends Controller_UserEnvironment { public function action_student() { $twig = Twig::factory('admin/students/profile'); $id = $this->request->param('param1'); $model = new Model_Account; - $degrees = array('bachelor' => 'Бакалавриат', 'specialist' => 'Специалитет', 'master' => 'Магистратура'); - $profile = $model->getPersonalInfo($id)->offsetGet(0); - $profile['Degree'] = $degrees[$profile['Degree']]; - $twig->Account = $model->getAccountInfo($id)->offsetGet(0); + $profile = $model->getPersonalInfo($id); + $profile['Degree'] = Model_Grades::getDegreeTitle($profile['Degree']); + $twig->Account = $model->getAccountInfo($id); $twig->Profile = $profile; - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } @@ -21,9 +20,9 @@ class Controller_Admin_Profile extends Controller_UserEnvi { $twig = Twig::factory('admin/teachers/profile'); $id = $this->request->param('param1'); $model = new Model_Account; - $twig->Account = $model->getAccountInfo($id)->offsetGet(0); - $twig->Profile = $model->getPersonalInfo($id)->offsetGet(0); - $twig->User = $this->UserInfo; + $twig->Account = $model->getAccountInfo($id); + $twig->Profile = $model->getPersonalInfo($id); + $twig->User = $this->user; $this->response->body($twig); } } diff --git a/~dev_rating/application/classes/Controller/Admin/Students.php b/~dev_rating/application/classes/Controller/Admin/Students.php index cc19ec957184056ae39879a5aca99ed86eaeca25..ecbd1cb3ed6ae8955914e3e94d346015a7708f9d 100644 --- a/~dev_rating/application/classes/Controller/Admin/Students.php +++ b/~dev_rating/application/classes/Controller/Admin/Students.php @@ -1,23 +1,23 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Admin_Students extends Controller_UserEnvi { +class Controller_Admin_Students extends Controller_UserEnvironment { public function action_index() { // VIEW $twig = Twig::factory('admin/students/index'); - $twig->Faculties = DataArray::factory('Faculties')->common()->asArray(); - $twig->Grades = DataArray::factory('Grades')->structured()->asArray(); - $twig->User = $this->UserInfo; + $twig->Faculties = Model_Faculties::toArray(); + $twig->Grades = Model_Grades::toStructuredArray(); + $twig->User = $this->user; $this->response->body($twig); } public function action_add() { $twig = Twig::factory('admin/students/add'); - $twig->Faculties = DataArray::factory('Faculties')->common()->asArray(); - $twig->Grades = DataArray::factory('Grades')->structured()->asArray(); - $twig->User = $this->UserInfo; + $twig->Faculties = Model_Faculties::toArray(); + $twig->Grades = Model_Grades::toStructuredArray(); + $twig->User = $this->user; $this->response->body($twig); } @@ -29,16 +29,16 @@ class Controller_Admin_Students extends Controller_UserEnvi { } // VIEW $twig = Twig::factory('admin/students/upload'); - $twig->Faculties = DataArray::factory('Faculties')->common()->asArray(); + $twig->Faculties = Model_Faculties::toArray(); $twig->UploadingResult = $result; - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } public function action_edit() { $twig = Twig::factory('admin/students/edit'); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } diff --git a/~dev_rating/application/classes/Controller/Admin/Subjects.php b/~dev_rating/application/classes/Controller/Admin/Subjects.php index da5499ce8c9616a53dfa9d517f78c4bd6fa51040..b14d43a2df4316944f35437c6a6c709a127aa106 100644 --- a/~dev_rating/application/classes/Controller/Admin/Subjects.php +++ b/~dev_rating/application/classes/Controller/Admin/Subjects.php @@ -1,6 +1,6 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Admin_Subjects extends Controller_UserEnvi { +class Controller_Admin_Subjects extends Controller_UserEnvironment { @@ -13,9 +13,9 @@ class Controller_Admin_Subjects extends Controller_UserEnvi { } // VIEW $twig = Twig::factory('admin/subjects/upload'); - $twig->Faculties = DataArray::factory('Faculties')->common()->asArray(); + $twig->Faculties = Model_Faculties::toArray(); $twig->UploadingResult = $result; - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } diff --git a/~dev_rating/application/classes/Controller/Admin/Teachers.php b/~dev_rating/application/classes/Controller/Admin/Teachers.php index e30c726315608f76ee0f05808a5822f44c1e3dba..cab950ed5e593126e092b3116bd905d56ef17a65 100644 --- a/~dev_rating/application/classes/Controller/Admin/Teachers.php +++ b/~dev_rating/application/classes/Controller/Admin/Teachers.php @@ -1,13 +1,13 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Admin_Teachers extends Controller_UserEnvi { +class Controller_Admin_Teachers extends Controller_UserEnvironment { public function action_index() { // VIEW $twig = Twig::factory('admin/teachers/index'); - $twig->Faculties = DataArray::factory('Faculties')->common()->asArray(); - $twig->User = $this->UserInfo; + $twig->Faculties = Model_Faculties::toArray(); + $twig->User = $this->user; $this->response->body($twig); } @@ -15,8 +15,8 @@ class Controller_Admin_Teachers extends Controller_UserEnvi { { $twig = Twig::factory('admin/teachers/add'); $twig->JobPositions = $this->getJobPositions(); - $twig->Faculties = DataArray::factory('Faculties')->common()->asArray(); - $twig->User = $this->UserInfo; + $twig->Faculties = Model_Faculties::toArray(); + $twig->User = $this->user; $this->response->body($twig); } @@ -28,9 +28,9 @@ class Controller_Admin_Teachers extends Controller_UserEnvi { } // VIEW $twig = Twig::factory('admin/teachers/upload'); - $twig->Faculties = DataArray::factory('Faculties')->common()->asArray(); + $twig->Faculties = Model_Faculties::toArray(); $twig->UploadingResult = $result; - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } @@ -39,11 +39,10 @@ class Controller_Admin_Teachers extends Controller_UserEnvi { return FileParser::TeachersList($filename); } - + // todo: move to teachers model, there's a duplicate at profile.php public function getJobPositions() { - $model = new Model_Admin_Teachers; - $jobPositions = $model->getJobPositions(); + $jobPositions = Model_Teachers::getJobPositions(); $jobPositionsHandled = array(); $i = 0; foreach($jobPositions as $row) { diff --git a/~dev_rating/application/classes/Controller/Authentication.php b/~dev_rating/application/classes/Controller/Authentication.php index 2ea09fa4cca18682cc1fc46b5c76694b7b130a14..a1687a4cf8e446b777de266c308b716df5993d40 100644 --- a/~dev_rating/application/classes/Controller/Authentication.php +++ b/~dev_rating/application/classes/Controller/Authentication.php @@ -7,7 +7,7 @@ class Controller_Authentication extends Controller { if(UTF8::strcasecmp($this->request->action(), 'logout')) { $user = User::instance(); if($user->isSignedIn()) { - $request = $user->offsetGet('Type').'/index'; + $request = $user->Type . '/index'; $page = Request::factory($request)->execute(); $this->response->body($page); } @@ -57,11 +57,12 @@ class Controller_Authentication extends Controller { { $token = $this->request->param('token'); if (!Account::instance()->checkToken($token)) { - throw HTTP_Exception::factory(403, - 'Данная ссылка для восстановления пароля более РЅРµ действительна!<br>Либо истекло время действия ссылки, либо РѕРЅР° уже была использована.'); + $message = "Данная ссылка для восстановления пароля более РЅРµ действительна!\n" . + "Либо истекло время действия ссылки, либо РѕРЅР° уже была использована."; + throw HTTP_Exception::factory(403, $message); } - if(!User::instance()->isSignedIn()) - { + + if (!User::instance()->isSignedIn()) { $twig = Twig::factory('sign/changepass'); $twig->Updates = self::getUpdates(); $twig->Token = $token; diff --git a/~dev_rating/application/classes/Controller/DeanOffice/Index.php b/~dev_rating/application/classes/Controller/DeanOffice/Index.php index 10cece405c2630311267842c0ea313840594a32c..faa8301d8d8b278ced3513bdfa9508d9b1b4e4e4 100644 --- a/~dev_rating/application/classes/Controller/DeanOffice/Index.php +++ b/~dev_rating/application/classes/Controller/DeanOffice/Index.php @@ -1,6 +1,6 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_DeanOffice_Index extends Controller_UserEnvi { +class Controller_DeanOffice_Index extends Controller_UserEnvironment { public function before() { Cookie::set('fD', 'true'); // Ставим РєСѓРє fD, чтоб иметь возможность скачать файл @@ -11,11 +11,11 @@ class Controller_DeanOffice_Index extends Controller_UserEnvi { public function action_index() { $twig = Twig::factory('dean_office/index'); - $model = new Model_Teacher_Map; + $model = new Model_Map; - $twig->GradesList = DataArray::factory('Grades')->common()->asArray(); + $twig->GradesList = Model_Grades::toArray(); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } } \ No newline at end of file diff --git a/~dev_rating/application/classes/Controller/DeanOffice/Students.php b/~dev_rating/application/classes/Controller/DeanOffice/Students.php new file mode 100644 index 0000000000000000000000000000000000000000..f49edd24ece3564097cba80e1eea7457de0c8703 --- /dev/null +++ b/~dev_rating/application/classes/Controller/DeanOffice/Students.php @@ -0,0 +1,12 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Controller_DeanOffice_Students extends Controller_UserEnvironment +{ + public function action_index() { + $twig = Twig::factory('dean_office/students/index'); + $twig->Faculties = Model_Faculties::toArray(); + $twig->Grades = Model_Grades::toStructuredArray(); + $twig->User = $this->user; + $this->response->body($twig); + } +} diff --git a/~dev_rating/application/classes/Controller/Handler.php b/~dev_rating/application/classes/Controller/Handler.php index d36405de53cac067afc766ba687fe10ac083344d..53e69a60594f8e80d3e2509d26c90a94f6073676 100644 --- a/~dev_rating/application/classes/Controller/Handler.php +++ b/~dev_rating/application/classes/Controller/Handler.php @@ -1,7 +1,17 @@ <?php defined('SYSPATH') or die('No direct script access.'); class Controller_Handler extends Controller { - protected $user, $post, $get, $model; + /** @var Validation */ + protected $post; + + /** @var Validation */ + protected $get; + + /** @var User */ + protected $user; + + protected $model; + private $access; const ACCESS_USER = 0; @@ -11,7 +21,7 @@ class Controller_Handler extends Controller { public function before() { $isDownload = Cookie::get('fD'); - $user = User::instance(); + $this->user = User::instance(); // Если Сѓ нас запрос идет РЅРµ РёР· AJAX if(!$this->request->is_ajax() && !$isDownload) { @@ -24,15 +34,14 @@ class Controller_Handler extends Controller { $this->get = Validation::factory(Arr::map('trim', $_GET)); // Если авторизован, получаем данные аккаунта - if($user->isSignedIn()) - { - $this->user = $user->getInfoAsArray(); - } + //if ($this->user->isSignedIn()) { + // $this->user = $this->user->toArray(); + //} // Получаем РёРјСЏ маршрута $route = Route::name($this->request->route()); $route .= ':'.$this->request->controller(); - $userMark = (int)$user->offsetGet('RoleMark'); + $userMark = (int)$this->user->RoleMark; if ($userMark == 0) { $userMark = (int)1; } diff --git a/~dev_rating/application/classes/Controller/Handler/AdmAccounts.php b/~dev_rating/application/classes/Controller/Handler/AdmAccounts.php index 9bbae23029cb6e380e78f90b38a9e9385f2be18b..25f03a6d2482348a3000bf5209c4461cf5f141a9 100644 --- a/~dev_rating/application/classes/Controller/Handler/AdmAccounts.php +++ b/~dev_rating/application/classes/Controller/Handler/AdmAccounts.php @@ -1,34 +1,33 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Handler_AdmAccounts extends Controller_Handler { - +class Controller_Handler_AdmAccounts extends Controller_Handler +{ public function before() { - $this->model = new Model_Admin_Accounts(); $this->setAccessLevel(self::ACCESS_USER); parent::before(); } public function action_getActivationForTeachers() { - $facultyID = $this->post->offsetGet('facultyID'); + $facultyID = $this->post['facultyID']; $departmentsHandled = array(); $i = 0; - $departments = $this->model->getDepartments($facultyID); + $departments = Model_Departments::ofFaculty($facultyID); foreach ($departments as $department) { $i++; $j = 0; - $accounts = $this->model->getTeachersByDepartment($department['ID']); + $accounts = Model_Teachers::getTeachersByDepartment($department['ID']); if ($accounts == null) continue; $departmentsHandled[$i]['Name'] = $department['Name']; foreach ($accounts as $row) { - $accInfo = $this->model->getAccountInfo($row['AccountID']); + $accInfo = Model_Accounts::getAccountInfo($row['AccountID']); if($code = $accInfo->get('Code')) { $j++; - $departmentsHandled[$i]['People'][$j]['LastName'] = $row['Last']; - $departmentsHandled[$i]['People'][$j]['FirstName'] = $row['First']; - $departmentsHandled[$i]['People'][$j]['SecondName'] = $row['Second']; + $departmentsHandled[$i]['People'][$j]['LastName'] = $row['LastName']; + $departmentsHandled[$i]['People'][$j]['FirstName'] = $row['FirstName']; + $departmentsHandled[$i]['People'][$j]['SecondName'] = $row['SecondName']; $departmentsHandled[$i]['People'][$j]['ActivationCode'] = $code; } } @@ -57,20 +56,20 @@ class Controller_Handler_AdmAccounts extends Controller_Handler { $this->response->body($File); } else { - throw HTTP_Exception::factory(404, 'No data found'); + throw HTTP_Exception::factory(400, 'No data found'); } } public function action_getActivationForStudents() { - $facultyID = $this->post->offsetGet('facultyID'); - $gradeID = $this->post->offsetGet('gradeID'); + $facultyID = $this->post['facultyID']; + $gradeID = $this->post['gradeID']; $groupsHandled = array(); $i = 0; - $studyGroups = $this->model->getStudyGroups($gradeID, $facultyID); - foreach ($studyGroups as $group) + $groups = Model_Students::getGroups($gradeID, $facultyID); + foreach ($groups as $group) { $i++; $j = 0; - $accounts = $this->model->getStudents($group['ID']); + $accounts = Model_Students::ofGroup($group['ID']); if (empty($accounts)) continue; $groupsHandled[$i]['Grade'] = $gradeID; @@ -78,7 +77,7 @@ class Controller_Handler_AdmAccounts extends Controller_Handler { $groupsHandled[$i]['Spec'] = $group['SpecName']; foreach ($accounts as $row) { - $accInfo = $this->model->getAccountInfo($row['AccountID']); + $accInfo = Model_Accounts::getAccountInfo($row['AccountID']); if($code = $accInfo->get('Code')) { $j++; diff --git a/~dev_rating/application/classes/Controller/Handler/AdmStudents.php b/~dev_rating/application/classes/Controller/Handler/AdmStudents.php index f32b016afa9cdfdca7100bc5c201f30163298ae5..d7ab8e06b6dbbfc7635ecf39e7e15b6fe47d695f 100644 --- a/~dev_rating/application/classes/Controller/Handler/AdmStudents.php +++ b/~dev_rating/application/classes/Controller/Handler/AdmStudents.php @@ -1,6 +1,6 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class SortingOptions { //extends SplEnum { +abstract class SortingOptions { //extends SplEnum { // todo: think about usage & file system //const __default = self::Name; const Name = 0; @@ -8,10 +8,9 @@ class SortingOptions { //extends SplEnum { const Group = 2; } -class Controller_Handler_AdmStudents extends Controller_Handler { - +class Controller_Handler_AdmStudents extends Controller_Handler +{ public function before() { - $this->model = new Model_Admin_Students(); $this->setAccessLevel(self::ACCESS_USER); parent::before(); } @@ -32,17 +31,17 @@ class Controller_Handler_AdmStudents extends Controller_Handler { ->rule('groupNum', 'digit') ->rule('facultyID', 'not_empty') ->rule('facultyID', 'digit'); - if($this->post->offsetGet('gradeNum') == 0) + if($this->post['gradeNum'] == 0) { $this->post->error('gradeNum', 'not_empty'); $response['success'] = false; } - if($this->post->offsetGet('groupNum') == 0) + if($this->post['groupNum'] == 0) { $this->post->error('groupNum', 'not_empty'); $response['success'] = false; } - if($this->post->offsetGet('facultyID') == 0) + if($this->post['facultyID'] == 0) { $this->post->error('facultyID', 'not_empty'); $response['success'] = false; @@ -50,12 +49,12 @@ class Controller_Handler_AdmStudents extends Controller_Handler { if($this->post->check()) { $code = $this->_createStudent( - $this->post->offsetGet('lastName'), - $this->post->offsetGet('firstName'), - $this->post->offsetGet('secondName'), - $this->post->offsetGet('gradeNum'), - $this->post->offsetGet('groupNum'), - $this->post->offsetGet('facultyID')); + $this->post['lastName'], + $this->post['firstName'], + $this->post['secondName'], + $this->post['gradeNum'], + $this->post['groupNum'], + $this->post['facultyID']); if($code != -1) { $response['success'] = true; @@ -73,27 +72,21 @@ class Controller_Handler_AdmStudents extends Controller_Handler { $this->response->body(json_encode($response)); } - public function action_uploadStudentFile() - { - $this->model->getStudentFile(); - - } - protected function _createStudent($lastName, $firstName, $secondName, $gradeID, $groupNum, $facultyID) { $activationCode = Account::instance()->createStudent($lastName, $firstName, $secondName, $gradeID, $groupNum, $facultyID); return $activationCode; } - public function action_getStudyGroups() + public function action_getGroups() { - $facultyID = $this->post->offsetGet('facultyID'); - $gradeID = $this->post->offsetGet('gradeNum'); + $facultyID = $this->post['facultyID']; + $gradeID = $this->post['gradeNum']; if(($facultyID && $gradeID) != 0) { - $studyGroups = $this->model->getStudyGroups($gradeID, $facultyID); - $studyGroupsHandled = array(); $i = $j = $id = 0; - foreach($studyGroups as $row) + $groups = Model_Students::getGroups($gradeID, $facultyID); + $groupsHandled = array(); $i = $j = $id = 0; + foreach($groups as $row) { if($id != $row['SpecID']) { @@ -102,75 +95,79 @@ class Controller_Handler_AdmStudents extends Controller_Handler { } $j++; if (is_null($row['SpecName'])) - $studyGroupsHandled[$i]['SpecName'] = "<без специализации>"; + $groupsHandled[$i]['SpecName'] = "<без специализации>"; else - $studyGroupsHandled[$i]['SpecName'] = $row['SpecName']; - $studyGroupsHandled[$i]['Groups'][$j]['ID'] = $row['ID']; - $studyGroupsHandled[$i]['Groups'][$j]['Num'] = $row['GroupNum']; + $groupsHandled[$i]['SpecName'] = $row['SpecName']; + $groupsHandled[$i]['Groups'][$j]['ID'] = $row['ID']; + $groupsHandled[$i]['Groups'][$j]['Num'] = $row['GroupNum']; } - $this->response->body(json_encode($studyGroupsHandled)); + $this->response->body(json_encode($groupsHandled)); } } public function action_getStudentsList($option = SortingOptions::Name) { + $from = isset($this->get['dean']) ? 'dean_office' : 'admin'; + $twig = Twig::factory($from . '/students/handler/listOutput'); + $success = false; - $facultyID = $this->post->offsetGet('facultyID'); - $gradeID = $this->post->offsetGet('gradeID'); - $groupID = $this->post->offsetGet('groupID'); + $facultyID = $this->post['facultyID']; + $gradeID = $this->post['gradeID']; + $groupID = $this->post['groupID']; - $this->post-> rule('FacultyID', 'not_empty') + $this->post-> rule('facultyID', 'not_empty') -> rule('facultyID', 'digit') - -> rule('GradeID', 'not_empty') + -> rule('gradeID', 'not_empty') -> rule('gradeID', 'digit') - -> rule('GroupID', 'not_empty') + -> rule('groupID', 'not_empty') -> rule('groupID', 'digit'); + if($this->post->check()) { -// $result = $this->commonModel->GetStudentsList($this->user['UserID'], $facultyID , $gradeID, $groupID); - $result = DataArray::factory('Students')->byFaculty($facultyID , $gradeID, $groupID)->asArray(); + $result = Model_Students::byFaculty($facultyID , $gradeID, $groupID); if (!empty($result)) { + $twig->List = $result; $success = true; } } //$this->response->body(json_encode($data)); - $twig = Twig::factory('admin/students/handler/listOutput'); - $twig->List = $result; $twig->Success = $success; $this->response->body($twig); } - public function action_getStudentsByGrade() - { - $gradeID = $this->post->offsetGet('gradeID'); - if($gradeID != 0) - { - $twig = Twig::factory('admin/students/handler/listOutput'); - $twig->List = DataArray::factory('Students')->byGrade($gradeID)->asArray(); - $this->response->body($twig); - } - } - public function action_getStudentsByStudyGroup() { - $groupID = $this->post->offsetGet('studyGroupID'); + $groupID = $this->post['studyGroupID']; if($groupID != 0) { $twig = Twig::factory('admin/students/handler/listOutput'); - $twig->List = DataArray::factory('Students')->byStudyGroup($groupID)->asArray(); + $twig->List = Model_Students::byStudyGroup($groupID); $this->response->body($twig); } } - + + /** @deprecated */ public function action_getStudentsByFaculty() { - $facultyID = $this->post->offsetGet('facultyID'); + $facultyID = $this->post['facultyID']; if($facultyID != 0) { $twig = Twig::factory('admin/students/handler/listOutput'); - $twig->List = DataArray::factory('Students')->byFaculty($facultyID)->asArray(); + // (Grade, Group) = (0,0), to ignore (search all students) + $twig->List = Model_Students::byFaculty($facultyID, 0, 0); $this->response->body($twig); } } - + + public function action_giveLeave() { + $id = (int) $this->get['id']; + Model_Student::load($id) + ->toAcademicLeave(); + } + + public function action_stopLeave() { + $id = (int) $this->get['id']; + //Model_Student::load($id) + // ->attach() + } } \ No newline at end of file diff --git a/~dev_rating/application/classes/Controller/Handler/AdmTeachers.php b/~dev_rating/application/classes/Controller/Handler/AdmTeachers.php index 67454f784a41564b96d835354179c71ccd901564..42663ffad3e054b1e1ef737bb31ddd2c76989c11 100644 --- a/~dev_rating/application/classes/Controller/Handler/AdmTeachers.php +++ b/~dev_rating/application/classes/Controller/Handler/AdmTeachers.php @@ -3,7 +3,7 @@ class Controller_Handler_AdmTeachers extends Controller_Handler { public function before() { - $this->model = new Model_Admin_Teachers; + $this->model = new Model_Teachers(); $this->setAccessLevel(self::ACCESS_USER); parent::before(); } @@ -22,12 +22,12 @@ class Controller_Handler_AdmTeachers extends Controller_Handler { ->rule('jobPositionID', 'digit') ->rule('departmentID', 'not_empty') ->rule('departmentID', 'digit'); - if($this->post->offsetGet('jobPositionID') == 0) + if($this->post['jobPositionID'] == 0) { $this->post->error('jobPositionID', 'not_empty'); $response['success'] = false; } - if($this->post->offsetGet('departmentID') == 0) + if($this->post['departmentID'] == 0) { $this->post->error('departmentID', 'not_empty'); $response['success'] = false; @@ -35,11 +35,11 @@ class Controller_Handler_AdmTeachers extends Controller_Handler { if($this->post->check()) { $code = $this->_createTeacher( - $this->post->offsetGet('lastName'), - $this->post->offsetGet('firstName'), - $this->post->offsetGet('secondName'), - $this->post->offsetGet('jobPositionID'), - $this->post->offsetGet('departmentID')); + $this->post['lastName'], + $this->post['firstName'], + $this->post['secondName'], + $this->post['jobPositionID'], + $this->post['departmentID']); if($code != -1) { $response['success'] = true; @@ -66,20 +66,20 @@ class Controller_Handler_AdmTeachers extends Controller_Handler { public function action_getTeachersList() { - $departmentID = $this->post->offsetGet('departmentID'); - $facultyID = $this->post->offsetGet('facultyID'); + $departmentID = $this->post['departmentID']; + $facultyID = $this->post['facultyID']; if($departmentID != 0) - $teachers = DataArray::factory('Teachers')->byDepartment($departmentID)->asArray(); + $teachers = Model_Teachers::byDepartment($departmentID); elseif($facultyID != 0) - $teachers = DataArray::factory('Teachers')->byFaculty($facultyID)->asArray(); + $teachers = Model_Teachers::byFaculty($facultyID); $twig = Twig::factory('admin/teachers/handler/listOutput'); $twig->List = $teachers; $this->response->body($twig); } - public function action_getDepartmentsList() - { - $facultyID = $this->post->offsetGet('facultyID'); - $this->response->body(DataArray::factory('Departments')->byFaculty($facultyID)->asJSON()); + public function action_getDepartmentsList() { + $facultyID = $this->post['facultyID']; + $departments = Model_Departments::byFaculty($facultyID); + $this->response->body(json_encode($departments)); } } \ No newline at end of file diff --git a/~dev_rating/application/classes/Controller/Handler/ErrMessages.php b/~dev_rating/application/classes/Controller/Handler/ErrMessages.php index 873dae7bcd4b90dd93fe28f9873392d08bd69d6e..891737de1f52d181dadf749a69654c500860a801 100644 --- a/~dev_rating/application/classes/Controller/Handler/ErrMessages.php +++ b/~dev_rating/application/classes/Controller/Handler/ErrMessages.php @@ -1,57 +1,64 @@ <?php defined('SYSPATH') or die('No direct script access.'); class Controller_Handler_ErrMessages extends Controller_Handler { - + + /** @var Model_errMessages */ + protected $model; + public function before() { $this->model = new Model_errMessages; $this->setAccessLevel(self::ACCESS_USER); parent::before(); } - + public function action_getRequests() { - $data = $this->model->getRequests($this->user['AccID']); + $data = $this->model->getRequests($this->user->ID); $i =0; $res = array(); - foreach ($data as $row) + foreach ($data as $row) { $res[$i] = $row; ++$i; - } - $res['num'] = --$i; + } + $res['num'] = --$i; - $this->response->body(json_encode($res)); + $this->response->body(json_encode($res)); } public function action_createRequest() { $title = $_POST['title']; $text = $_POST['text']; - $result = $this->model->newRequest($this->user['ID'], $title, $text); - - $to = "it.lab.mmcs@gmail.com"; - $subject = "Request ".$result[0]['Num'].": rating system report"; - - $message = "Faculty: ".$this->user['FacultyName']."\n"; - $message .= "Type: ".$this->user['Type']."\n"; - if ($this->user['Type'] === "teacher") { - $message .= "Department: ".$this->user['DepName']."\n"; - } else if ($this->user['Type'] === "student") { - $message .= "Degree: ".$this->user['Degree']; - $message .= " Grade: ".$this->user['GradeNum']; - $message .= " Group: ".$this->user['GroupNum']."\n"; + $result = $this->model->newRequest($this->user->ID, $title, $text); + + // todo: use twig + $to = 'it.lab.mmcs@gmail.com'; + $subject = "Request {$result[0]['Num']}: rating system report"; + + $message = "Faculty: {$this->user->FacultyName}\n"; + $message .= "Type: {$this->user->Type}\n"; + + if ($this->user->Type === "teacher") { + $message .= "Department: {$this->user['DepName']}\n"; + } elseif ($this->user->Type === 'student') { + $message .= sprintf("Degree: %s Grade: %s Group: %s\n", + $this->user['Degree'], $this->user['GradeNum'], $this->user['GroupNum']); } - $message .= "Sender: ".$this->user['Last'].' '.$this->user['First'].' '.$this->user['Second']."\n\n"; - $message .= "Title: ".$title."\n"; - $message .= "Message: ".$text; - $headers = "From: RatingSystem@no-reply.mmcs.sfedu.ru\n"; - $headers .= "Reply-To: ".$this->user['EMail']; + $message .= sprintf("Sender: %s %s %s\n\n", + $this->user->LastName, $this->user->FirstName, $this->user->SecondName); + + $message .= "Title: " . $title . "\n"; + $message .= "Message: " . $text; + + $headers = "From: RatingSystem@no-reply.mmcs.sfedu.ru\n"; + $headers .= "Reply-To: " . $this->user['EMail']; $data['success'] = true; mail($to, $subject, $message, $headers); $data['success'] = ($result[0]['Num'] > 0); - + $this->response->body(json_encode($data)); } } diff --git a/~dev_rating/application/classes/Controller/Handler/FileCreator.php b/~dev_rating/application/classes/Controller/Handler/FileCreator.php index 81c011141bbdd117dbb27714db6aad5f24b27a3f..6c1127f42a6a36b7b30800379a7f5faa8b79d143 100644 --- a/~dev_rating/application/classes/Controller/Handler/FileCreator.php +++ b/~dev_rating/application/classes/Controller/Handler/FileCreator.php @@ -2,186 +2,133 @@ class Controller_Handler_FileCreator extends Controller_Handler { - public function before() { - $this->model = new Model_Teacher_Rating; $this->setAccessLevel(self::ACCESS_USER); parent::before(); } - + // Таблица баллов (СЃРѕ страницы оценивания) [dev version] - public function action_GenerateExcelRatingTable() - { - // TODO CHECK!!! + public function action_GenerateExcelRatingTable() { + $xls = new PHPExcel(); - $xls = new PHPExcel(); + // Устанавливаем индекс активного листа + $xls->setActiveSheetIndex(0); - // Устанавливаем индекс активного листа - $xls->setActiveSheetIndex(0); + // Получаем активный лист + $sheet = $xls->getActiveSheet(); - // Получаем активный лист - $sheet = $xls->getActiveSheet(); + // Шапка таблицы: структура РЈРљР” (модули Рё мероприятия) + $structure = Model_Map::getMapForDiscipline($this->post['disciplineID']); - // Шапка таблицы: структура РЈРљР” (модули Рё мероприятия) - $structure = $this->model->GetMapForDiscipline($this->user['TeacherID'], $this->post->offsetGet('disciplineID')); + $id = -1; + $count = 0; + $maxRate = 0; + $structureHandled = array(); - $structureHandled = array(); - $maxRate = 0; $i = 0; $module = 0; + foreach ($structure as $row) { + if ($row['ModuleID'] != $id) { + $id = $row['ModuleID']; + $module =& $structureHandled[$count++]; - foreach($structure as $row) - { - if($row['ModuleID'] != $module) - { - $i++; - $module = $row['ModuleID']; - } - if(!isset($structureHandled[$i]['SubmodulesCount'])) - { - $structureHandled[$i]['SubmodulesCount'] = 0; - $structureHandled[$i]['MaxRate'] = 0; - } - $j = $structureHandled[$i]['SubmodulesCount'] += 1; - $structureHandled[$i]['MaxRate'] += (int) $row['MaxRate']; - $structureHandled[$i]['ModuleTitle'] = $row['ModuleName']; - $structureHandled[$i]['ModuleType'] = $row['ModuleType']; - - $structureHandled[$i][$j]['SubmoduleID'] = $row['SubmoduleID']; - $structureHandled[$i][$j]['Title'] = $row['SubModuleName']; - - $structureHandled[$i][$j]['MaxRate'] = (int) $row['MaxRate']; - $maxRate += $row['MaxRate']; + $module = array( + 'MaxRate' => 0, + 'SubmodulesCount' => 0, + 'ModuleTitle' => $row['ModuleName'], + 'ModuleType' => $row['ModuleType'], + ); } - $structureHandled['ModulesCount'] = $i; - $structureHandled['MaxRate'] = (int) $maxRate; - $sheet->setCellValueByColumnAndRow( - 0, // Столбец. Рндексация СЃ 0 - 1, // Строка. Рндексация СЃ 1 - 'Модуль' - ); + $module['SubmodulesCount']++; - $sheet->setCellValueByColumnAndRow( - 0, - 2, - 'Мероприятие' + $module[] = array( + 'SubmoduleID' => $row['SubmoduleID'], + 'Title' => $row['SubModuleName'], + 'MaxRate' => (int)$row['MaxRate'], ); - $sheet->setCellValueByColumnAndRow( - 0, - 3, - 'Макс. балл' - ); + $maxRate += $row['MaxRate']; + $module['MaxRate'] += (int)$row['MaxRate']; + } - $SubmodulesCount = 0; - // Модули - for ($k = 1; $k <= $structureHandled['ModulesCount']; $k++) - { - if ($k == 1) $pointer = 1; + $structureHandled['ModulesCount'] = $count; + $structureHandled['MaxRate'] = (int)$maxRate; - $sheet->mergeCellsByColumnAndRow($pointer, 1, $pointer + $structureHandled[$k]['SubmodulesCount'] - 1, 1); + $sheet->setCellValueByColumnAndRow(0, 1, 'Модуль'); + $sheet->setCellValueByColumnAndRow(0, 2, 'Мероприятие'); + $sheet->setCellValueByColumnAndRow(0, 3, 'Макс. балл'); - $sheet->setCellValueByColumnAndRow( - $pointer, - 1, - $structureHandled[$k]['ModuleTitle'] - ); + $submodulesCount = 0; - $l = 0; - // Мероприятия - for ($l = 1; $l <= $structureHandled[$k]['SubmodulesCount']; $l++) - { - $sheet->setCellValueByColumnAndRow( - $pointer + $l - 1, - 2, - $structureHandled[$k][$l]['Title'] - ); - - $sheet->setCellValueByColumnAndRow( - $pointer + $l - 1, - 3, - $structureHandled[$k][$l]['MaxRate'] - ); - $SubmodulesCount++; - } + // Модули + for ($k = 0, $pointer = 1; $k <= $structureHandled['ModulesCount']; $k++) { + $sheet->mergeCellsByColumnAndRow($pointer, 1, $pointer + $structureHandled[$k]['SubmodulesCount'] - 1, 1); + $sheet->setCellValueByColumnAndRow($pointer, 1, $structureHandled[$k]['ModuleTitle']); - $pointer = $structureHandled[$k]['SubmodulesCount'] + 1; + // Мероприятия + for ($l = 0; $l <= $structureHandled[$k]['SubmodulesCount']; $l++) { + $sheet->setCellValueByColumnAndRow($pointer + $l, 2, $structureHandled[$k][$l]['Title']); + $sheet->setCellValueByColumnAndRow($pointer + $l, 3, $structureHandled[$k][$l]['MaxRate']); + $submodulesCount++; } - $sheet->setCellValueByColumnAndRow( - $SubmodulesCount + 1, - 1, - 'Ртог' - ); + $pointer = $structureHandled[$k]['SubmodulesCount'] + 1; + } - $sheet->mergeCellsByColumnAndRow( $SubmodulesCount + 1, 1, $SubmodulesCount + 1, 3 ); + $sheet->setCellValueByColumnAndRow($submodulesCount + 1, 1, 'Ртог'); + $sheet->mergeCellsByColumnAndRow($submodulesCount + 1, 1, $submodulesCount + 1, 3); - // Студенты Рё РёС… баллы - $students = $this->model->GetStudentsForRating($this->user['TeacherID'], $this->post->offsetGet('disciplineID')); - $i_s = 0; $curGroup = 0; $ratesum = 0; + // Студенты Рё РёС… баллы + $students = Model_Rating::GetStudentsForRating($this->post['disciplineID']); - foreach($students as $row) { - if ($curGroup !== $row['GroupID']) { - $curGroup = $row['GroupID']; - $i_s++; - $sheet->mergeCellsByColumnAndRow( 0, 3 + $i_s, $SubmodulesCount + 1, 3 + $i_s ); - $sheet->setCellValueByColumnAndRow( - 0, - 3 + $i_s, - $row['GroupNum']." РіСЂСѓРїРїР°" - ); - } - // Студенты - $i_s++; - $ratesum += $r['Rate']; - - $sheet->setCellValueByColumnAndRow( - 0, - 3 + $i_s, - $row['Last'].' '.$row['First'].' '.$row['Second'] - ); + $i = 0; + $curGroup = 0; + $rateSum = 0; - // Баллы студента - $rate = $this->model->getMapForStudent($row['ID'], $this->post->offsetGet('disciplineID')); - $i_r = 0; - foreach($rate as $r) { - $i_r++; - $sheet->setCellValueByColumnAndRow( - $i_r, - 3 + $i_s, - $r['Rate'] - ); - } + foreach ($students as $row) { + if ($curGroup !== $row['GroupID']) { + $curGroup = $row['GroupID']; - $sheet->setCellValueByColumnAndRow( - $SubmodulesCount + 1, // Столбец. Рндексация СЃ 0 - 3 + $i_s, - $ratesum - ); + $i++; + $sheet->mergeCellsByColumnAndRow(0, 3 + $i, $submodulesCount + 1, 3 + $i); + $sheet->setCellValueByColumnAndRow(0, 3 + $i, $row['GroupNum'] . ' РіСЂСѓРїРїР°'); + } + // Студенты + $i++; + $rateSum += $row['Rate']; + $sheet->setCellValueByColumnAndRow(0, 3 + $i, $row['Last'] . ' ' . $row['First'] . ' ' . $row['Second']); + + // Баллы студента + $rate = Model_Rating::getMapForStudent($row['ID'], $this->post['disciplineID']); + $i_r = 0; + foreach ($rate as $r) { + $i_r++; + $sheet->setCellValueByColumnAndRow($i_r, 3 + $i, $r['Rate']); } - $this->GetHeaders(); - - // Выводим содержимое файла - $objWriter = new PHPExcel_Writer_Excel5($xls); - $objWriter->save('php://output'); + $sheet->setCellValueByColumnAndRow($submodulesCount + 1, 3 + $i, $rateSum); + } + + $this->GetHeaders(); + + // Выводим содержимое файла + $objWriter = new PHPExcel_Writer_Excel5($xls); + $objWriter->save('php://output'); } // Ведомость public function action_GenerateFinalForm() { - // TODO CHECK!!! // TODO - // parameters - $disciplineID = $this->post->offsetGet('disciplineID'); - $groupID = $this->post->offsetGet('studyGroupID'); - - // preparation - $db = $this->model; - $info = $db->getFinalFormInfo($disciplineID, $groupID); - - + // TODO CHECK!!! // TODO + // parameters + $disciplineID = $this->post['disciplineID']; + $groupID = $this->post['studyGroupID']; + + // preparation + $info = Model_Rating::getFinalFormInfo($disciplineID, $groupID); + $type = $info[0]['ExamType']; $templateFile = DOCROOT."docs/template $type.xls"; if (!file_exists($templateFile)) { @@ -189,34 +136,37 @@ class Controller_Handler_FileCreator extends Controller_Handler } $objPHPExcel = PHPExcel_IOFactory::load($templateFile); $objPHPExcel->setActiveSheetIndex(0); - + // $specName = ''; <------- TODO - $this->printDisciplineToExcelFile($objPHPExcel, $disciplineID, $groupID, $info[0]); - $grade = $info[0]["GradeNum"]; - $group = $info[0]["GroupNum"]; + $this->printDisciplineToExcelFile($objPHPExcel, $disciplineID, $groupID, $info[0]); + $grade = $info[0]["GradeNum"]; + $group = $info[0]["GroupNum"]; + $subjName = $info[0]["SubjectName"]; + $subjName = UTF8::substr($subjName,0, 10); + $subjName = str_replace(' ', '_', $subjName); + $filename = $subjName."_".$grade."_".$group; //$this->GetHeaders("FinalForm".$disciplineID."_".$groupID); - $this->GetHeaders("FinalForm_".$grade."_".$group); + $this->GetHeaders($filename); $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save('php://output'); - } - + } + public function printDisciplineToExcelFile(&$objPHPExcel, $disciplineID, $groupID, $headerData) { - + // preparation $type = $headerData['ExamType']; - $db = $this->model; - $result = $db->getRatesForStudentsGroup($this->user['TeacherID'], $disciplineID, $groupID); - $rates = $db->getAttestationData($disciplineID, $groupID); + $result = Model_Rating::getRatesForStudentsGroup($disciplineID, $groupID); + $rates = Model_Rating::getAttestationData($disciplineID, $groupID); // fill header $this->prepareSheetHeader($objPHPExcel, $type, $headerData); - + // fill students rows $startRow = 12; $rowNumber = $startRow; $index = 1; - - $examHold = $this->checkExamIsHold($result); + + $examHold = $this->checkExamIsHold($result); $i=0; foreach($result as $studentInfo){ @@ -228,33 +178,34 @@ class Controller_Handler_FileCreator extends Controller_Handler while ($rates[$i]['Type'] == 'exam' && $rates[$i]['StudentID'] == $studentInfo['ID']) { $orderNum = $rates[$i]['OrderNum']; $studentInfo['Attempt'][$orderNum]['ExamRate'] = (int)$rates[$i]['Rate']; - if (($timestamp = strtotime($rates[$i]['Date'])) == false) + $timestamp = strtotime($rates[$i]['Date']); + if ($timestamp == false) $date = ''; else $date = date("d.m.y", $timestamp); $studentInfo['Attempt'][$orderNum]['ExamDate'] = $date; $i++; } - $this->addStudentToSheet($objPHPExcel, $type, $studentInfo, $rowNumber, $index, $examHold); + $this->addStudentToSheet($objPHPExcel, $type, $studentInfo, $rowNumber, $index, $examHold); $rowNumber++; - $index++; + $index++; } } - protected function prepareSheetHeader(&$objPHPExcel, $disciplineType, $data) { + protected function prepareSheetHeader(PHPExcel &$objPHPExcel, $disciplineType, $data) { $sheet = $objPHPExcel->getActiveSheet(); - + $range = $objPHPExcel->getNamedRange("Discipline")->getRange(); $sheet->setCellValue($range, $data['SubjectName']); $range = $objPHPExcel->getNamedRange("Group")->getRange(); $sheet->setCellValue($range, $data['GroupNum']); $range = $objPHPExcel->getNamedRange("Subdivision")->getRange(); $sheet->setCellValue($range, $data['FacultyName']); - $range = $objPHPExcel->getNamedRange("Major")->getRange(); + $range = $objPHPExcel->getNamedRange("Major")->getRange(); $sheet->setCellValue($range, "Специальность: ".$data['SpecName']." ".$data['SpecCode']); $range = $objPHPExcel->getNamedRange("Teacher")->getRange(); $sheet->setCellValue($range, $data['LastName']." ".$data['FirstName']." ".$data['SecondName']); - + $range = $objPHPExcel->getNamedRange("Grade")->getRange(); $degree = $data['Degree']; $gradeNum = $data['GradeNum']; @@ -262,26 +213,28 @@ class Controller_Handler_FileCreator extends Controller_Handler if ($degree == 'master') $gradeName = $gradeName."Рј"; $sheet->setCellValue($range, $gradeName); - + $range = $objPHPExcel->getNamedRange("Semester")->getRange(); $semester = $data['SemesterNum'] + ($gradeNum -1)*2; $sheet->setCellValue($range, $semester); $range = $objPHPExcel->getNamedRange("Year")->getRange(); - $sheet->setCellValue($range, $data['Year']); + $startYear = $data['Year']; + $sheet->setCellValue($range, $startYear."/".($startYear+1)); $range = $objPHPExcel->getNamedRange("CreationDate")->getRange(); $sheet->setCellValue($range, date("d.m.y")); - + + $controlDate = ""; $range = $objPHPExcel->getNamedRange("Date")->getRange(); if ($disciplineType == 'credit') { - $controlDate = "Дата зачета\n30.12.2014"; + $controlDate = "Дата зачета\n".$this->figureOutCreditDate($data['SemesterNum'], $startYear); } elseif ($disciplineType == 'exam') { $controlDate = "Дата экзамена\n__________"; } $sheet->setCellValue("$range", $controlDate); } - protected function addStudentToSheet(&$objPHPExcel, $disciplineType, $data, $row, $index, $examHold1) + protected function addStudentToSheet(PHPExcel &$objPHPExcel, $disciplineType, $data, $row, $index, $examHold1) { $sheet = $objPHPExcel->getActiveSheet(); if ($disciplineType == 'credit') { @@ -291,7 +244,7 @@ class Controller_Handler_FileCreator extends Controller_Handler } } - protected function addStudentInfoForCreditToSheet(&$sheet, $data, $row, $index) + protected function addStudentInfoForCreditToSheet(PHPExcel_Worksheet &$sheet, $data, $row, $index) { $indPosition = 'A'; // Номер $namePosition = 'B'; // Р¤РРћ @@ -310,9 +263,9 @@ class Controller_Handler_FileCreator extends Controller_Handler ->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER); $sheet->mergeCells("B".$row.":F".$row); - $lastName = $data['Last']; - $firstName = $data['First']; - $secondName = $data['Second']; + $lastName = $data['LastName']; + $firstName = $data['FirstName']; + $secondName = $data['SecondName']; $semesterRate = (int)$data['intermediate']; $bonus = (int)$data['bonus']; $fullName = $lastName." ".$firstName." ".$secondName; @@ -324,16 +277,14 @@ class Controller_Handler_FileCreator extends Controller_Handler ->setCellValue($bonusRatePosition.$row, $bonus); $i=0; - $rateToShow = 0; + $extra = 0; do { - if (!$data['Attempt'][$i+1]['ExamDate']) - continue; + if ($i > 0) { + if (is_null($data['Attempt'][$i]['ExtraRate'])) + continue; - if ($i == 0) - $extra = 0; - else { $extra = $data['Attempt'][$i]['ExtraRate']; - $sheet->setCellValue($datePosition[$i].$row, $data['Attempt'][$i]['Date']) + $sheet->setCellValue($datePosition[$i].$row, $data['Attempt'][$i]['ExamDate']) ->setCellValue($extraRatePosition[$i].$row, $extra); } @@ -342,12 +293,12 @@ class Controller_Handler_FileCreator extends Controller_Handler if ($totalRate > 100) $totalRate = 100; - if($rateForCredit < 60) { - $rateToShow = ""; - $tempStr = "РЅРµ зачтено"; + if ($rateForCredit < 60) { + $rateToShow = ""; + $tempStr = "РЅРµ зачтено"; } else { - $rateToShow = $totalRate; - $tempStr = "зачтено"; + $rateToShow = $totalRate; + $tempStr = "зачтено"; } $sheet->setCellValue($stringRatePosition[$i].$row, $tempStr); @@ -356,10 +307,9 @@ class Controller_Handler_FileCreator extends Controller_Handler } while(++$i<3); $sheet->setCellValue($totalRatePosition.$row, $rateToShow); - } - protected function addStudentInfoForExamToSheet(&$sheet, $data, $row, $index, $examHold) + protected function addStudentInfoForExamToSheet(PHPExcel_Worksheet &$sheet, $data, $row, $index, $examHold) { $indPosition = 'A'; // Номер $namePosition = 'B'; // Р¤РРћ @@ -391,9 +341,9 @@ class Controller_Handler_FileCreator extends Controller_Handler ->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT); $sheet->mergeCells("B".$row.":G".$row); - $lastName = $data['Last']; - $firstName = $data['First']; - $secondName = $data['Second']; + $lastName = $data['LastName']; + $firstName = $data['FirstName']; + $secondName = $data['SecondName']; $semesterRate = (int)$data['intermediate']; $bonus = (int)$data['bonus']; $fullName = $lastName." ".$firstName." ".$secondName; @@ -410,13 +360,12 @@ class Controller_Handler_FileCreator extends Controller_Handler continue; $examRateValue = $data['Attempt'][$i+1]['ExamRate']; - if ($i > 0) { - $sheet->setCellValue($datePosition[$i].$row, $data['Attempt'][$i+1]['ExamDate']); - if ($i==1) { - $extra = $data['Attempt'][1]['ExtraRate']; - $examAdmission += $extra; - $sheet->setCellValue($extraRatePosition.$row, $extra); - } + if ($i != 0) { + $extra = $data['Attempt'][1]['ExtraRate']; + $sheet->setCellValue($datePosition[$i].$row, $data['Attempt'][$i+1]['ExamDate']) + ->setCellValue($extraRatePosition.$row, $extra); + $examAdmission += $extra; + } $total = $examAdmission+$examRateValue+$bonus; @@ -431,7 +380,7 @@ class Controller_Handler_FileCreator extends Controller_Handler } while(++$i<3); $sheet->setCellValue($totalRatePosition.$row, $totalRateStr); } - + protected function getSheetName(&$disciplineInfo) { $str = $disciplineInfo['SubjectAbbr']; if (empty($str)) { @@ -440,15 +389,14 @@ class Controller_Handler_FileCreator extends Controller_Handler //$str = preg_replace('/[^A-Za-z0-9\-]/', '', $str); return substr($str, 0, 10); } - + public function action_GenerateFinalFormsForGroup() { // parameters - //$gradeID = $this->post->offsetGet('gradeID'); - $groupID = $this->post->offsetGet('GroupID'); + //$gradeID = $this->post['gradeID']; + $groupID = $this->post['GroupID']; // preparation - $db = $this->model; - $listDisciplines = $db->GetDisciplinesForGroup($groupID); + $listDisciplines = Model_Disciplines::ofGroup($groupID); $templateFile = DOCROOT."docs/template credit.xls"; if (!file_exists($templateFile)) { @@ -458,13 +406,17 @@ class Controller_Handler_FileCreator extends Controller_Handler // Make copy of sheet $sheetTemplate = $objPHPExcel->getActiveSheet()->copy(); // Make copy of named ranges - $nmrange = $objPHPExcel->getNamedRanges() ; + $nmRange = $objPHPExcel->getNamedRanges() ; $index = 0; + $gradeNum = 0; + $groupNum = 0; + + foreach ($listDisciplines as $record) { $disciplineID = $record['DisciplineID']; - $info = $db->getFinalFormInfo($disciplineID, $groupID); + $info = Model_Rating::getFinalFormInfo($disciplineID, $groupID); $type = $info[0]['ExamType']; if ($type == 'exam') { continue; @@ -475,31 +427,31 @@ class Controller_Handler_FileCreator extends Controller_Handler foreach ($objPHPExcel->getNamedRanges() as $name => $r ) { $objPHPExcel -> removeNamedRange ($r->getName(), null); - } + } //make clone from page copy and include it in workbook $C = clone $sheetTemplate; try { $C->setTitle($this->getSheetName($info[0])); } catch (Exception $ex) { $C->setTitle("Без_имени_".$index); - } - + } + $objPHPExcel->addSheet($C,$index); $objPHPExcel->setActiveSheetIndex($index); - // create name ranges at new sheet - foreach ($nmrange as $namedRange) { + // create name ranges at new sheet + foreach ($nmRange as $namedRange) { $name = $namedRange->getName(); $rg = $namedRange->getRange(); $objPHPExcel->addNamedRange(new PHPExcel_NamedRange($name, $objPHPExcel->getActiveSheet(),$rg)); } } else - { + { try { $objPHPExcel->setActiveSheetIndex($index)->setTitle($this->getSheetName($info[0])); } catch (Exception $ex) { $objPHPExcel->setActiveSheetIndex($index)->setTitle("Без_имени_".$index); - } + } $gradeNum = $info[0]['GradeNum']; $groupNum = $info[0]['GroupNum']; } @@ -507,17 +459,16 @@ class Controller_Handler_FileCreator extends Controller_Handler $this->printDisciplineToExcelFile($objPHPExcel, $disciplineID, $groupID, $info[0]); $index++; } - + if ($index === 0) { throw HTTP_Exception::factory(400); - return; } $this->GetHeaders("FinalForm_".$gradeNum."_".$groupNum); $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5'); $objWriter->save('php://output'); } - + // Выводим HTTP-заголовки public function GetHeaders($filename = 'excel') { @@ -527,13 +478,13 @@ class Controller_Handler_FileCreator extends Controller_Handler $this->response->headers("Content-type", " application/vnd.ms-excel" ); $this->response->headers("Content-Disposition", "attachment; filename=".$filename.".xls" ); } - - protected function checkExamIsHold(&$studentsRates) + + protected function checkExamIsHold(&$studentsRates) { foreach($studentsRates as $studentInfo){ if ($studentInfo['exam'] >= 0) return 1; - } + } return 0; } @@ -545,7 +496,7 @@ class Controller_Handler_FileCreator extends Controller_Handler $totalRateStr = ''; $rateOfFive = ''; $examRateStr = ''; - if ($examHold != 0) + if ($examHold != 0) { $examRateStr = $examRateValue; if (($examAdmission < 38) or ($examRateValue < 22)) { @@ -560,15 +511,28 @@ class Controller_Handler_FileCreator extends Controller_Handler } } else - { + { if ($examAdmission < 38) { // задолженник //$totalRateStr = ' '; $rateOfFive = 'неуд'; $examRateStr = '0'; - } + } } - + return array($totalRateStr, $rateOfFive, $examRateStr); } + protected function figureOutCreditDate($semesterNum, $year) + { + $result = ""; + if ($semesterNum == 1) + $result = "30.12."; + else if ($semesterNum == 2) { + $result = "30.05."; + $year++; + } + $result = $result.$year; + return $result; + } + } \ No newline at end of file diff --git a/~dev_rating/application/classes/Controller/Handler/GetData.php b/~dev_rating/application/classes/Controller/Handler/GetData.php index 443e13e436d0ffc7de1636b097a310db1f21d4f6..f98b3b743a9395d9471b002dd523a0c84309af96 100644 --- a/~dev_rating/application/classes/Controller/Handler/GetData.php +++ b/~dev_rating/application/classes/Controller/Handler/GetData.php @@ -1,10 +1,11 @@ <?php defined('SYSPATH') or die('No direct script access.'); +/** Получение СЃРїРёСЃРєР° РіСЂСѓРїРї, РєСѓСЂСЃРѕРІ, предметов, Рё С‚.Рґ. */ class Controller_Handler_GetData extends Controller_Handler { public function before() { - //$this->model = new Model_Teacher_Rating; + //$this->model = new Model_Rating; $this->setAccessLevel(self::ACCESS_USER); parent::before(); } @@ -16,8 +17,8 @@ class Controller_Handler_GetData extends Controller_Handler $this->post -> rule('GradeID', 'not_empty') -> rule('GradeID', 'digit'); if($this->post->check()) { - $data['data'] = DataArray::factory('StudyGroups')->ordByGroups( - $this->post->offsetGet('GradeID'), $this->user['FacultyID'] )->asArray(); + $data['data'] = Model_Groups::orderByGroups( + $this->post['GradeID'], $this->user->FacultyID); $data['success'] = true; } @@ -31,9 +32,8 @@ class Controller_Handler_GetData extends Controller_Handler $this->post -> rule('GroupID', 'not_empty') -> rule('GroupID', 'digit'); if($this->post->check()) { - $data['data'] = DataArray::factory('Disciplines')->forGroup( - $this->post->offsetGet('GroupID'))->asArray(); - + $group = $this->post['GroupID']; + $data['data'] = Model_Disciplines::ofGroup($group)->as_array(); $data['success'] = true; } $this->response->body(json_encode($data)); diff --git a/~dev_rating/application/classes/Controller/Handler/Map.php b/~dev_rating/application/classes/Controller/Handler/Map.php index 25840728f930a24ac3c94c41cca044ee1a6b7172..90c1d961e89b7a061d73221f93f7734936f28a39 100644 --- a/~dev_rating/application/classes/Controller/Handler/Map.php +++ b/~dev_rating/application/classes/Controller/Handler/Map.php @@ -1,9 +1,12 @@ <?php defined('SYSPATH') or die('No direct script access.'); class Controller_Handler_Map extends Controller_Handler { - + + /** @var Model_Map */ + protected $model; + public function before() { - $this->model = new Model_Teacher_Map; + $this->model = new Model_Map; $this->setAccessLevel(self::ACCESS_USER); parent::before(); } @@ -22,27 +25,35 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('SubjectID', 'digit') -> rule('BonusRate', 'not_empty') -> rule('ExamType', 'not_empty') - -> rule('LectionCount', 'not_empty') - -> rule('LectionCount', 'digit') + -> rule('LectureCount', 'not_empty') + -> rule('LectureCount', 'digit') -> rule('PracticeCount', 'not_empty') -> rule('PracticeCount', 'digit') -> rule('LabCount', 'not_empty') -> rule('LabCount', 'digit') -> rule('FacultyID', 'not_empty') -> rule('FacultyID', 'digit'); - if($this->post->check()) { - $result = $this->model->AddDiscipline( + + if ($this->post->check()) { + if (Model_Discipline::exists($this->user['TeacherID'], $this->post['SubjectID'], $this->post['Grade'])) { + //throw HTTP_Exception::factory(403, "Дисциплина СЃ таким РєСѓСЂСЃРѕРј уже существует"); + $data = ['success' => false, 'code' => 1]; + $this->response->body(json_encode($data)); + return; + } + + $result = Model_Discipline::create( $this->user['TeacherID'], - $this->post->offsetGet('Grade'), - $this->post->offsetGet('SubjectID'), - $this->post->offsetGet('ExamType'), - $this->post->offsetGet('LectionCount'), - $this->post->offsetGet('PracticeCount'), - $this->post->offsetGet('LabCount'), - $this->post->offsetGet('FacultyID') + $this->post['Grade'], + $this->post['SubjectID'], + $this->post['ExamType'], + $this->post['LectureCount'], + $this->post['PracticeCount'], + $this->post['LabCount'], + $this->post['FacultyID'] ); $data['DisciplineID'] = $result[0]['Num']; - if ($this->post->offsetGet('BonusRate') == "true") + if ($this->post['BonusRate'] == "true") $result = $this->model->AddModuleBonus( $this->user['TeacherID'], $data['DisciplineID'] @@ -61,7 +72,7 @@ class Controller_Handler_Map extends Controller_Handler { if($this->post->check()) { $result = $this->model->DeleteDiscipline( $this->user['TeacherID'], - $this->post->offsetGet('DisciplineID') + $this->post['DisciplineID'] ); if ($result[0]['Num'] == 0) $data['success'] = true; @@ -77,23 +88,24 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('DisciplineID', 'not_empty') -> rule('DisciplineID', 'digit'); if($this->post->check()) { - $BindTeachersList = DataArray::factory('Teachers')->forDiscipline($id)->asArray(); + $id = $this->post['DisciplineID']; + $BindTeachersList = Model_Teachers::forDiscipline($id); $binded = false; foreach ($BindTeachersList as $teacher) { - if ($teacher['TeacherID'] == $this->post->offsetGet('NewAuthorID')) { + if ($teacher['TeacherID'] == $this->post['NewAuthorID']) { $binded = true; break; } } if ($binded == false) { - $result = $this->model->BindTeacher($this->user['TeacherID'], $this->post->offsetGet('NewAuthorID'), $this->post->offsetGet('DisciplineID')); + $result = $this->model->BindTeacher($this->user['TeacherID'], $this->post['NewAuthorID'], $this->post['DisciplineID']); } $result = $this->model->DelegateDiscipline( $this->user['TeacherID'], - $this->post->offsetGet('NewAuthorID'), - $this->post->offsetGet('DisciplineID') + $this->post['NewAuthorID'], + $this->post['DisciplineID'] ); if ($result[0]['Num'] == 0) $data['success'] = true; @@ -112,8 +124,8 @@ class Controller_Handler_Map extends Controller_Handler { if($this->post->check()) { $result = $this->model->ChangeDisciplineSubject( $this->user['TeacherID'], - $this->post->offsetGet('DisciplineID'), - $this->post->offsetGet('SubjectID') + $this->post['DisciplineID'], + $this->post['SubjectID'] ); if ($result[0]['Num'] == 0) $data['success'] = true; @@ -128,17 +140,17 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('DisciplineID', 'digit') -> rule('BonusRate', 'not_empty'); if($this->post->check()) { - if ($this->post->offsetGet('BonusRate') == 'true') { + if ($this->post['BonusRate'] == 'true') { $result = $this->model->AddModuleBonus( $this->user['TeacherID'], - $this->post->offsetGet('DisciplineID') + $this->post['DisciplineID'] ); $data['action'] = 'add'; } else { $result = $this->model->DeleteModuleBonus( $this->user['TeacherID'], - $this->post->offsetGet('DisciplineID') + $this->post['DisciplineID'] ); $data['action'] = 'delete'; } @@ -153,13 +165,23 @@ class Controller_Handler_Map extends Controller_Handler { $data['success'] = false; $this->post -> rule('DisciplineID', 'not_empty') -> rule('DisciplineID', 'digit') + -> rule('SubjectID', 'not_empty') + -> rule('SubjectID', 'digit') -> rule('GradeID', 'not_empty') -> rule('GradeID', 'digit'); + if($this->post->check()) { - $result = $this->model->ChangeDisciplineGrade( + if (Model_Discipline::exists($this->user['TeacherID'], $this->post['SubjectID'], $this->post['GradeID'])) { + //throw HTTP_Exception::factory(403, "Дисциплина СЃ таким РєСѓСЂСЃРѕРј уже существует"); + $data = ['success' => false, 'code' => 1]; + $this->response->body(json_encode($data)); + return; + } + + $result = Model_Discipline::changeGrade( + $this->post['DisciplineID'], $this->user['TeacherID'], - $this->post->offsetGet('DisciplineID'), - $this->post->offsetGet('GradeID') + $this->post['GradeID'] ); if ($result[0]['Num'] == 0) $data['success'] = true; @@ -175,8 +197,8 @@ class Controller_Handler_Map extends Controller_Handler { if($this->post->check()) { $result = $this->model->ChangeDisciplineControl( $this->user['TeacherID'], - $this->post->offsetGet('DisciplineID'), - $this->post->offsetGet('Control') + $this->post['DisciplineID'], + $this->post['Control'] ); $data['success'] = $result[0]['Num']; } @@ -197,9 +219,9 @@ class Controller_Handler_Map extends Controller_Handler { if($this->post->check()) { $result = $this->model->ChangeDisciplineHours( $this->user['TeacherID'], - $this->post->offsetGet('DisciplineID'), - $this->post->offsetGet('Hours'), - $this->post->offsetGet('Type') + $this->post['DisciplineID'], + $this->post['Hours'], + $this->post['Type'] ); if ($result[0]['Num'] == 0) $data['success'] = true; @@ -216,10 +238,11 @@ class Controller_Handler_Map extends Controller_Handler { $this->post -> rule('FacultyID', 'not_empty') -> rule('FacultyID', 'digit'); if($this->post->check()) { - $SubjectsList = DataArray::factory('Subjects')->byFaculty($this->post->offsetGet('FacultyID'))->asJSON(); + $faculty = $this->post['FacultyID']; + $subjectsList = Model_Subjects::byFaculty($faculty); $data['success'] = true; } - $this->response->body($SubjectsList); + $this->response->body(json_encode($subjectsList)); } // Добавить модуль Рё Рє модулю 1 мероприятие @@ -231,7 +254,7 @@ class Controller_Handler_Map extends Controller_Handler { // Добавление модуля $result = $this->model->AddModule( $this->user['TeacherID'], - $this->post->offsetGet('DisciplineID'), + $this->post['DisciplineID'], '' ); $data['moduleID'] = $result[0]['Num']; @@ -264,7 +287,7 @@ class Controller_Handler_Map extends Controller_Handler { if($this->post->check()) { $result = $this->model->AddSubmodule( $this->user['TeacherID'], - $this->post->offsetGet('submoduleID'), + $this->post['submoduleID'], '0', //MaxRate '', '', //Description @@ -284,7 +307,7 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('ModuleID', 'digit') -> rule('ModuleName', 'not_empty'); if($this->post->check()) { - $result = $this->model->ChangeModuleName($this->user['TeacherID'], $this->post->offsetGet('ModuleID'), $this->post->offsetGet('ModuleName')); + $result = $this->model->ChangeModuleName($this->user['TeacherID'], $this->post['ModuleID'], $this->post['ModuleName']); if ($result[0]['Num'] == 0) $data['success'] = true; } @@ -298,7 +321,7 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('SubmoduleID', 'digit') -> rule('SubmoduleName', 'not_empty'); if($this->post->check()) { - $result = $this->model->ChangeSubmoduleName($this->user['TeacherID'], $this->post->offsetGet('SubmoduleID'), $this->post->offsetGet('SubmoduleName')); + $result = $this->model->ChangeSubmoduleName($this->user['TeacherID'], $this->post['SubmoduleID'], $this->post['SubmoduleName']); if ($result[0]['Num'] == 0) $data['success'] = true; } @@ -315,8 +338,8 @@ class Controller_Handler_Map extends Controller_Handler { if($this->post->check()) { $result = $this->model->SwapModuleOrder( $this->user['TeacherID'], - $this->post->offsetGet('ModuleID1'), - $this->post->offsetGet('ModuleID2') + $this->post['ModuleID1'], + $this->post['ModuleID2'] ); if ($result[0]['Num'] == 0) $data['success'] = true; @@ -334,8 +357,8 @@ class Controller_Handler_Map extends Controller_Handler { if($this->post->check()) { $result = $this->model->SwapSubmoduleOrder( $this->user['TeacherID'], - $this->post->offsetGet('SubmoduleID1'), - $this->post->offsetGet('SubmoduleID2') + $this->post['SubmoduleID1'], + $this->post['SubmoduleID2'] ); if ($result[0]['Num'] == 0) $data['success'] = true; @@ -351,7 +374,7 @@ class Controller_Handler_Map extends Controller_Handler { if($this->post->check()) { $result = $this->model->deleteModule( $this->user['TeacherID'], - $this->post->offsetGet('ModuleID') + $this->post['ModuleID'] ); $data['success'] = ($result[0]['Num'] == 0); } @@ -364,7 +387,7 @@ class Controller_Handler_Map extends Controller_Handler { $this->post -> rule('SubmoduleID', 'not_empty') -> rule('SubmoduleID', 'digit'); if($this->post->check()) { - $result = $this->privateDeleteSubmodule($this->post->offsetGet('SubmoduleID')); + $result = $this->privateDeleteSubmodule($this->post['SubmoduleID']); $data['success'] = ($result == 0); } $this->response->body(json_encode($data)); @@ -379,9 +402,9 @@ class Controller_Handler_Map extends Controller_Handler { if($this->post->check()) { $result = $this->model->ChangeSubmoduleMaxAndControl( $this->user['TeacherID'], - $this->post->offsetGet('SubmoduleID'), - $this->post->offsetGet('MaxRate'), - $this->post->offsetGet('ControlType') + $this->post['SubmoduleID'], + $this->post['MaxRate'], + $this->post['ControlType'] ); if ($result[0]['Num'] == 0) $data['success'] = true; @@ -394,10 +417,10 @@ class Controller_Handler_Map extends Controller_Handler { $data['success'] = false; $this->post -> rule('DisciplineID', 'not_empty') -> rule('DisciplineID', 'digit') - -> rule('StudyGroupID', 'not_empty') - -> rule('StudyGroupID', 'digit'); + -> rule('GroupID', 'not_empty') + -> rule('GroupID', 'digit'); if($this->post->check()) { - $result = $this->model->BindGroup($this->user['TeacherID'], $this->post->offsetGet('DisciplineID'), $this->post->offsetGet('StudyGroupID')); + $result = $this->model->BindGroup($this->user['TeacherID'], $this->post['DisciplineID'], $this->post['GroupID']); if ($result[0]['Num'] == 0) $data['success'] = true; $data['code'] = $result[0]['Num']; @@ -410,10 +433,10 @@ class Controller_Handler_Map extends Controller_Handler { $data['success'] = false; $this->post -> rule('DisciplineID', 'not_empty') -> rule('DisciplineID', 'digit') - -> rule('StudyGroupID', 'not_empty') - -> rule('StudyGroupID', 'digit'); + -> rule('GroupID', 'not_empty') + -> rule('GroupID', 'digit'); if($this->post->check()) { - $result = $this->model->UnbindGroup($this->user['TeacherID'], $this->post->offsetGet('DisciplineID'), $this->post->offsetGet('StudyGroupID')); + $result = $this->model->UnbindGroup($this->user['TeacherID'], $this->post['DisciplineID'], $this->post['GroupID']); if ($result[0]['Num'] == 0) $data['success'] = true; } @@ -428,7 +451,7 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('DisciplineID', 'not_empty') -> rule('DisciplineID', 'digit'); if($this->post->check()) { - $result = $this->model->BindStudent($this->user['TeacherID'], $this->post->offsetGet('DisciplineID'), $this->post->offsetGet('StudentID')); + $result = $this->model->BindStudent($this->user['TeacherID'], $this->post['DisciplineID'], $this->post['StudentID']); if ($result[0]['Num'] == 0) $data['success'] = true; } @@ -443,7 +466,7 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('DisciplineID', 'not_empty') -> rule('DisciplineID', 'digit'); if($this->post->check()) { - $result = $this->model->UnbindStudent($this->user['TeacherID'], $this->post->offsetGet('DisciplineID'), $this->post->offsetGet('StudentID')); + $result = $this->model->UnbindStudent($this->user['TeacherID'], $this->post['DisciplineID'], $this->post['StudentID']); if ($result[0]['Num'] == 0) $data['success'] = true; } @@ -451,13 +474,15 @@ class Controller_Handler_Map extends Controller_Handler { } // Получаем СЃРїРёСЃРѕРє РіСЂСѓРїРї - public function action_GetStudyGroups() { + public function action_GetGroups() { $this->post -> rule('GradeID', 'digit') -> rule('FacultyID', 'digit'); if($this->post->check()) { - $Groups = DataArray::factory('StudyGroups')->ordByGroups($this->post->offsetGet('GradeID'), $this->post->offsetGet('FacultyID'))->asJSON(); + $grade = $this->post['GradeID']; + $faculty = $this->post['FacultyID']; + $groups = Model_Groups::orderByGroups($grade, $faculty); } - $this->response->body($Groups); + $this->response->body(json_encode($groups)); } // РџРѕРёСЃРє студентов @@ -468,16 +493,15 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('DisciplineID', 'not_empty') -> rule('DisciplineID', 'digit'); if($this->post->check()) { - $SearchResult = DataArray::factory('Students') - ->NotAttendingDiscipline( - $this->post->offsetGet('GradeID'), - $this->post->offsetGet('GroupID'), - $this->post->offsetGet('FacultyID'), - $this->post->offsetGet('Name'), - $this->post->offsetGet('DisciplineID') - )->asJSON(); + $searchResult = Model_Students::NotAttendingDiscipline( + $this->post['GradeID'], + $this->post['GroupID'], + $this->post['FacultyID'], + $this->post['Name'], + $this->post['DisciplineID'] + ); } - $this->response->body($SearchResult); + $this->response->body(json_encode($searchResult)); } @@ -489,7 +513,7 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('DisciplineID', 'not_empty') -> rule('DisciplineID', 'digit'); if($this->post->check()) { - $result = $this->model->BindTeacher($this->user['TeacherID'], $this->post->offsetGet('BindingTeacher'), $this->post->offsetGet('DisciplineID')); + $result = $this->model->BindTeacher($this->user['TeacherID'], $this->post['BindingTeacher'], $this->post['DisciplineID']); if ($result[0]['Num'] == 0) $data['success'] = true; } @@ -504,7 +528,7 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('DisciplineID', 'not_empty') -> rule('DisciplineID', 'digit'); if($this->post->check()) { - $result = $this->model->UnbindTeacher($this->user['TeacherID'], $this->post->offsetGet('BindingTeacher'), $this->post->offsetGet('DisciplineID')); + $result = $this->model->UnbindTeacher($this->user['TeacherID'], $this->post['BindingTeacher'], $this->post['DisciplineID']); if ($result[0]['Num'] == 0) $data['success'] = true; } @@ -516,9 +540,10 @@ class Controller_Handler_Map extends Controller_Handler { $this->post -> rule('FacultyID', 'not_empty') -> rule('FacultyID', 'digit'); if($this->post->check()) { - $DepList = DataArray::factory('Departments')->byFaculty($this->post->offsetGet('FacultyID'))->asJSON(); + $faculty = $this->post['FacultyID']; + $departments = Model_Departments::byFaculty($faculty); } - $this->response->body($DepList); + $this->response->body(json_encode($departments)); } // РџРѕРёСЃРє преподавателей @@ -528,19 +553,19 @@ class Controller_Handler_Map extends Controller_Handler { -> rule('DisciplineID', 'digit'); if($this->post->check()) { $SeResult = $this->model->SearchTeachers( - $this->post->offsetGet('FacultyID'), - $this->post->offsetGet('DepartmentID'), - $this->post->offsetGet('Last'), - $this->post->offsetGet('DisciplineID') + $this->post['FacultyID'], + $this->post['DepartmentID'], + $this->post['Last'], + $this->post['DisciplineID'] ); $SearchResult = array(); $i = 0; foreach($SeResult as $row){ $i++; $SearchResult[$i]['TeacherID'] = $row['ID']; - $SearchResult[$i]['TeacherLast'] = $row['Last']; - $SearchResult[$i]['TeacherFirst'] = $row['First']; - $SearchResult[$i]['TeacherSecond'] = $row['Second']; + $SearchResult[$i]['TeacherLast'] = $row['LastName']; + $SearchResult[$i]['TeacherFirst'] = $row['FirstName']; + $SearchResult[$i]['TeacherSecond'] = $row['SecondName']; $SearchResult[$i]['JobPositionName'] = $row['JobPositionName']; $SearchResult[$i]['DepID'] = $row['DepID']; } diff --git a/~dev_rating/application/classes/Controller/Handler/Rating.php b/~dev_rating/application/classes/Controller/Handler/Rating.php index e6250adf00e6f26670938e55892702602a563f8c..a6ad8b57686e14f4af5b26fdbe8bd15795543617 100644 --- a/~dev_rating/application/classes/Controller/Handler/Rating.php +++ b/~dev_rating/application/classes/Controller/Handler/Rating.php @@ -2,9 +2,11 @@ class Controller_Handler_Rating extends Controller_Handler { + /** @var Model_Rating */ + protected $model; public function before() { - $this->model = new Model_Teacher_Rating; + $this->model = new Model_Rating; $this->setAccessLevel(self::ACCESS_USER); parent::before(); } @@ -19,10 +21,10 @@ class Controller_Handler_Rating extends Controller_Handler -> rule('rate', 'digit') -> rule('rate', 'range', array(':value', 0, 100)); if($this->post->check()) { - $result = $this->model->SetStudentRate( $this->user['TeacherID'], - $this->post->offsetGet('student'), - $this->post->offsetGet('submodule'), - $this->post->offsetGet('rate')); + $result = $this->model->SetStudentRate( $this->user['TeacherID'], + $this->post['student'], + $this->post['submodule'], + $this->post['rate']); $data['success'] = ($result[0]['Num'] == 0); } $this->response->body(json_encode($data)); @@ -38,7 +40,7 @@ class Controller_Handler_Rating extends Controller_Handler //$SGID = Cookie::get('SGID', null); $SG_json = json_decode(Cookie::get('SGID', null), true); - $SG_json[$this->post->offsetGet('disciplineID')] = $this->post->offsetGet('groupSelected'); + $SG_json[$this->post['disciplineID']] = $this->post['groupSelected']; Cookie::set('SGID', json_encode($SG_json), '2592000'); $data['success'] = true; diff --git a/~dev_rating/application/classes/Controller/Handler/Session.php b/~dev_rating/application/classes/Controller/Handler/Session.php index 09e7b24f3f0307e64c9be2a8b9e19d5f65afadb1..2270f78d4da4f0d084008fcb60b555e93a1b8f95 100644 --- a/~dev_rating/application/classes/Controller/Handler/Session.php +++ b/~dev_rating/application/classes/Controller/Handler/Session.php @@ -1,8 +1,8 @@ <?php defined('SYSPATH') or die('No direct script access.'); class Controller_Handler_Session extends Controller_Handler { - - protected $_user; + /** @var User */ + protected $_user; # $user is already defined in the parent class. public function before() { $this->_user = User::instance(true); diff --git a/~dev_rating/application/classes/Controller/Handler/Settings.php b/~dev_rating/application/classes/Controller/Handler/Settings.php index aa184f91ca8683453aee132fa6b37cc5cc53451c..b22524db99e7c267fc8cbebf4e5273857994faa0 100644 --- a/~dev_rating/application/classes/Controller/Handler/Settings.php +++ b/~dev_rating/application/classes/Controller/Handler/Settings.php @@ -12,7 +12,7 @@ class Controller_Handler_Settings extends Controller_Handler { $config = Kohana::$config->load('security.securityPolicy'); $this->post->rule('login', $config['login']['allowedSymbols'])->rule('login', 'not_empty'); $arr['success'] = true; - $login = $this->post->offsetGet('login'); + $login = $this->post['login']; if(!$this->post->check()) { $arr['success'] = false; @@ -38,8 +38,8 @@ class Controller_Handler_Settings extends Controller_Handler { ->rule('password', 'min_length', array(':value', $config['password']['length'])) ->rule('confirm_password', 'matches', array(':validation', 'confirm_password', 'password')); $arr['success'] = true; - $old = $this->post->offsetGet('old_password'); - $new = $this->post->offsetGet('password'); + $old = $this->post['old_password']; + $new = $this->post['password']; if(!$this->post->check()) { $arr['success'] = false; @@ -79,15 +79,14 @@ class Controller_Handler_Settings extends Controller_Handler { public function action_getDepartmentsList() { - $facultyID = $this->post->offsetGet('facultyID'); - $deps = DataArray::factory('Departments')->byFaculty($facultyID)->asArray(); - $this->response->body(json_encode($deps)); + $facultyID = $this->post['facultyID']; + $departments = Model_Departments::byFaculty($facultyID); + $this->response->body(json_encode($departments)); } public function action_changeEMail() { - $this->post->rule('email'); - // if(Account::instance()->changeMail()) + // We don't change email address:\ } public function action_confirmNewEMail() @@ -101,7 +100,7 @@ class Controller_Handler_Settings extends Controller_Handler { ->rule('semesterID', 'not_empty') ->rule('semesterID', 'digit'); if($this->post->check()) { - $semesterID = $this->post->offsetGet('semesterID'); + $semesterID = $this->post['semesterID']; User::instance()->SetSemester($semesterID); } } diff --git a/~dev_rating/application/classes/Controller/Handler/Sign.php b/~dev_rating/application/classes/Controller/Handler/Sign.php index ff0c841295e9cd1041a7979fbefd7346e2b53429..65f588f43db28ed50d2838fbbf4c9126b4fbf28e 100644 --- a/~dev_rating/application/classes/Controller/Handler/Sign.php +++ b/~dev_rating/application/classes/Controller/Handler/Sign.php @@ -13,7 +13,7 @@ class Controller_Handler_Sign extends Controller_Handler { $checklogin = true; $response['success'] = false; if(!$this->post->check()) { - $this->post = Validation::factory($this->post->as_array()); + $this->post = Validation::factory($this->post->data()); $this->post->rule('login', 'alpha_dash')->rule('login', 'not_empty'); if(!$this->post->check()) { @@ -24,8 +24,8 @@ class Controller_Handler_Sign extends Controller_Handler { if($checklogin) { $response['success'] = User::instance() - ->signIn($this->post->offsetGet('login'), - $this->post->offsetGet('password')); + ->signIn($this->post['login'], + $this->post['password']); } $this->response->body(json_encode($response)); } @@ -44,10 +44,10 @@ class Controller_Handler_Sign extends Controller_Handler { if($this->post->check()) { list($response['success'], $attempt) = User::instance() - ->signUp($this->post->offsetGet('activation_code'), - $this->post->offsetGet('email'), - $this->post->offsetGet('login'), - $this->post->offsetGet('password')); + ->signUp($this->post['activation_code'], + $this->post['email'], + $this->post['login'], + $this->post['password']); if(!$response['success']) { switch ($attempt) @@ -77,13 +77,18 @@ class Controller_Handler_Sign extends Controller_Handler { $this->post->rule('email', 'not_empty')->rule('email', 'email'); if($this->post->check()) { - $email = $this->post->offsetGet('email'); + $email = $this->post['email']; if(Account::instance()->isMailExists($email)) { - Account::instance()->createRecoveryRequest($this->post->offsetGet('email')); + Account::instance()->createRecoveryRequest($this->post['email']); + $response['success'] = true; } - $response['success'] = true; + else + $response['error'] = 'Пользователь СЃ таким e-mail адресом РЅРµ зарегистрирован РІ системе!'; } + else + $response['error'] = 'Введенная строка РЅРµ является e-mail адресом!'; + $this->response->body(json_encode($response)); } @@ -96,10 +101,10 @@ class Controller_Handler_Sign extends Controller_Handler { ->rule('confirm_password', 'matches', array(':validation', 'confirm_password', 'password')); if($this->post->check()) { - $token = $this->post->offsetGet('token'); + $token = $this->post['token']; if(Account::instance()->checkToken($token)) { - Account::instance()->changePasswordByToken($token, $this->post->offsetGet('password')); + Account::instance()->changePasswordByToken($token, $this->post['password']); $response['success'] = true; } } diff --git a/~dev_rating/application/classes/Controller/Handler/readme.txt b/~dev_rating/application/classes/Controller/Handler/readme.txt deleted file mode 100644 index 228867ba6313984fe8b09ccb97ec8e7a2d0180fc..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Controller/Handler/readme.txt +++ /dev/null @@ -1,2 +0,0 @@ -FileCreator - создание ведомостей -GetData - Получить список групп, курсов, предметов и тд \ No newline at end of file diff --git a/~dev_rating/application/classes/Controller/Student/Index.php b/~dev_rating/application/classes/Controller/Student/Index.php index f13f3925e2f75615b1a2d3676c23e5a5aafc7465..b378568bc9f3cce6e9bd527147d3dd98157bec94 100644 --- a/~dev_rating/application/classes/Controller/Student/Index.php +++ b/~dev_rating/application/classes/Controller/Student/Index.php @@ -1,91 +1,49 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Student_Index extends Controller_UserEnvi { +class Controller_Student_Index extends Controller_UserEnvironment { - public function action_index() - { - $db = new Model_Student; - $disciplines = $db->getAllDisciplines($this->UserInfo['StudentID']); + public function action_index() { + $student_id = $this->user['StudentID']; + $disciplines = Model_Disciplines::ofStudent($student_id); - $i = 0; - $colorsList = array('Undefined', 'ECTS-F', 'ECTS-FX', 'ECTS-E', 'ECTS-D', 'ECTS-C', 'ECTS-B', 'ECTS-A'); - foreach($disciplines as $row) - { - $i++; - $disciplinesHandled[$i]['ID'] = $row['ID']; - if($row['ExamType'] == 'exam') - { - $disciplinesHandled[$i]['Control'] = 'Ркзамен'; - } - elseif($row['ExamType'] == 'credit') - { - $disciplinesHandled[$i]['Control'] = 'Зачет'; - } - $disciplinesHandled[$i]['Teachers'] = $this->getTeachersForDiscipline($row['ID']); - $disciplinesHandled[$i]['Title'] = $row['SubjectName']; - $disciplinesHandled[$i]['Rate'] = $row['Rate']; - $disciplinesHandled[$i]['MaxCurrentRate'] = $row['MaxCurrentRate']; - $disciplinesHandled[$i]['ColorScheme'] = $colorsList[$this->getColor($row['Rate'], $row['MaxCurrentRate'], $row['ExamRate'])]; + $list = array(); + foreach ($disciplines as $row) { + $row['Title'] = $row['SubjectName']; + $row['Teachers'] = self::getTeachersForDiscipline($row['ID']); + $row['Control'] = ($row['ExamType'] == 'exam') ? 'Ркзамен' : 'Зачет'; + $row['ColorScheme'] = Model_Subjects::getECTSMark($row['Rate'], $row['MaxCurrentRate'], $row['ExamRate']); + $list[] = $row; } $twig = Twig::factory('student/index'); - if ($i != 0) - $twig->disciplines = $disciplinesHandled; - $twig->User = $this->UserInfo; + if (count($disciplines) > 0) + $twig->disciplines = $list; + $twig->User = $this->user; $twig->Semester = $this->SemesterInfo; - $twig->SemesterList = DataArray::factory('Semesters')->getList(); + $twig->SemesterList = Model_Semesters::toArray(); $this->response->body($twig); } - - protected function getTeachersForDiscipline($id) { - $model = new Model_Student; - $teachers = $model->getTeachersForDiscipline($id); - $teachersHandled = array(); $i = 0; - foreach ($teachers as $teacher) - { - $i++; - $teachersHandled[$i] = $teacher['Last'].' '.UTF8::substr($teacher['First'], 0, 1).'. '; - if(!empty($teacher['Second'])) - { - $teachersHandled[$i] .= UTF8::substr($teacher['Second'], 0, 1).'.'; - } - } - return $teachersHandled; - } - - protected function getColor($rate, $current, $examRate) - { - if($current > 0) - { - $percent = $rate / $current; - if($percent < 0.31) - $color = 1; - elseif($percent >= 0.31 AND $percent <= 0.59) - $color = 2; - elseif($percent >= 0.60 AND $percent <= 0.64) - $color = 3; - elseif($percent >= 0.65 AND $percent <= 0.70) - $color = 4; - elseif($percent >= 0.71 AND $percent <= 0.84) - $color = 5; - elseif($percent >= 0.85 AND $percent <= 0.94) - $color = 6; - elseif($percent >= 0.95) - $color = 7; - if($examRate !== NULL AND $examRate < 22) - $color = 2; - } - else - { - $color = 0; + + /** + * @param $id int discipline id + * @return array list of short-form names + */ + private static function getTeachersForDiscipline($id) { + $teachers = Model_Teachers::ofDiscipline($id); + + $list = array(); + foreach ($teachers as $teacher) { + $name = $teacher['LastName'] . ' ' . UTF8::substr($teacher['FirstName'], 0, 1) . '. '; + if (!empty($teacher['SecondName'])) + $name .= UTF8::substr($teacher['SecondName'], 0, 1) . '.'; + $list[] = $name; } - return $color; + return $list; } - public function action_settings() { $twig = Twig::factory('settings'); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } } diff --git a/~dev_rating/application/classes/Controller/Student/Subject.php b/~dev_rating/application/classes/Controller/Student/Subject.php index 6eb985f3ba513333f828204577f2574ccfe86e56..23899c30bc37ab0d3f5c170237287e03dc5e6412 100644 --- a/~dev_rating/application/classes/Controller/Student/Subject.php +++ b/~dev_rating/application/classes/Controller/Student/Subject.php @@ -1,16 +1,13 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Student_Subject extends Controller_UserEnvi { +class Controller_Student_Subject extends Controller_UserEnvironment { public function action_show() { - - // ЛОГРРљРђ - $db = new Model_Student; $id = $this->request->param('id'); - - $discipline = $db->getDisciplineMap($this->UserInfo['StudentID'], $id); - $info = $db->getDisciplineInfoByID($id)->offsetGet(0); + $student = $this->user['StudentID']; + $discipline = Model_Rating::getRates($id, $student); + $info = Model_Discipline::getInfo($id); // Рнформация Рѕ предмете $subject['Title'] = $info['SubjectName']; @@ -23,12 +20,12 @@ class Controller_Student_Subject extends Controller_UserEnvi { $subject['Control'] = 'Зачет'; } $subject['ExamType'] = $info['ExamType']; - $subject['LectionCount'] = $info['LectionCount']; + $subject['LectureCount'] = $info['LectureCount']; $subject['PracticeCount'] = $info['PracticeCount']; $subject['LabCount'] = $info['LabCount']; $subject['DepName'] = $info['DepName']; $subject['Teachers'] = $this->getTeachersForDiscipline($id); - $semester = $db->getSemesterInfo($info['SemesterID']); + $semester = Model_Semesters::getInfo($info['SemesterID']); $semester['Num'] = $semester['Num'] == 1 ? 'Осенний' : 'Весенний'; $subject['Num'] = $semester['Num']; $subject['Year'] = $semester['Year']; @@ -85,7 +82,7 @@ class Controller_Student_Subject extends Controller_UserEnvi { $disciplineHandled['Modules'][$i]['MaxRate'] += (int) $row['MaxRate']; $disciplineHandled['Modules'][$i]['Title'] = $row['ModuleName']; - $disciplineHandled['Modules'][$i]['Submodules'][$j]['Title'] = $row['SubModuleName']; + $disciplineHandled['Modules'][$i]['Submodules'][$j]['Title'] = $row['SubmoduleName']; $disciplineHandled['Modules'][$i]['Submodules'][$j]['Description'] = $row['SubmoduleDescription']; $disciplineHandled['Modules'][$i]['Submodules'][$j]['Rate'] = (int) $row['Rate']; $disciplineHandled['Modules'][$i]['Submodules'][$j]['Date'] = $row['Date']; @@ -107,7 +104,7 @@ class Controller_Student_Subject extends Controller_UserEnvi { // ПРЕДСТАВЛЕНРР• $twig = Twig::factory('student/subject'); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $twig->Discipline = $subject; $twig->DisciplineMap = $disciplineHandled; @@ -115,16 +112,15 @@ class Controller_Student_Subject extends Controller_UserEnvi { } protected function getTeachersForDiscipline($id) { - $model = new Model_Student; - $teachers = $model->getTeachersForDiscipline($id); + $teachers = Model_Teachers::ofDiscipline($id); $teachersHandled = array(); $i = 0; foreach ($teachers as $teacher) { $i++; - $teachersHandled[$i] = $teacher['Last'].' '.$teacher['First'].' '; - if(!empty($teacher['Second'])) + $teachersHandled[$i] = $teacher['LastName'].' '.$teacher['FirstName'].' '; + if(!empty($teacher['SecondName'])) { - $teachersHandled[$i] .= $teacher['Second']; + $teachersHandled[$i] .= $teacher['SecondName']; } } return $teachersHandled; diff --git a/~dev_rating/application/classes/Controller/Teacher/Discipline.php b/~dev_rating/application/classes/Controller/Teacher/Discipline.php index 0fe2f98b413d44fab5decf980d5918bded89e7aa..aa9f04d47859dd168bcbe45ff67f7d7d87911be1 100644 --- a/~dev_rating/application/classes/Controller/Teacher/Discipline.php +++ b/~dev_rating/application/classes/Controller/Teacher/Discipline.php @@ -1,15 +1,15 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Teacher_Discipline extends Controller_UserEnvi { +class Controller_Teacher_Discipline extends Controller_UserEnvironment { public function action_CreateDiscipline() { $twig = Twig::factory('teacher/discipline/CreateDiscipline'); - $db = new Model_Teacher_Map; - $twig->User = $this->UserInfo; - $twig->FacultiesList = DataArray::factory('Faculties')->common()->asArray(); - $twig->SubjectsList = DataArray::factory('Subjects')->byFaculty($this->UserInfo['FacultyID'])->asArray(); - $twig->GradesList = DataArray::factory('Grades')->common()->asArray(); + $db = new Model_Map; + $twig->User = $this->user; + $twig->FacultiesList = Model_Faculties::toArray(); + $twig->SubjectsList = Model_Subjects::byFaculty($this->user['FacultyID']); + $twig->GradesList = Model_Grades::toArray(); $this->response->body($twig); } @@ -17,15 +17,13 @@ class Controller_Teacher_Discipline extends Controller_UserEnvi { public function action_EditSettings() { $id = $this->request->param('id'); - $db = new Model_Teacher_Map; + $db = new Model_Map; $twig = Twig::factory('teacher/discipline/EditSettings'); - $twig->User = $this->UserInfo; - - //$twig->FacultiesList = DataArray::factory('Faculties')->common()->asArray(); - $twig->Discipline = $this->GetDisciplineInfo($db, $id); - $twig->SubjectsList = DataArray::factory('Subjects')->byFaculty($this->UserInfo['FacultyID'])->asArray(); - $twig->GradesList = DataArray::factory('Grades')->common()->asArray(); + $twig->User = $this->user; + $twig->Discipline = $this->GetDisciplineInfo($id); + $twig->SubjectsList = Model_Subjects::byFaculty($this->user['FacultyID']); + $twig->GradesList = Model_Grades::toArray(); $this->response->body($twig); } @@ -33,12 +31,12 @@ class Controller_Teacher_Discipline extends Controller_UserEnvi { public function action_EditStructure() { $id = $this->request->param('id'); - $db = new Model_Teacher_Map; + $db = new Model_Map; $twig = Twig::factory('teacher/discipline/EditStructure'); - $twig->User = $this->UserInfo; - $twig->Discipline = $this->GetDisciplineInfo($db, $id); - $twig->Map = $this->GetMapInfo($db->getMapForDiscipline($this->UserInfo['TeacherID'], $id)); + $twig->User = $this->user; + $twig->Discipline = $this->GetDisciplineInfo($id); + $twig->Map = $this->GetMapInfo($db->getMapForDiscipline($id)); $this->response->body($twig); } @@ -46,14 +44,14 @@ class Controller_Teacher_Discipline extends Controller_UserEnvi { public function action_EditGroups() { $id = $this->request->param('id'); - $db = new Model_Teacher_Map; + $db = new Model_Map; $twig = Twig::factory('teacher/discipline/EditGroups'); - $twig->User = $this->UserInfo; - $twig->Discipline = $this->GetDisciplineInfo($db, $id); + $twig->User = $this->user; + $twig->Discipline = $this->GetDisciplineInfo($id); - $twig->GroupsForDiscipline = DataArray::factory('StudyGroups')->forDiscipline($id)->asArray(); - $twig->StudyGroups = DataArray::factory('StudyGroups')->ordByGroups($twig->Discipline['GradeID'], $twig->Discipline['FacultyID'])->asArray(); + $twig->GroupsForDiscipline = Model_Groups::forDiscipline($id); + $twig->Groups = Model_Groups::orderByGroups($twig->Discipline['GradeID'], $twig->Discipline['FacultyID']); $this->response->body($twig); } @@ -61,22 +59,24 @@ class Controller_Teacher_Discipline extends Controller_UserEnvi { public function action_EditStudents() { $id = $this->request->param('id'); - $db = new Model_Teacher_Map; + $db = new Model_Map; $twig = Twig::factory('teacher/discipline/EditStudents'); - $twig->User = $this->UserInfo; - $twig->Discipline = $this->GetDisciplineInfo($db, $id); - $twig->GradesList = DataArray::factory('Grades')->common()->asArray(); - $twig->StudyGroups = DataArray::factory('StudyGroups')->ordByGroups($twig->Discipline['GradeID'], $twig->Discipline['FacultyID'])->asArray(); + $twig->User = $this->user; + $twig->Discipline = $this->GetDisciplineInfo($id); + $twig->GradesList = Model_Grades::toArray(); + $twig->GroupsList = Model_Groups::orderByGroups($twig->Discipline['GradeID'], $twig->Discipline['FacultyID']); - $students = $db->getStudentsForDiscipline($this->UserInfo['TeacherID'], $id); + $students = Model_Students::ofDiscipline($id); $stdHandled = array(); $attachStdHandled = array(); $groupID = 0; $i = 0; $k = 0; + $n = 0; + $j = 0; foreach($students as $row) { - if ($row['Type'] == 'attach'){ + if ($row['AttachType'] == 'attach'){ if ($row['GroupID'] != $groupID) { $groupID = $row['GroupID']; $k++; @@ -85,14 +85,14 @@ class Controller_Teacher_Discipline extends Controller_UserEnvi { $attachStdHandled[$k]['GradeID'] = $row['GradeID']; $attachStdHandled[$k]['GradeNum'] = $row['GradeNum']; $attachStdHandled[$k]['GroupNum'] = $row['GroupNum']; - $attachStdHandled[$k]['Degree'] = DataArray::factory('Students')->getDegreeTitle($row['Degree']); + $attachStdHandled[$k]['Degree'] = Model_Grades::getDegreeTitle($row['Degree']); } $n++; $attachStdHandled[$k]['students'][$n]['ID'] = $row['ID']; - $attachStdHandled[$k]['students'][$n]['Last'] = $row['Last']; - $attachStdHandled[$k]['students'][$n]['First'] = $row['First']; - $attachStdHandled[$k]['students'][$n]['Second'] = $row['Second']; - $attachStdHandled[$k]['students'][$n]['Type'] = $row['Type']; + $attachStdHandled[$k]['students'][$n]['LastName'] = $row['LastName']; + $attachStdHandled[$k]['students'][$n]['FirstName'] = $row['FirstName']; + $attachStdHandled[$k]['students'][$n]['SecondName'] = $row['SecondName']; + $attachStdHandled[$k]['students'][$n]['AttachType'] = $row['AttachType']; // $k++; // $attachStdHandled['StdCount'] += 1; @@ -117,14 +117,14 @@ class Controller_Teacher_Discipline extends Controller_UserEnvi { $stdHandled[$i]['GradeID'] = $row['GradeID']; $stdHandled[$i]['GradeNum'] = $row['GradeNum']; $stdHandled[$i]['GroupNum'] = $row['GroupNum']; - $stdHandled[$i]['Degree'] = DataArray::factory('Students')->getDegreeTitle($row['Degree']); + $stdHandled[$i]['Degree'] = Model_Grades::getDegreeTitle($row['Degree']); } $j++; $stdHandled[$i]['students'][$j]['ID'] = $row['ID']; - $stdHandled[$i]['students'][$j]['Last'] = $row['Last']; - $stdHandled[$i]['students'][$j]['First'] = $row['First']; - $stdHandled[$i]['students'][$j]['Second'] = $row['Second']; - $stdHandled[$i]['students'][$j]['Type'] = $row['Type']; + $stdHandled[$i]['students'][$j]['LastName'] = $row['LastName']; + $stdHandled[$i]['students'][$j]['FirstName'] = $row['FirstName']; + $stdHandled[$i]['students'][$j]['SecondName'] = $row['SecondName']; + $stdHandled[$i]['students'][$j]['AttachType'] = $row['AttachType']; } } @@ -137,21 +137,21 @@ class Controller_Teacher_Discipline extends Controller_UserEnvi { public function action_EditTeachers() { $id = $this->request->param('id'); - $db = new Model_Teacher_Map; + $db = new Model_Map; $twig = Twig::factory('teacher/discipline/EditTeachers'); - $twig->User = $this->UserInfo; - $twig->Discipline = $this->getDisciplineInfo($db, $id); - $twig->BindTeachersList = DataArray::factory('Teachers')->forDiscipline($id)->asArray(); - $twig->FacultiesList = DataArray::factory('Faculties')->common()->asArray(); - $twig->Departments = DataArray::factory('Departments')->byFaculty($this->UserInfo['FacultyID'])->asArray(); + $twig->User = $this->user; + $twig->Discipline = $this->getDisciplineInfo($id); + $twig->BindTeachersList = Model_Teachers::forDiscipline($id); + $twig->FacultiesList = Model_Faculties::toArray(); + $twig->Departments = Model_Departments::byFaculty($this->user['FacultyID']); $this->response->body($twig); } private function GetMapInfo($map) { $mapHandled = array(); - + $maxRate = 0; $i = 0; $module = 0; foreach($map as $row) { @@ -173,19 +173,19 @@ class Controller_Teacher_Discipline extends Controller_UserEnvi { $mapHandled[$i]['SubmodulesCount'] = 0; $mapHandled[$i]['MaxRate'] = 0; } - $mapHandled[$i]['isExam'] = $row['isExam']; + $mapHandled[$i]['IsExam'] = $row['IsExam']; $j = $mapHandled[$i]['SubmodulesCount'] += 1; $mapHandled[$i]['MaxRate'] += (int) $row['MaxRate']; $mapHandled[$i]['ModuleTitle'] = $row['ModuleName']; $mapHandled[$i][$j]['SubmoduleID'] = $row['SubmoduleID']; - $mapHandled[$i][$j]['Title'] = $row['SubModuleName']; + $mapHandled[$i][$j]['Title'] = $row['SubmoduleName']; $mapHandled[$i][$j]['Description'] = $row['SubmoduleDescription']; - $mapHandled[$i][$j]['SubmoduleControl'] = $row['SubmoduleControl']; + $mapHandled[$i][$j]['SubmoduleControl'] = $row['SubmoduleType']; $mapHandled[$i][$j]['MaxRate'] = (int) $row['MaxRate']; $maxRate += $row['MaxRate']; - if ($row['SubmoduleControl'] == 'CurrentControl') + if ($row['SubmoduleType'] == 'CurrentControl') $mapHandled[$i]['CurrentControl'] += (int) $row['MaxRate']; - if ($row['SubmoduleControl'] == 'LandmarkControl') + if ($row['SubmoduleType'] == 'LandmarkControl') $mapHandled[$i]['LandmarkControl'] += (int) $row['MaxRate']; } $mapHandled['ModulesCount'] = $i; @@ -196,56 +196,32 @@ class Controller_Teacher_Discipline extends Controller_UserEnvi { return $mapHandled; } - public function GetDisciplineInfo($db, $id) + public function GetDisciplineInfo($id) { - $info = $db->getDisciplineInfoByID($id); - - if($info->count() == 0) - throw HTTP_Exception::factory(404, "Учебная карта дисциплины СЃ ID $id РЅРµ найдена!"); - else - $info = $info->offsetGet(0); - - $subject['AuthorID'] = $info['AuthorID']; - if($this->UserInfo['TeacherID'] != $subject['AuthorID']) + $discipline = Model_Discipline::getInfo($id); + if ($this->user['TeacherID'] != $discipline['AuthorID']) throw HTTP_Exception::factory(403, "Недостаточно прав для редактирования."); - - $subject['DisciplineID'] = $id; - $subject['DepID'] = $info['DepID']; - $subject['FacultyID'] = $info['FacultyID']; - $subject['FacultyName'] = $info['FacultyName']; - $subject['isLocked'] = $info['isLocked']; - $subject['isBonus'] = $info['isBonus']; - - $subject['SemesterID'] = $info['SemesterID']; - $semester = DataArray::factory('Semesters')->bySemester($subject['SemesterID'])->asArray(); - $subject['SemesterNum'] = $semester['SemesterNum'] == 1 ? 'Осенний' : 'Весенний'; - $subject['SemesterYear'] = $semester['SemesterYear']; - - $teachers = DataArray::factory('Teachers')->forDiscipline($id)->asArray(); - - $subject['SubjectName'] = $info['SubjectName']; - $subject['SubjectID'] = $info['SubjectID']; - $subject['ExamType'] = $info['ExamType']; - - $subject['LectureHours'] = $info['LectionCount']; - $subject['PracticeHours'] = $info['PracticeCount']; - $subject['LabHours'] = $info['LabCount']; - $subject['GradeID'] = $info['GradeID']; - - $teachersHandled = array(); $i = 0; - + + $semester = Model_Semesters::getInfo($discipline['SemesterID']); + $discipline['SemesterNum'] = $semester['SemesterNum'] == 1 ? 'Осенний' : 'Весенний'; + $discipline['SemesterYear'] = $semester['SemesterYear']; + + $discipline['LectureHours'] = $discipline['LectureCount']; + $discipline['PracticeHours'] = $discipline['PracticeCount']; + $discipline['LabHours'] = $discipline['LabCount']; + + $teachers = Model_Teachers::forDiscipline($id); + + $list = array(); foreach ($teachers as $row) { - $teachersHandled[$i] = $row['Last'].' '.$row['First'].''; - if(!empty($row['Second'])) - { - $teachersHandled[$i] .= ' '.$row['Second']; - } - $i++; + $name = $row['LastName'] . ' ' . $row['FirstName']; + if (!empty($row['SecondName'])) + $name .= ' ' . $row['SecondName']; + $list[] = $name; } - $subject['Teachers'] = implode(', ', $teachersHandled); + $discipline['Teachers'] = implode(', ', $list); - return $subject; + return $discipline; } - } \ No newline at end of file diff --git a/~dev_rating/application/classes/Controller/Teacher/Index.php b/~dev_rating/application/classes/Controller/Teacher/Index.php index 694e094e4d233264cd5c880913314396383290de..1456a0c1d9ff20d0654745f83013dfff28814d9e 100644 --- a/~dev_rating/application/classes/Controller/Teacher/Index.php +++ b/~dev_rating/application/classes/Controller/Teacher/Index.php @@ -1,17 +1,16 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Teacher_Index extends Controller_UserEnvi { +class Controller_Teacher_Index extends Controller_UserEnvironment { public function action_index() { $twig = Twig::factory('teacher/index'); - - $model = new Model_Teacher_Index; - $disciplines = $model->getDisciplinesForTeacher($this->UserInfo['TeacherID']); + + $disciplines = Model_Disciplines::ofTeacher($this->user['TeacherID']); $subjID = $discID = $gradeNum = $i = $j = $k = 0; // Combo!!! $disciplinesHandled = array(); $groupsInDiscipline = array(); - $degrees = array('bachelor' => 'Бакалавриат', 'specialist' => 'Специалитет', 'master' => 'Магистратура'); + foreach ($disciplines as $row) { if($subjID != $row['SubjectID'] || $gradeNum != $row['GradeID']) { @@ -20,8 +19,8 @@ class Controller_Teacher_Index extends Controller_UserEnvi { $subjID = $row['SubjectID']; $gradeNum = $row['GradeID']; $disciplinesHandled[$i]['Title'] = $row['SubjectName']; - $disciplinesHandled[$i]['GradeNum'] = $row['GradeNum']; - $disciplinesHandled[$i]['Degree'] = $degrees[$row['Degree']]; + $disciplinesHandled[$i]['GradeNum'] = $row['GradeNum']; + $disciplinesHandled[$i]['Degree'] = Model_Grades::getDegreeTitle($row['Degree']); } @@ -29,9 +28,9 @@ class Controller_Teacher_Index extends Controller_UserEnvi { { $j++; $k = 0; $groupsInDiscipline = array(); - $disciplinesHandled[$i]['Disciplines'][$j]['isAuthor'] = $row['isAuthor']; - $disciplinesHandled[$i]['Disciplines'][$j]['isLocked'] = $row['isLocked']; - $disciplinesHandled[$i]['Disciplines'][$j]['isMapCreated'] = $row['isMapCreated']; + $disciplinesHandled[$i]['Disciplines'][$j]['IsAuthor'] = $row['IsAuthor']; + $disciplinesHandled[$i]['Disciplines'][$j]['IsLocked'] = $row['IsLocked']; + $disciplinesHandled[$i]['Disciplines'][$j]['IsMapCreated'] = $row['IsMapCreated']; $disciplinesHandled[$i]['Disciplines'][$j]['ID'] = $discID = $row['ID']; $disciplinesHandled[$i]['Disciplines'][$j]['ControlType'] = $this->getControlType($row['ExamType']); $disciplinesHandled[$i]['Disciplines'][$j]['Teachers'] = $this->getTeachersForDiscipline($discID); @@ -41,15 +40,15 @@ class Controller_Teacher_Index extends Controller_UserEnvi { $disciplinesHandled[$i]['Disciplines'][$j]['Groups'] = implode(', ', $groupsInDiscipline); } //!for_each $twig->Subjects = $disciplinesHandled; - $twig->SemesterList = DataArray::factory('Semesters')->getList(); + $twig->SemesterList = Model_Semesters::toArray(); $twig->Semester = $this->SemesterInfo; - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } public function action_settings() { $twig = Twig::factory('settings'); - $twig->User = $this->UserInfo; + $twig->User = $this->user; $this->response->body($twig); } @@ -66,16 +65,15 @@ class Controller_Teacher_Index extends Controller_UserEnvi { } protected function getTeachersForDiscipline($id) { - $model = new Model_Teacher_Index; - $teachers = $model->getTeachersForDiscipline($id); + $teachers = Model_Teachers::ofDiscipline($id); $teachersHandled = array(); $i = 0; foreach ($teachers as $teacher) { $i++; - $teachersHandled[$i] = $teacher['Last'].' '.UTF8::substr($teacher['First'], 0, 1).'. '; - if(!empty($teacher['Second'])) + $teachersHandled[$i] = $teacher['LastName'].' '.UTF8::substr($teacher['FirstName'], 0, 1).'. '; + if(!empty($teacher['SecondName'])) { - $teachersHandled[$i] .= UTF8::substr($teacher['Second'], 0, 1).'.'; + $teachersHandled[$i] .= UTF8::substr($teacher['SecondName'], 0, 1).'.'; } } return $teachersHandled; diff --git a/~dev_rating/application/classes/Controller/Teacher/Profile.php b/~dev_rating/application/classes/Controller/Teacher/Profile.php index 73c687819f0f8ff51e06ce5abbd0ae1205f76ff5..af79ecf33dfd3a72bb665b23dac6d16b6de74500 100644 --- a/~dev_rating/application/classes/Controller/Teacher/Profile.php +++ b/~dev_rating/application/classes/Controller/Teacher/Profile.php @@ -1,20 +1,19 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Teacher_Profile extends Controller_UserEnvi { +class Controller_Teacher_Profile extends Controller_UserEnvironment { public function action_edit() { $twig = Twig::factory('profile/settings'); $twig->JobPositions = $this->getJobPositions(); $twig->Faculties = $this->getFaculties(); - $twig->Departments = DataArray::factory('Departments')->byFaculty($this->UserInfo['FacultyID'])->asArray(); - $twig->User = $this->UserInfo; + $twig->Departments = Model_Departments::byFaculty($this->user->FacultyID); + $twig->User = $this->user; $this->response->body($twig); } public function getFaculties() { - $model = new Model_Admin_Teachers; - $faculties = $model->getFaculties(); + $faculties = Model_Teachers::getFaculties(); $facultiesHandled = array(); $i = 0; foreach($faculties as $row) { @@ -25,11 +24,11 @@ class Controller_Teacher_Profile extends Controller_UserEnvi { } return $facultiesHandled; } - + + // todo: move to teachers model, there's a duplicate at admin/teachers.php public function getJobPositions() { - $model = new Model_Admin_Teachers; - $jobPositions = $model->getJobPositions(); + $jobPositions = Model_Teachers::getJobPositions(); $jobPositionsHandled = array(); $i = 0; foreach($jobPositions as $row) { diff --git a/~dev_rating/application/classes/Controller/Teacher/Rating.php b/~dev_rating/application/classes/Controller/Teacher/Rating.php index 29f107b7e33bb47f88b36e3146c4fa7e0fac6b61..1be52f96d0d2c6a6c45114345b029d57c4c994d0 100644 --- a/~dev_rating/application/classes/Controller/Teacher/Rating.php +++ b/~dev_rating/application/classes/Controller/Teacher/Rating.php @@ -1,18 +1,22 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Controller_Teacher_Rating extends Controller_UserEnvi { +class Controller_Teacher_Rating extends Controller_UserEnvironment { + /** @var Model_Rating */ protected $model_rating; + /** @var Model_Map */ + protected $model_discipline; + public function before() { Cookie::set('fD', 'true'); // Ставим РєСѓРє fD, чтоб иметь возможность скачать отчет TODO - $this->model_rating = new Model_Teacher_Rating; - $this->model_discipline = new Model_Teacher_Map; + $this->model_rating = new Model_Rating; + $this->model_discipline = new Model_Map; parent::before(); } // Получить РёР· РєСѓРєР° SGID выбранную ранее РіСЂСѓРїРїСѓ для данной дисциплины - private function getStudyGroupID_ForFilter($id) { + private function getGroupID_ForFilter($id) { # $id = disciplineID $SG_array = json_decode(Cookie::get('SGID', null), true); if ($SG_array !== null && array_key_exists($id, $SG_array)) { @@ -24,10 +28,10 @@ class Controller_Teacher_Rating extends Controller_UserEnvi { // Настройки дисциплины Рё выбранная РіСЂСѓРїРїР°(для фильтра) private function getDisciplineInformation($id) { - $temp = $this->model_discipline->getDisciplineInfoByID($id); - $disciplineInfo = $temp[0]; - $disciplineInfo['ID'] = $id; - $disciplineInfo['StudyGroupID_Filter'] = $this->getStudyGroupID_ForFilter($id); + $temp = Model_Discipline::getInfo($id); + $disciplineInfo = $temp; +// $disciplineInfo['ID'] = $id; + $disciplineInfo['GroupID_Filter'] = $this->getGroupID_ForFilter($id); return $disciplineInfo; } @@ -35,11 +39,11 @@ class Controller_Teacher_Rating extends Controller_UserEnvi { // Шапка таблицы: структура РЈРљР” (модули Рё мероприятия) private function getStructure($id, $type) { - $teacherID = $this->UserInfo['TeacherID']; + $teacherID = $this->user['TeacherID']; if ($type == "rating") { - $structure = $this->model_rating->getMapForDiscipline($teacherID, $id); + $structure = $this->model_rating->getMapForDiscipline($id); } else { - $structure = $this->model_rating->GetMapForDisciplineExam($teacherID, $id); + $structure = $this->model_rating->GetMapForDisciplineExam($id); } if($structure->count() == 0) { throw HTTP_Exception::factory (404, "Страница РЅРµ найдена"); @@ -70,7 +74,7 @@ class Controller_Teacher_Rating extends Controller_UserEnvi { $cur_submodule['MaxRate'] = (int)$cur_submodule['MaxRate']; if ($type == "rating") { - $cur_submodule['Title'] = $row['SubModuleName']; + $cur_submodule['Title'] = $row['SubmoduleName']; $maxRate += $row['MaxRate']; } else { //$type == "exam" if ($row['ModuleType'] == 'extra') { @@ -232,7 +236,7 @@ class Controller_Teacher_Rating extends Controller_UserEnvi { $this->correctExtra($curStudent, $examType, $lastExtraIndex, $firstEmptyExtra, $rateExtra); } - protected function get_edit_rights_for_teacher($teacherID, $disciplineID) // $this->UserInfo['TeacherID']=id + protected function get_edit_rights_for_teacher($teacherID, $disciplineID) // $this->user['TeacherID']=id { $sql = "SELECT `GetEditRightsForTeacher`('$teacherID', '$disciplineID') AS `Num`;";//"CALL `GetEditRightsForTeacher`('$teacherID', '$disciplineID'); "; $res = DB::query(Database::SELECT, $sql)->execute(); @@ -248,7 +252,9 @@ class Controller_Teacher_Rating extends Controller_UserEnvi { $structureHandled = $this->getStructure($disciplineId, $page_type); // Студенты Рё РёС… баллы - $students = $this->model_rating->GetStudentsForRating($this->UserInfo['TeacherID'], $disciplineId); + $students = $this->model_rating->GetStudentsForRating($disciplineId); + + $rateHandled = array(); $groupsHandled = array(); $i_g = $i_s = $curGroup = 0; @@ -269,7 +275,7 @@ class Controller_Teacher_Rating extends Controller_UserEnvi { // Баллы студента if ($page_type == "rating") { - $rates_raw = $this->model_rating->getMapForStudent($row['ID'], $disciplineId); + $rates_raw = Model_Rating::getRates($disciplineId, $row['ID']); $rates = $this->getRatesForRatingPage($rates_raw); $curStudent['RateResult'] = $rates['RateResult']; unset($rates['RateResult']); @@ -277,21 +283,21 @@ class Controller_Teacher_Rating extends Controller_UserEnvi { $rateHandled[$i_g]['Students'][$i_s] = $curStudent; } else { - $rate = $this->model_rating->getMapForStudentExam($row['ID'], $disciplineId); + $rate = Model_Rating::getExamRates($disciplineId, $row['ID']); $this->getRatesForExamPage($curStudent, $rate, $disciplineInfo['ExamType'], $disciplineId); $rateHandled[$i_g]['Students'][$i_s] = $curStudent; } $i_s++; } - $editRights=$this->get_edit_rights_for_teacher($this->UserInfo['TeacherID'], $disciplineInfo['ID']); + $editRights=$this->get_edit_rights_for_teacher($this->user['TeacherID'], $disciplineInfo['ID']); if($editRights == 1) $twig->editRights=$editRights; else $twig->editRights=0; // РќР° вывод - $twig->User = $this->UserInfo; + $twig->User = $this->user; $twig->headerRate = $structureHandled; // Шапка таблицы: структура РЈРљР” (модули Рё мероприятия) $twig->rateTable = $rateHandled; $twig->groups = $groupsHandled; diff --git a/~dev_rating/application/classes/Controller/UserEnvi.php b/~dev_rating/application/classes/Controller/UserEnvi.php deleted file mode 100644 index 86760fdfd3db6147de4268312b5f54210b90da97..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Controller/UserEnvi.php +++ /dev/null @@ -1,79 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Controller_UserEnvi extends Controller { - protected $UserInfo; - protected $SemesterInfo; - protected static $degrees = array( 'bachelor' => 'Бакалавриат', - 'specialist' => 'Специалитет', - 'master' => 'Магистратура'); - - - public function before() - { - $user = User::instance(); - if(!$user->isSignedIn()) { - $this->redirect('sign', 302); - return; - } - $this->UserInfo = $user->getInfoAsArray(); - - $db = new Model_Student; - $semester = $db->getSemesterInfo($this->UserInfo['SemesterID']); - // $semester['Num'] = $semester['Num'] == 1 ? 'Осень' : 'Весна'; - if($semester['Num'] == 1) - { - $semester['Num'] = 'Осень'; - } - else - { - $semester['Num'] = 'Весна'; - $semester['Year']++; - } - $this->SemesterInfo = $semester; - - if($this->UserInfo['Type'] == 'student') { - //unified degree from db - $uniDegree = $this->UserInfo['Degree']; - $this->UserInfo['Degree'] = self::$degrees[$uniDegree]; - } - // Проверка РЅР° доступ Рє странице - $route = Route::name($this->request->route()); - $userMark = $user->offsetGet('RoleMark'); - $sysModel = new Model_System; - $bitmask = (int)$sysModel->getBitmaskForRoute($route); - if ($bitmask === 0) { - $bitmask = (int)1; - } - if ($userMark === 0) { - $userMark = (int)1; - } - if(!($bitmask & $userMark)) { - throw HTTP_Exception::factory(403, - 'РќРµ пытайтесь попасть туда, РєСѓРґР° попадать РЅРµ следует.'); - } - } - - public function action_index() - { - $type = $this->UserInfo['Type']; - $page = Request::factory($type.'/index')->execute(); - $this->response->body($page); - } - - public function action_profile() - { - if($this->UserInfo['Type'] != 'teacher') { - $this->redirect('/', 302); - } else { - $url = "teacher/profile"; - $page = Request::factory($url)->execute(); - $this->response->body($page); - } - } - - public function action_settings() - { - $page = Request::factory($this->UserInfo['Type'].'/settings')->execute(); - $this->response->body($page); - } -} diff --git a/~dev_rating/application/classes/Controller/UserEnvironment.php b/~dev_rating/application/classes/Controller/UserEnvironment.php new file mode 100644 index 0000000000000000000000000000000000000000..15a36c660648f079f5adfa6513454aab0f27b0df --- /dev/null +++ b/~dev_rating/application/classes/Controller/UserEnvironment.php @@ -0,0 +1,68 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Controller_UserEnvironment extends Controller +{ + protected $SemesterInfo; + + /** @var User */ + protected $user; + + public function before() { + $this->user = User::instance(); + if (!$this->user->isSignedIn()) { + $this->redirect('sign', 302); + return; + } + + $semester = Model_Semesters::getInfo($this->user->SemesterID); + // $semester['Num'] = $semester['Num'] == 1 ? 'Осень' : 'Весна'; + if ($semester['Num'] == 1) { + $semester['Num'] = 'Осень'; + } else { + $semester['Num'] = 'Весна'; + $semester['Year']++; + } + $this->SemesterInfo = $semester; + + if ($this->user->Type == 'student') { + //unified degree from db + $uniDegree = $this->user['Degree']; + $this->user['Degree'] = Model_Grades::getDegreeTitle($uniDegree); + } + // Проверка РЅР° доступ Рє странице + $route = Route::name($this->request->route()); + $userMark = $this->user->RoleMark; + $sysModel = new Model_System; + $bitmask = (int)$sysModel->getBitmaskForRoute($route); + if ($bitmask === 0) { + $bitmask = (int)1; + } + if ($userMark === 0) { + $userMark = (int)1; + } + if (!($bitmask & $userMark)) { + throw HTTP_Exception::factory(403, 'РќРµ пытайтесь попасть туда, РєСѓРґР° попадать РЅРµ следует.'); + } + } + + public function action_index() { + $type = $this->user->Type; + $page = Request::factory($type . '/index')->execute(); + $this->response->body($page); + } + + public function action_profile() { + if ($this->user->Type != 'teacher') { + $this->redirect('/', 302); + } else { + $url = "teacher/profile"; + $page = Request::factory($url)->execute(); + $this->response->body($page); + } + } + + public function action_settings() { + $page = Request::factory($this->user->Type . '/settings')->execute(); + $this->response->body($page); + } +} diff --git a/~dev_rating/application/classes/Controller/Window.php b/~dev_rating/application/classes/Controller/Window.php index c3f1fcb4228f704f0fdb6c8054e4302b31b7fdce..a3df0b2cfede3eb6284cee8354749cceaf270e46 100644 --- a/~dev_rating/application/classes/Controller/Window.php +++ b/~dev_rating/application/classes/Controller/Window.php @@ -1,31 +1,30 @@ <?php defined('SYSPATH') or die('No direct script access.'); - -class Controller_Window extends Controller { - protected $user; - public function before() - { +class Controller_Window extends Controller +{ + private $user; + + public function before() { $user = User::instance(); - if($user->isSignedIn()) - { - $this->user = $user->getInfoAsArray(); - } + //if ($user->isSignedIn()) { + // $this->user = $user->toArray(); + //} } - public function action_get() - { + public function action_get() { $path = UTF8::str_ireplace(':', '/', $this->request->param('id')); - if(Kohana::find_file('views/popup', $path, 'twig')) - { - $twig = Twig::factory('popup/'.$path); + if (Kohana::find_file('views/popup', $path, 'twig')) { + $twig = Twig::factory('popup/' . $path); $twig->User = $this->user; $arr = explode('||', $twig->render()); - $json = json_encode(array('title' => $arr[0], 'width' => $arr[1], 'top' => $arr[2], 'content' => $arr[3])); + $json = json_encode(array( + 'title' => $arr[0], + 'width' => $arr[1], + 'top' => $arr[2], + 'content' => $arr[3])); $this->response->body($json); - } - else - { - throw HTTP_Exception::factory (404, "Рскомый шаблон $path РЅРµ найден"); + } else { + throw HTTP_Exception::factory(404, "Рскомый шаблон $path РЅРµ найден"); } } } diff --git a/~dev_rating/application/classes/DataArr/Departments.php b/~dev_rating/application/classes/DataArr/Departments.php deleted file mode 100644 index ca529798b7cd53985b32ffaa506468f78405559f..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/Departments.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -class DataArr_Departments { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_Departments; - } - - public function byFaculty($facultyID) - { - if($facultyID != 0) - { - $departaments = $this->model->getDepartmentsByFaculty($facultyID); - $departamentsHandled = array(); $i = 0; - foreach($departaments as $row) - { - $i++; - $departamentsHandled[$i]['ID'] = $row['ID']; - if($row['Name'] != null) - { - $departamentsHandled[$i]['Name'] = $row['Name']; - } - else { - $departamentsHandled[$i]['Name'] = '<служебная кафедра>'; - } - } - return new DataArray_Result($departamentsHandled); - } - } - -} diff --git a/~dev_rating/application/classes/DataArr/Disciplines.php b/~dev_rating/application/classes/DataArr/Disciplines.php deleted file mode 100644 index 61d8fbedd37cb8c94ffb99973689df0aa2c0e4fe..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/Disciplines.php +++ /dev/null @@ -1,28 +0,0 @@ -<?php - -class DataArr_Disciplines { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_Disciplines; - } - - public function forGroup($GroupID) { - $teacherModel = new Model_Teacher_Rating; - $Disciplines = $teacherModel->getDisciplinesForGroup($GroupID); - - $DisciplinesHandled = array(); - $i = 0; - - foreach($Disciplines as $row) { - $i++; - $DisciplinesHandled[$i]['DisciplineID'] = $row['DisciplineID']; - $DisciplinesHandled[$i]['SubjectName'] = $row['SubjectName']; - $DisciplinesHandled[$i]['ExamType'] = $row['ExamType']; - } - - return new DataArray_Result($DisciplinesHandled); - } - - // TODO: Методы для получения СЃРїРёСЃРєР° дисциплин -} \ No newline at end of file diff --git a/~dev_rating/application/classes/DataArr/Faculties.php b/~dev_rating/application/classes/DataArr/Faculties.php deleted file mode 100644 index 9e9c4bb8c781d667bc8f472882621471d5a95637..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/Faculties.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php - -class DataArr_Faculties { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_Faculties; - } - - public function common() { - $list = $this->model->GetFaculties(); - - $FacList = array(); $i = 0; - - foreach ($list as $row) { - $i++; - $FacList[$i]['ID'] = $row['ID']; - $FacList[$i]['Name'] = $row['Name']; - $FacList[$i]['Abbr'] = $row['Abbr']; - } - - return new DataArray_Result($FacList); - } - - // TODO: Метод для получения факультетов -} \ No newline at end of file diff --git a/~dev_rating/application/classes/DataArr/Grades.php b/~dev_rating/application/classes/DataArr/Grades.php deleted file mode 100644 index bfbb21ec29100dd3aaa954fd986b2650c5a38aa3..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/Grades.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php - -class DataArr_Grades { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_Grades; - } - - public function common() { - $GradeList = $this->model->GetGrades(); - $Grade = array(); $i = 0; - - foreach ($GradeList as $row){ - $i++; - $Grade[$i]['ID'] = $row['ID']; - $Grade[$i]['Num'] = $row['Num']; - $Grade[$i]['Degree'] = $row['Degree']; - if ($row['Degree'] == 'bachelor' || $row['Degree'] == 'specialist') - $Grade[$i]['Title'] = 'РљСѓСЂСЃ '.$row['Num']; - if ($row['Degree'] == 'master') - $Grade[$i]['Title'] = 'Магистратура '.$row['Num']; - } - - return new DataArray_Result($Grade); - } - - public function structured() { - $grades = DataArray::factory('Grades')->common()->asArray(); - $gradesHandled = array(); $i = $j = 0; $degree = 'null'; - $degrees = array('bachelor' => 'Бакалавриат', 'specialist' => 'Специалитет', 'master' => 'Магистратура'); - foreach($grades as $row) - { - if($degree != $row['Degree']) - { - $degree = $row['Degree'] ; - $i++; $j = 0; - } - $j++; - $gradesHandled[$i]['Title'] = $degrees[$row['Degree']]; - $gradesHandled[$i]['Grades'][$j]['ID'] = $row['ID']; - $gradesHandled[$i]['Grades'][$j]['Num'] = $row['Num']; - } - return new DataArray_Result($gradesHandled); - } - -} diff --git a/~dev_rating/application/classes/DataArr/JobPositions.php b/~dev_rating/application/classes/DataArr/JobPositions.php deleted file mode 100644 index 9439c630be14e75cfdb4aa6dc5df3893f0b3deb3..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/JobPositions.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php - -class DataArr_JobPositions { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_JobPositions; - } - - // TODO: Метод для получения должностных позиций -} diff --git a/~dev_rating/application/classes/DataArr/Semesters.php b/~dev_rating/application/classes/DataArr/Semesters.php deleted file mode 100644 index 80a8f7491ebd1d95b476d6e3e916d2d34f4b15e7..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/Semesters.php +++ /dev/null @@ -1,27 +0,0 @@ -<?php - -class DataArr_Semesters { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_Semesters; - } - - public function bySemester($SemesterID){ - $departaments = $this->model->getSemesterInfo($SemesterID); - return new DataArray_Result($departamentsHandled); - } - - public function getList() - { - $semesters = $this->model->getSemesters(); - $semestersHandled = array(); $i = 0; - foreach($semesters as $value) - { - $semestersHandled[$i] = $value; - $semestersHandled[$i]['Num'] = $value['Num'] == 1 ? 'Осенний' : 'Весенний'; - $i++; - } - return $semestersHandled; - } -} diff --git a/~dev_rating/application/classes/DataArr/Specializations.php b/~dev_rating/application/classes/DataArr/Specializations.php deleted file mode 100644 index 3a8374c35e65c1766c7f5fe1c6015109c28807c3..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/Specializations.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php - -class DataArr_Specializations { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_Specializations; - } - - // TODO: Метод для получения СЃРїРёСЃРєР° специализаций -} \ No newline at end of file diff --git a/~dev_rating/application/classes/DataArr/Students.php b/~dev_rating/application/classes/DataArr/Students.php deleted file mode 100644 index fae81e5447690c607939be37b9c053095997b29b..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/Students.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php - -/* -attach - прикреплен -detach - откреплен -NULL - РІ РѕСЃРЅРѕРІРЅРѕР№ РіСЂСѓРїРїРµ -*/ - -class DataArr_Students { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_Students; - } - - public function byStudyGroup($groupID) - { - $students = $this->model->getStudentsByStudyGroups($groupID); - return new DataArray_Result($this->generateArray($students)); - } - - public function byFaculty($facultyID, $gradeID, $groupID) - { - $students = $this->model->getStudentsByFaculty($facultyID, $gradeID, $groupID); - return new DataArray_Result($this->generateArray($students)); - } - - public function byGrade($gradeID) - { - $students = $this->model->getStudentsByGrade($gradeID); - return new DataArray_Result($this->generateArray($students)); - } - - public function getDegreeTitle($degree) - { - switch($degree) - { - case 'bachelor': - { - return 'Бакалавриат'; - } - case 'specialist': - { - return 'Специалитет'; - } - case 'master': - { - return 'Магистратура'; - } - - } - } - - protected function generateArray($students) - { - $studentsHandled = array(); $i = 0; - foreach($students as $row) - { - $i++; - $studentsHandled[$i]['ID'] = $row['ID']; - $studentsHandled[$i]['AccountID'] = $row['AccountID']; - $studentsHandled[$i]['LastName'] = $row['Last']; - $studentsHandled[$i]['FirstName'] = $row['First']; - $studentsHandled[$i]['SecondName'] = $row['Second']; - $studentsHandled[$i]['GroupID'] = $row['GroupID']; - $studentsHandled[$i]['GroupNum'] = $row['GroupNum']; - $studentsHandled[$i]['GradeID'] = $row['GradeID']; // ID РєСѓСЂСЃР° - $studentsHandled[$i]['GradeNum'] = $row['GradeNum']; // НОМЕРкурса, Р° РЅРµ ID... ID почти всегда <> НОМЕРУ РєСѓСЂСЃР° - $studentsHandled[$i]['Degree'] = $this->getDegreeTitle($row['Degree']); - $studentsHandled[$i]['Type'] = $row['Type']; - } - return $studentsHandled; - } - - public function NotAttendingDiscipline($GradeID, $GroupID, $FacultyID, $Name, $DisciplineID) - { - $students = $this->model->SearchStudents($GradeID, $GroupID, $FacultyID, $Name, $DisciplineID); - return new DataArray_Result($this->generateArray($students)); - } -} diff --git a/~dev_rating/application/classes/DataArr/StudyGroups.php b/~dev_rating/application/classes/DataArr/StudyGroups.php deleted file mode 100644 index 1932720d9ead6750c2380debc2089116663b9642..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/StudyGroups.php +++ /dev/null @@ -1,46 +0,0 @@ -<?php - -class DataArr_StudyGroups { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_StudyGroups; - } - - public function forDiscipline($DisciplineID) { - $Groups = $this->model->getStudyGroupsForDiscipline($DisciplineID); - - $GroupsHandled = array(); - $i = 0; - - foreach($Groups as $row) { - $i++; - $GroupsHandled[$i]['ID'] = $row['ID']; - $GroupsHandled[$i]['GradeNum'] = $row['GradeNum']; - $GroupsHandled[$i]['GroupNum'] = $row['GroupNum']; - $GroupsHandled[$i]['SpecName'] = $row['SpecName']; - $GroupsHandled[$i]['SpecAbbr'] = $row['SpecAbbr']; - } - - return new DataArray_Result($GroupsHandled); - } - - public function ordByGroups($GradeID, $FacultyID) { - $Groups = $this->model->getStudyGroups($GradeID, $FacultyID); - $GroupsHandled = array(); - $i = 0; - - foreach($Groups as $row) { - $i++; - $GroupsHandled[$i]['ID'] = $row['ID']; - $GroupsHandled[$i]['GroupNum'] = $row['GroupNum']; - $GroupsHandled[$i]['SpecID'] = $row['SpecID']; - $GroupsHandled[$i]['SpecName'] = $row['SpecName']; - $GroupsHandled[$i]['SpecAbbr'] = $row['SpecAbbr']; - } - - return new DataArray_Result($GroupsHandled); - } - - // TODO: Методы для получения СЃРїРёСЃРєР° учебных РіСЂСѓРїРї -} \ No newline at end of file diff --git a/~dev_rating/application/classes/DataArr/Subjects.php b/~dev_rating/application/classes/DataArr/Subjects.php deleted file mode 100644 index 6e607aa925eb276fe8368527d5073ad874553aaa..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/Subjects.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php - -class DataArr_Subjects { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_Subjects; - } - - public function byFaculty($FacultyID) { - - $list = $this->model->getSubjects($FacultyID); - - $SubjectsList = array(); $i = 0; - - foreach ($list as $row) { - $i++; - $SubjectsList[$i]['ID'] = $row['ID']; - $SubjectsList[$i]['Title'] = $row['Name']; - $SubjectsList[$i]['Abbr'] = $row['Abbr']; - } - - return new DataArray_Result($SubjectsList); - } - -} diff --git a/~dev_rating/application/classes/DataArr/Teachers.php b/~dev_rating/application/classes/DataArr/Teachers.php deleted file mode 100644 index 3bd07b6426bcad0d652fd7aa12fb3927f1a4346a..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/Teachers.php +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -class DataArr_Teachers { - - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_Teachers; - } - - public function byFaculty($facultyID) - { - if($facultyID != 0) - { - $teachers = $this->model->getTeachersByFaculty($facultyID); - $i = 0; - foreach($teachers as $row) - { - $i++; - $teachersHandled[$i]['ID'] = $row['ID']; - $teachersHandled[$i]['AccountID'] = $row['AccountID']; - $teachersHandled[$i]['First'] = $row['First']; - $teachersHandled[$i]['Second'] = $row['Second']; - $teachersHandled[$i]['Last'] = $row['Last']; - $teachersHandled[$i]['JobPositionName'] = $row['JobPositionName']; - $teachersHandled[$i]['DepartmentID'] = $row['DepID']; - $teachersHandled[$i]['DepartmentName'] = $row['DepName']; - } - } - return new DataArray_Result($teachersHandled); - } - - public function byDepartment($departmentID) - { - $teachers = $this->model->getTeachersByDepartment($departmentID); - $i = 0; - foreach($teachers as $row) - { - $i++; - $teachersHandled[$i]['ID'] = $row['ID']; - $teachersHandled[$i]['AccountID'] = $row['AccountID']; - $teachersHandled[$i]['First'] = $row['First']; - $teachersHandled[$i]['Second'] = $row['Second']; - $teachersHandled[$i]['Last'] = $row['Last']; - $teachersHandled[$i]['JobPositionName'] = $row['JobPositionName']; - $teachersHandled[$i]['DepartmentName'] = $row['DepName']; - } - return new DataArray_Result($teachersHandled); - } - - public function forDiscipline($disciplineID, $asConcat = false, $asInitials = false) - { - $teachers = $this->model->getTeachersForDiscipline($disciplineID); - $teachersHandled = array(); $i = 0; - foreach ($teachers as $teacher) - { - $i++; $tchr = array(); - $tchr['isAuthor'] = $teacher['isAuthor']; - $tchr['ID'] = $teacher['ID']; - $tchr['Last'] = $teacher['Last']; - $tchr['First'] = $asInitials ? - UTF8::substr($teacher['First'], 0, 1).'. ' : $teacher['First']; - if(!empty($teacher['Second'])) - $tchr['Second'] = $asInitials ? - UTF8::substr($teacher['Second'], 0, 1).'. ' : $teacher['Second']; - if($asConcat) - $teachersHandled[$i] = $tchr['Last'].$tchr['First'].$tchr['Second']; - else - $teachersHandled[$i] = $tchr; - } - return new DataArray_Result($teachersHandled); - } - -} diff --git a/~dev_rating/application/classes/DataArr/Tickets.php b/~dev_rating/application/classes/DataArr/Tickets.php deleted file mode 100644 index 5395052a5f2092fd924349051ca75f01654dae37..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArr/Tickets.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php - -class DataArr_Tickets { - protected $model; - - public function __construct() { - $this->model = new Model_DataArr_Tickets; - } - - public function forAccount($accountID) - { - - } - - public function forAdministrator() - { - - } -} diff --git a/~dev_rating/application/classes/DataArray.php b/~dev_rating/application/classes/DataArray.php deleted file mode 100644 index 3be6c66d75b21f0d4301f043e61b2ade18c1b7c4..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArray.php +++ /dev/null @@ -1,14 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class DataArray -{ - public static function factory($type = NULL) { - if($type == NULL) - return false; - else - { - $className = 'DataArr_'.$type; - return new $className(); - } - } -} \ No newline at end of file diff --git a/~dev_rating/application/classes/DataArray/Result.php b/~dev_rating/application/classes/DataArray/Result.php deleted file mode 100644 index 4260f1daaddd94da2a476fd27ce405f75eb40724..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/DataArray/Result.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php - -class DataArray_Result { - protected $dataArr; - - public function __construct($dataArr) { - $this->dataArr = $dataArr; - } - - public function asArray() - { - return $this->dataArr; - } - - public function asJSON() - { - return json_encode($this->dataArr); - } -} diff --git a/~dev_rating/application/classes/DataHelper.php b/~dev_rating/application/classes/DataHelper.php new file mode 100644 index 0000000000000000000000000000000000000000..2c78c1c5ffecba96143683159f7687587f3a5ea1 --- /dev/null +++ b/~dev_rating/application/classes/DataHelper.php @@ -0,0 +1,85 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class DataHelper +{ + // take array with (at least) LastName & FirstName keys + static public function AbbreviateName(&$personInfo) { + $fullName = $personInfo['LastName'].' '.UTF8::substr($personInfo['FirstName'], 0, 1).'. '; + if(!empty($personInfo['SecondName'])) { + $fullName .= UTF8::substr($personInfo['SecondName'], 0, 1).'.'; + } + return $fullName; + } + + static public function GetAbbrNameArray($persons) + { + $result = array(); + $i = 0; + foreach ($persons as $person){ + $result[$i] = self::AbbreviateName($person); + ++$i; + } + return $result; + } + + static public function LocalizeExamType($examType) { + return ($examType === "exam")?"Ркзамен":"Зачет"; + } + + static public function LocalizeDegree($degree) { + return Model_Grades::getDegreeTitle($degree); + } + + static public function DeserializeDisciplines($rawDiscs) + { + $subjID = $discID = $gradeID = $i = $j = 0; // Combo!!! + $result = array(); + + foreach ($rawDiscs as $row) + { + $curSubjectID = $row['SubjectID']; + $curGradeID = $row['GradeID']; + $curDiscID = $row['ID']; + + if($subjID != $curSubjectID || $gradeID != $curGradeID) + { + $j = 0; + ++$i; + $subjID = $curSubjectID; + $gradeID = $curGradeID; + + // new grade/subject + $data = array(); + $data['Degree'] = $row['Degree']; + $data['GradeNum'] = $row['GradeNum']; + $data['SubjectName'] = $row['SubjectName']; + $result[$i] = $data; + $result[$i]['Disciplines'] = array(); + $discs = &$result[$i]['Disciplines']; + } + + if($discID != $curDiscID) + { + $discID = $curDiscID; + $discs[$j] = $row; // IsAuthor, IsLocked, IsMapCreated, ID, ExamType + ++$j; + } + } //!for_each + + return $result; + } + + + + + + + + + + + + + + +} \ No newline at end of file diff --git a/~dev_rating/application/classes/FileParser.php b/~dev_rating/application/classes/FileParser.php index 420a081fefc1890249cb876a687800d6a5afdbd8..2ab693f9fee7aa048cb489b40f9770e17aa0e361 100644 --- a/~dev_rating/application/classes/FileParser.php +++ b/~dev_rating/application/classes/FileParser.php @@ -4,7 +4,7 @@ class FileParser { public static function StudentsList($filename, $facultyID) { - $model = new Model_Admin_Students; + $model = new Model_Students(); if(File::mime($filename) != 'text/plain') return true; $file = fopen($filename, "r"); @@ -16,18 +16,7 @@ class FileParser // РљСѓСЂСЃ, степень подготовки $studentGradeNum = $line[1]; $studentGroupNum = $line[2]; - switch($line[3]) - { - case 'Бакалавр': - $studentDegree = 'bachelor'; - break; - case 'Специалист': - $studentDegree = 'specialist'; - break; - case 'Магистр': - $studentDegree = 'master'; - break; - } + $studentDegree = Model_Grades::getDegreeTitle($line[3]); $studentSpec = $line[4]; $attempt = Account::instance()->createStudentEx($lastName, $firstName, $secondName, $studentGradeNum, $studentGroupNum, $studentDegree, $studentSpec, $facultyID); @@ -46,7 +35,7 @@ class FileParser { $resultArr = array(); $resultArr['Success'] = false; - $model = new Model_Admin_Students; + $model = new Model_Students(); if(File::mime($filename) != 'text/plain') return $resultArr; $file = fopen($filename, "r"); @@ -86,9 +75,9 @@ class FileParser if(File::mime($filename) != 'text/plain') return true; - $file = fopen($filename, "r"); + $file = fopen($filename, "r"); $i = $j = 0; - while ($line = fgetcsv($file, 0, ";")) + while ($line = fgetcsv($file, 0, ";")) { // РРјСЏ, фамилия, отчество list($lastName, $firstName, $secondName) = self::parsePeopleName($line[0]); @@ -96,9 +85,8 @@ class FileParser $facultyID = 6; // TODO fix facultyID hardcode if ($line[2]) $facultyID = $faculties[trim($line[2])]; - - $attempt = Account::instance()->createTeacherByDepName($lastName, $firstName, $secondName, - $departmentName, $facultyID); + $attempt = Account::instance()->createTeacherByDepName($lastName, $firstName, $secondName, + $departmentName, $facultyID); // TODO fix facultyID hardcode if($attempt == -1) { $resultArr[$j]['Row'] = $i; diff --git a/~dev_rating/application/classes/Model/Accounts.php b/~dev_rating/application/classes/Model/Accounts.php new file mode 100644 index 0000000000000000000000000000000000000000..b59747db18d971f9cb792dc0020f3ea404244693 --- /dev/null +++ b/~dev_rating/application/classes/Model/Accounts.php @@ -0,0 +1,9 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Accounts extends Model +{ + public static function getAccountInfo($ID) { + $sql = "CALL `GetAccountInfo`('$ID'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } +} \ No newline at end of file diff --git a/~dev_rating/application/classes/Model/Admin/Accounts.php b/~dev_rating/application/classes/Model/Admin/Accounts.php deleted file mode 100644 index 2ca3fdebce7ebd404398c2a0ca5ce357664f288f..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/Admin/Accounts.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_Admin_Accounts extends Model -{ - public function getStudyGroups($gradeID, $facultyID) - { - $sql = "CALL `GetStudyGroups`('$gradeID', '$facultyID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getStudents($groupID) - { - $sql = "CALL `GetStudents`('$groupID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getDepartments($facultyID) - { - $sql = "CALL `GetDepartments`('$facultyID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getTeachersByDepartment($departmentID) - { - $sql = "CALL `GetTeachersByDepartment`('$departmentID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getAccountInfo($ID) - { - $sql = "CALL `GetAccountInfo`('$ID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - -} \ No newline at end of file diff --git a/~dev_rating/application/classes/Model/Admin/Students.php b/~dev_rating/application/classes/Model/Admin/Students.php deleted file mode 100644 index e77fab402e3557a5b199ceee17a9b999a7db89ef..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/Admin/Students.php +++ /dev/null @@ -1,19 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_Admin_Students extends Model -{ - - public function getStudyGroups($gradeNum, $facultyID) - { - $sql = "CALL `GetStudyGroups`('$gradeNum', '$facultyID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getGradeID($gradeNum, $degree) - { - $degree = Database::instance()->escape($degree); - $sql = "SELECT `GetGradeID`('$gradeNum', $degree) AS `ID`; "; - return DB::query(Database::SELECT, $sql)->execute()->get('ID'); - } - -} \ No newline at end of file diff --git a/~dev_rating/application/classes/Model/Admin/Teachers.php b/~dev_rating/application/classes/Model/Admin/Teachers.php deleted file mode 100644 index 41e8fd370381ccce00df355c65081157e66d1dd3..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/Admin/Teachers.php +++ /dev/null @@ -1,35 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_Admin_Teachers extends Model -{ - public function getFaculties() - { - $sql = "CALL `GetFaculties`(); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getJobPositions() - { - $sql = "CALL `GetJobPositions`(); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getTeachersByFaculty($facultyID) - { - $sql = "CALL `GetTeachersByFaculty`('$facultyID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getTeachersByDepartment($departamentID) - { - $sql = "CALL `GetTeachersByDepartment`('$departamentID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getDepartmentsByFaculty($facultyID) - { - $sql = "CALL `GetDepartments`('$facultyID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - -} \ No newline at end of file diff --git a/~dev_rating/application/classes/Model/DataArr/Departments.php b/~dev_rating/application/classes/Model/DataArr/Departments.php deleted file mode 100644 index 6d0007605b8b821fa4f6341f0e805ee47ef45389..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/Departments.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_Departments extends Model -{ - public function getDepartmentsByFaculty($facultyID) - { - $sql = "CALL `GetDepartments`('$facultyID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } -} diff --git a/~dev_rating/application/classes/Model/DataArr/Disciplines.php b/~dev_rating/application/classes/Model/DataArr/Disciplines.php deleted file mode 100644 index b687824fe3a2f2b2826f510b823841c579b3e72d..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/Disciplines.php +++ /dev/null @@ -1,7 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_Disciplines extends Model -{ - - -} diff --git a/~dev_rating/application/classes/Model/DataArr/Faculties.php b/~dev_rating/application/classes/Model/DataArr/Faculties.php deleted file mode 100644 index fd5ffc872fc29ab587a17e903c21c921401f5c2b..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/Faculties.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_Faculties extends Model -{ - public function getFaculties() - { - $sql = "CALL `GetFaculties`(); "; - return DB::query(Database::SELECT, $sql)->execute(); - } -} diff --git a/~dev_rating/application/classes/Model/DataArr/Grades.php b/~dev_rating/application/classes/Model/DataArr/Grades.php deleted file mode 100644 index da4531142e5739f65da08eb7f0f4f3950bdbb590..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/Grades.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_Grades extends Model -{ - public function getGrades() - { - $sql = "CALL `GetGrades`();"; - return DB::query(Database::SELECT, $sql)->execute(); - } - -} diff --git a/~dev_rating/application/classes/Model/DataArr/JobPositions.php b/~dev_rating/application/classes/Model/DataArr/JobPositions.php deleted file mode 100644 index 477ef45e547b1a4980b067df6208167937888ac0..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/JobPositions.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_JobPositions extends Model -{ - -} diff --git a/~dev_rating/application/classes/Model/DataArr/Semesters.php b/~dev_rating/application/classes/Model/DataArr/Semesters.php deleted file mode 100644 index eb23ad3054e867c2bf707a54f70cdf6ded73d5ca..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/Semesters.php +++ /dev/null @@ -1,17 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_Semesters extends Model -{ - public function getSemesterInfo($id) - { - $sql = "CALL `GetSemesterInfo`('$id'); "; - return DB::query(Database::SELECT, $sql)->execute()->offsetGet(0); - } - - public function getSemesters() - { - $sql = "CALL `GetSemesters`()"; - return DB::query(Database::SELECT, $sql)->execute(); - } - -} diff --git a/~dev_rating/application/classes/Model/DataArr/Specializations.php b/~dev_rating/application/classes/Model/DataArr/Specializations.php deleted file mode 100644 index c89d74797a3ab69e8ab02bac8321ee4ce30297d9..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/Specializations.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_Specializations extends Model -{ - -} diff --git a/~dev_rating/application/classes/Model/DataArr/Students.php b/~dev_rating/application/classes/Model/DataArr/Students.php deleted file mode 100644 index 6ac6ed30e2d160b10bf2344e1778e0ec6249ac3d..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/Students.php +++ /dev/null @@ -1,48 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_Students extends Model -{ - public function getStudentsByStudyGroups($groupID) - { - $sql = "CALL `GetStudents`('$groupID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getStudentsByFaculty($facultyID, $gradeID, $groupID) - { - $sql = "CALL `GetStudentsByFaculty`('$facultyID', '$gradeID', $groupID); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getStudentsByGradeID($facultyID, $gradeID) - { - $sql = "CALL `GetStudentsByFaculty`('$facultyID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getStudentsForDiscipline($teacherID, $disciplineID) - { - $sql = "CALL `getStudentsForDiscipline`('$teacherID', '$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - - // public function searchStudents($Grade, $GroupN, $FacultyID, $Last, $First, $Second) - // { - // $sql = "CALL `SearchStudents`('$Grade', '$GroupN', '$FacultyID', '$Last', '$First', '$Second'); "; - // return DB::query(Database::SELECT, $sql)->execute(); - // } - - // public function searchStudentsNew($Grade, $GroupN, $FacultyID, $Last, $First, $Second, $DisciplineID) - // { - // $sql = "CALL `SearchStudentsNew`('$Grade', '$GroupN', '$FacultyID', '$Last', '$First', '$Second', '$DisciplineID'); "; - // return DB::query(Database::SELECT, $sql)->execute(); - // } - - public function SearchStudents($GradeID, $GroupID, $FacultyID, $Name, $DisciplineID) - { - $Name = Database::instance()->escape($Name); - $sql = "CALL `SearchStudents`('$GradeID', '$GroupID', '$FacultyID', $Name, '$DisciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } -} diff --git a/~dev_rating/application/classes/Model/DataArr/StudyGroups.php b/~dev_rating/application/classes/Model/DataArr/StudyGroups.php deleted file mode 100644 index beb00196a82cad428c85dc97fcfdb999f4dc2b67..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/StudyGroups.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_StudyGroups extends Model -{ - public function getStudyGroupsForDiscipline($disciplineID) - { - $sql = "CALL `GetStudyGroupsForDiscipline`('$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - // public function getStudyGroups($Grade, $FacultyID) - // { - // $sql = "CALL `GetStudyGroups`('$Grade', '$FacultyID'); "; - // return DB::query(Database::SELECT, $sql)->execute(); - // } - - public function getStudyGroups($grade, $facultyID) - { - $sql = "CALL `GetStudyGroups`('$grade', '$facultyID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - -} diff --git a/~dev_rating/application/classes/Model/DataArr/Subjects.php b/~dev_rating/application/classes/Model/DataArr/Subjects.php deleted file mode 100644 index 5dd0d3f403c2a81d098ee4df5c5b0f9a2fa7e0e7..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/Subjects.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_Subjects extends Model -{ - public function getSubjects($facultyID) - { - $sql = "CALL `GetSubjects`('$facultyID');"; - return DB::query(Database::SELECT, $sql)->execute(); - } - -} diff --git a/~dev_rating/application/classes/Model/DataArr/Teachers.php b/~dev_rating/application/classes/Model/DataArr/Teachers.php deleted file mode 100644 index 866d15006c04eab232011e7b202415230eec3028..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/Teachers.php +++ /dev/null @@ -1,42 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_Teachers extends Model -{ - public function getTeachersByFaculty($facultyID) - { - $sql = "CALL `GetTeachersByFaculty`('$facultyID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getTeachersByDepartment($departamentID) - { - $sql = "CALL `GetTeachersByDepartment`('$departamentID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getTeachersForDiscipline($disciplineID) - { - $sql = "CALL `GetTeachersForDiscipline`('$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function searchTeachers($FacultyID, $DepartmentID, $Last, $First, $Second) { - $db = Database::instance(); - $Last = $db->escape($Last); - $Second = $db->escape($Second); - $First = $db->escape($First); - $sql = "CALL `SearchTeachers`('$FacultyID', '$DepartmentID', $Last, $First, $Second); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function searchTeacherNew($FacultyID, $DepartmentID, $Last, $First, $Second, $DisciplineID) { - $db = Database::instance(); - $Last = $db->escape($Last); - $Second = $db->escape($Second); - $First = $db->escape($First); - $sql = "CALL `SearchTeacherNew`('$FacultyID', '$DepartmentID', $Last, $First, $Second, '$DisciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - -} diff --git a/~dev_rating/application/classes/Model/DataArr/Tickets.php b/~dev_rating/application/classes/Model/DataArr/Tickets.php deleted file mode 100644 index ecbf55fe72ae792e1293e5a31f487558a60f36bb..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/DataArr/Tickets.php +++ /dev/null @@ -1,6 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_DataArr_Tickets extends Model -{ - -} diff --git a/~dev_rating/application/classes/Model/Departments.php b/~dev_rating/application/classes/Model/Departments.php new file mode 100644 index 0000000000000000000000000000000000000000..ab19cba96bc684a547bdcdaaea4d72de9090eb64 --- /dev/null +++ b/~dev_rating/application/classes/Model/Departments.php @@ -0,0 +1,26 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Departments extends Model +{ + /** + * @param $faculty int faculty id + * @return Database_Result + */ + public static function ofFaculty($faculty) { + $sql = "CALL `GetDepartments`('$faculty'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function byFaculty($facultyID) { + $list = array(); + if ($facultyID > 0) { + $departments = self::ofFaculty($facultyID); + foreach ($departments as $row) { + if ($row['Name'] == null) + $row['Name'] = '<служебная кафедра>'; + $list[] = $row; + } + } + return $list; + } +} diff --git a/~dev_rating/application/classes/Model/Discipline.php b/~dev_rating/application/classes/Model/Discipline.php new file mode 100644 index 0000000000000000000000000000000000000000..13dd62d13725fcca01d53458790c5184d6fa5e3d --- /dev/null +++ b/~dev_rating/application/classes/Model/Discipline.php @@ -0,0 +1,61 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Discipline extends Model +{ + /** + * @param $id int discipline id + * @return array data from <tt>view_disciplines</tt> table + * @throws HTTP_Exception if discipline does not exist + */ + public static function getInfo($id) { + $sql = "CALL `GetDisciplineInfo`('$id'); "; + $info = DB::query(Database::SELECT, $sql)->execute(); + + if($info->count() == 0) + throw HTTP_Exception::factory(404, "Учебная карта дисциплины СЃ ID $id РЅРµ найдена!"); + return $info->offsetGet(0); + } + + + /** + * Add new discipline. + * + * @param $teacher int teacher id + * @param $grade int 1-7 + * @param $subject int subject id + * @param $examType string <tt>exam</tt> or <tt>credit</tt> + * @param $lectureCount int + * @param $practiceCount int + * @param $labCount int + * @param $department int department id + * @return Database_Result + */ + public static function create($teacher, $grade, $subject, $examType, $lectureCount, $practiceCount, $labCount, $department) { + $sql = "SELECT `AddDiscipline`('$teacher', '$grade', '$subject', '$examType', '$lectureCount', '$practiceCount', '$labCount', '$department') AS `Num`;"; + return DB::query(Database::SELECT, $sql)->execute(); + } + + /** Change grade. */ + public static function changeGrade($DisciplineID, $teacherID, $Grade) { + $sql = "SELECT `ChangeDisciplineGrade`('$teacherID', '$DisciplineID', '$Grade') AS `Num`;"; + return DB::query(Database::SELECT, $sql)->execute(); + } + + /** + * Check, whether discipline already exists. + * + * @param $teacher int teacher id + * @param $subject int subject id + * @param $grade int grade num (1-7) + * @return true, if exists + */ + public static function exists($teacher, $subject, $grade) { + $disciplines = Model_Disciplines::ofTeacher($teacher); + foreach ($disciplines as $d) { + if ($subject == $d['SubjectID'] && $grade == $d['GradeNum']) + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/~dev_rating/application/classes/Model/Disciplines.php b/~dev_rating/application/classes/Model/Disciplines.php new file mode 100644 index 0000000000000000000000000000000000000000..4cbbf0e05b1345618e2c22dd2d2a16671a206cd9 --- /dev/null +++ b/~dev_rating/application/classes/Model/Disciplines.php @@ -0,0 +1,34 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Disciplines extends Model +{ + /** + * @param $id int student id + * @return Database_Result select from <tt>view_disciplines</tt> table + */ + public static function ofStudent($id) { + $sql = "CALL `GetDisciplinesForStudent`('$id'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + /** + * @param $id int teacher id + * @return Database_Result + */ + public static function ofTeacher($id) + { + $sql = "CALL `GetDisciplinesForTeacher`('$id'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + /** + * @param $group int group id + * @return Database_Result + */ + public static function ofGroup($group) { + $sql = "CALL `GetDisciplinesForGroup`('$group')"; + return DB::query(Database::SELECT, $sql)->execute(); + } + + // TODO: Методы для получения СЃРїРёСЃРєР° дисциплин +} \ No newline at end of file diff --git a/~dev_rating/application/classes/Model/Faculties.php b/~dev_rating/application/classes/Model/Faculties.php new file mode 100644 index 0000000000000000000000000000000000000000..83ad3a47ca7646d6ddb46d58b934f716ceae19dd --- /dev/null +++ b/~dev_rating/application/classes/Model/Faculties.php @@ -0,0 +1,18 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Faculties extends Model +{ + public static function getFaculties() { + $sql = "CALL `GetFaculties`(); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function toArray() { + $faculties = self::getFaculties(); + + $list = array(); + foreach ($faculties as $row) + $list[] = $row; + return $list; + } +} diff --git a/~dev_rating/application/classes/Model/Grades.php b/~dev_rating/application/classes/Model/Grades.php new file mode 100644 index 0000000000000000000000000000000000000000..d1a6adc2d9c1eddf108d8ca4e7a2e0f491937e79 --- /dev/null +++ b/~dev_rating/application/classes/Model/Grades.php @@ -0,0 +1,57 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Grades extends Model +{ + public static function getGrades() { + $sql = "CALL `GetGrades`();"; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function toArray() { + $grades = self::GetGrades(); + $list = array(); + + foreach ($grades as $row) { + if ($row['Degree'] == 'bachelor' || $row['Degree'] == 'specialist') + $row['Title'] = 'РљСѓСЂСЃ ' . $row['Num']; + if ($row['Degree'] == 'master') + $row['Title'] = 'Магистратура ' . $row['Num']; + $list[] = $row; + } + + return $list; + } + + public static function getDegreeTitle($degree) { + switch ($degree) { + case 'bachelor': + return 'Бакалавриат'; + case 'specialist': + return 'Специалитет'; + case 'master': + return 'Магистратура'; + default: + return $degree; + } + } + + /** @return array an array with elements, grouped by grades. */ + public static function toStructuredArray() { + $grades = self::toArray(); + $list = array(); + $degree = 'null'; + $i = 0; + + foreach ($grades as $row) { + if ($degree != $row['Degree']) { + $degree = $row['Degree']; + $i++; + } + + $list[$i]['Title'] = self::getDegreeTitle($row['Degree']); + $list[$i]['Grades'][] = $row; + } + + return $list; + } +} diff --git a/~dev_rating/application/classes/Model/Groups.php b/~dev_rating/application/classes/Model/Groups.php new file mode 100644 index 0000000000000000000000000000000000000000..04532574eae9f31f2ef905ab532db66dabec9126 --- /dev/null +++ b/~dev_rating/application/classes/Model/Groups.php @@ -0,0 +1,36 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Groups extends Model +{ + public static function getGroupsForDiscipline($disciplineID) { + $sql = "CALL `GetGroupsForDiscipline`('$disciplineID'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function getGroups($grade, $facultyID) { + $sql = "CALL `GetGroups`('$grade', '$facultyID'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function forDiscipline($DisciplineID) { + $groups = self::getGroupsForDiscipline($DisciplineID); + + $list = array(); + foreach ($groups as $row) + $list[] = $row; + + return $list; + } + + public static function orderByGroups($GradeID, $FacultyID) { + $groups = self::getGroups($GradeID, $FacultyID); + + $list = array(); + foreach ($groups as $row) + $list[] = $row; + + return $list; + } + + // TODO: Методы для получения СЃРїРёСЃРєР° учебных РіСЂСѓРїРї +} diff --git a/~dev_rating/application/classes/Model/Teacher/Map.php b/~dev_rating/application/classes/Model/Map.php similarity index 61% rename from ~dev_rating/application/classes/Model/Teacher/Map.php rename to ~dev_rating/application/classes/Model/Map.php index efe4beaa5801ce984cc1f534b031433789466482..51d05c210d8ce4efcf4b57171410fc52474388ca 100644 --- a/~dev_rating/application/classes/Model/Teacher/Map.php +++ b/~dev_rating/application/classes/Model/Map.php @@ -1,146 +1,112 @@ <?php defined('SYSPATH') or die('No direct script access.'); -class Model_Teacher_Map extends Model +class Model_Map extends Model { - - - public function getStudentsForDiscipline($teacherID, $disciplineID) - { - $sql = "CALL `getStudentsForDiscipline`('$teacherID', '$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - - public function addModuleBonus($teacherID, $disciplineID) + public static function addModuleBonus($teacherID, $disciplineID) { $sql = "SELECT `AddModuleBonus`('$teacherID', '$disciplineID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function deleteModuleBonus($teacherID, $disciplineID) + + public static function deleteModuleBonus($teacherID, $disciplineID) { $sql = "SELECT `DeleteModuleBonus`('$teacherID', '$disciplineID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); - } - - public function addModule($teacherID, $disciplineID, $title) + } + + public static function addModule($teacherID, $disciplineID, $title) { $db = Database::instance(); $title = $db->escape($title); $sql = "SELECT `AddModule`('$teacherID', '$disciplineID', $title) AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); - } - - public function deleteModule($teacherID, $moduleID) + } + + public static function deleteModule($teacherID, $moduleID) { $sql = "SELECT `DeleteModule`('$teacherID', '$moduleID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - public function DelegateDiscipline($teacherID, $NewAuthorID, $DisciplineID) + public static function DelegateDiscipline($teacherID, $NewAuthorID, $DisciplineID) { $sql = "SELECT `DelegateDiscipline`('$teacherID', '$NewAuthorID', '$DisciplineID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function changeModuleName($teacherID, $moduleID, $Name) + + public static function changeModuleName($teacherID, $moduleID, $Name) { $db = Database::instance(); $Name = $db->escape($Name); $sql = "SELECT `ChangeModuleName`('$teacherID', '$moduleID', $Name) AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function addSubmodule($teacherID, $moduleID, $maxRate, $title, $description, $typeControl) + + public static function addSubmodule($teacherID, $moduleID, $maxRate, $title, $description, $typeControl) { $sql = "SELECT `AddSubmodule`('$teacherID', '$moduleID', '$maxRate', '$title', '$description', '$typeControl') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function deleteSubmodule($teacherID, $submoduleID) + + public static function deleteSubmodule($teacherID, $submoduleID) { $sql = "SELECT `DeleteSubmodule`('$teacherID', '$submoduleID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function changeSubmoduleName($teacherID, $submoduleID, $Name) + + public static function changeSubmoduleName($teacherID, $submoduleID, $Name) { $db = Database::instance(); $Name = $db->escape($Name); $sql = "SELECT `ChangeSubmoduleName`('$teacherID', '$submoduleID', $Name) AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - - - public function swapModuleOrder($teacherID, $moduleID1, $moduleID2) + + + + public static function swapModuleOrder($teacherID, $moduleID1, $moduleID2) { $sql = "SELECT `SwapModuleOrder`('$teacherID', '$moduleID1', '$moduleID2') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function swapSubmoduleOrder($teacherID, $submoduleID1, $submoduleID2) + + public static function swapSubmoduleOrder($teacherID, $submoduleID1, $submoduleID2) { $sql = "SELECT `SwapSubmoduleOrder`('$teacherID', '$submoduleID1', '$submoduleID2') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - public function changeSubmoduleMaxAndControl($teacherID, $SubmoduleID, $MaxRate, $ControlType) + public static function changeSubmoduleMaxAndControl($teacherID, $SubmoduleID, $MaxRate, $ControlType) { $db = Database::instance(); $ControlType = $db->escape($ControlType); $sql = "SELECT `ChangeSubmoduleMaxAndControl`('$teacherID', '$SubmoduleID', '$MaxRate', $ControlType) AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - - - - - public function getDisciplineInfoByID($discipline_id) - { - $sql = "CALL `GetDisciplineInfoByID`('$discipline_id'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - public function getMapForDiscipline($teacherID, $disciplineID) + public static function getMapForDiscipline($disciplineID) { - $sql = "CALL `getMapForDiscipline`('$teacherID', '$disciplineID'); "; + $sql = "CALL `GetRoadmap`('$disciplineID'); "; return DB::query(Database::SELECT, $sql)->execute(); } - - - - public function addDiscipline($teacherID, $Grade, $SubjectID, $ExamType, $LectionCount, $PracticeCount, $LabCount, $DepartmentID) - { - $sql = "SELECT `AddDiscipline`('$teacherID', '$Grade', '$SubjectID', '$ExamType', '$LectionCount', '$PracticeCount', '$LabCount', '$DepartmentID') AS `Num`;"; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function changeDisciplineSubject($teacherID, $DisciplineID, $SubjectID) + public static function changeDisciplineSubject($teacherID, $DisciplineID, $SubjectID) { $sql = "SELECT `ChangeDisciplineSubject`('$teacherID', '$DisciplineID', '$SubjectID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function changeDisciplineGrade($teacherID, $DisciplineID, $Grade) - { - $sql = "SELECT `ChangeDisciplineGrade`('$teacherID', '$DisciplineID', '$Grade') AS `Num`;"; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function changeDisciplineControl($teacherID, $DisciplineID, $Control) + + public static function changeDisciplineControl($teacherID, $DisciplineID, $Control) { $db = Database::instance(); $Control = $db->escape($Control); $sql = "SELECT `ChangeDisciplineControl`('$teacherID', '$DisciplineID', $Control) AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function changeDisciplineHours($teacherID, $DisciplineID, $Hours, $Type) + + public static function changeDisciplineHours($teacherID, $DisciplineID, $Hours, $Type) { $db = Database::instance(); $Type = $db->escape($Type); @@ -148,44 +114,44 @@ class Model_Teacher_Map extends Model return DB::query(Database::SELECT, $sql)->execute(); } - public function deleteDiscipline($AuthorID, $DisciplineID) + public static function deleteDiscipline($AuthorID, $DisciplineID) { $sql = "SELECT `DeleteDiscipline`('$AuthorID', '$DisciplineID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - public function bindGroup($teacherID, $DisciplineID, $StudyGroupID) + public static function bindGroup($teacherID, $DisciplineID, $GroupID) { - $sql = "SELECT `BindGroup`('$teacherID', '$DisciplineID', '$StudyGroupID') AS `Num`;"; + $sql = "SELECT `BindGroup`('$teacherID', '$DisciplineID', '$GroupID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function unbindGroup($teacherID, $DisciplineID, $StudyGroupID) + + public static function unbindGroup($teacherID, $DisciplineID, $GroupID) { - $sql = "SELECT `UnbindGroup`('$teacherID', '$DisciplineID', '$StudyGroupID') AS `Num`;"; + $sql = "SELECT `UnbindGroup`('$teacherID', '$DisciplineID', '$GroupID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function bindStudent($teacherID, $DisciplineID, $StudentID) + + public static function bindStudent($teacherID, $DisciplineID, $StudentID) { $sql = "SELECT `BindStudent`('$teacherID', '$DisciplineID', '$StudentID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function UnbindStudent($teacherID, $DisciplineID, $StudentID) + + public static function UnbindStudent($teacherID, $DisciplineID, $StudentID) { $sql = "SELECT `UnbindStudent`('$teacherID', '$DisciplineID', '$StudentID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function bindTeacher($AccessedTeacher, $BindingTeacher, $DisciplineID) + + public static function bindTeacher($AccessedTeacher, $BindingTeacher, $DisciplineID) { $sql = "SELECT `BindTeacher`('$AccessedTeacher', '$BindingTeacher', '$DisciplineID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); } - - public function unbindTeacher($AccessedTeacher, $BindingTeacher, $DisciplineID) + + public static function unbindTeacher($AccessedTeacher, $BindingTeacher, $DisciplineID) { $sql = "SELECT `UnbindTeacher`('$AccessedTeacher', '$BindingTeacher', '$DisciplineID') AS `Num`;"; return DB::query(Database::SELECT, $sql)->execute(); @@ -203,7 +169,7 @@ class Model_Teacher_Map extends Model // } // deprecated (moved in helpers) - public function searchTeachers($FacultyID, $DepartmentID, $Name, $DisciplineID) + public static function searchTeachers($FacultyID, $DepartmentID, $Name, $DisciplineID) { $db = Database::instance(); $Name = $db->escape($Name); diff --git a/~dev_rating/application/classes/Model/Rating.php b/~dev_rating/application/classes/Model/Rating.php new file mode 100644 index 0000000000000000000000000000000000000000..7f2f2d02f546b2193f124a6b996f2ba6be5cebae --- /dev/null +++ b/~dev_rating/application/classes/Model/Rating.php @@ -0,0 +1,76 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Rating extends Model +{ + public static function GetStudentsForRating($disciplineID) { + $sql = "CALL `GetStudentsForRating`('$disciplineID'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + /** + * Get the disciplines's roadmap (учебная карта). + * @param $discipline int discipline id + * @return Database_Result select from <tt>view_roadmap</tt> table + */ + public static function getMapForDiscipline($discipline) { + $sql = "CALL `GetRoadmap`('$discipline'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + /** + * @param $discipline int discipline id + * @param $student int student id + * @return Database_Result + */ + public static function getRates($discipline, $student) { + $sql = "CALL `GetRates`('$student', '$discipline'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + /** + * @param $discipline int discipline id + * @param $student int student id + * @return Database_Result + */ + public static function getExamRates($discipline, $student) { + $sql = "CALL `GetRatesExam`('$student', '$discipline'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function GetMapForDisciplineExam($disciplineID) { + $sql = "CALL `GetRoadmapExam`('$disciplineID'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function getMapForStudent($studentID, $disciplineID) + { + $sql = "CALL `GetMapForStudent`('$studentID', '$disciplineID'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function getAttestationData($disciplineID, $groupID) + { + $sql = "CALL `GetAttestationData`($disciplineID, $groupID)"; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function SetStudentRate($teacherID, $studentID, $submoduleID, $rate) { + $sql = "SELECT `SetStudentRate`('$teacherID', '$studentID', '$submoduleID', '$rate') AS `Num`;"; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function GetStudentRate($studentID, $disciplineID) { + $sql = "SELECT `GetRateForDisc`('$studentID', '$disciplineID') AS `Num`;"; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function getRatesForStudentsGroup($disciplineID, $groupID) { + $sql = "CALL `GetRatesForGroup`('$disciplineID', '$groupID')"; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function getFinalFormInfo($disciplineID, $groupID) { + $sql = "CALL `getFinalFormInfo`('$disciplineID', '$groupID')"; + return DB::query(Database::SELECT, $sql)->execute(); + } +} diff --git a/~dev_rating/application/classes/Model/Semesters.php b/~dev_rating/application/classes/Model/Semesters.php new file mode 100644 index 0000000000000000000000000000000000000000..77124664ad1e443ff16e59d526cf641b7057de61 --- /dev/null +++ b/~dev_rating/application/classes/Model/Semesters.php @@ -0,0 +1,30 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Semesters extends Model +{ + /** + * @param $id int semester id + * @return array data from <tt>semesters</tt> table + */ + public static function getInfo($id) { + $sql = "CALL `GetSemesterInfo`('$id'); "; + return DB::query(Database::SELECT, $sql)->execute()->offsetGet(0); + } + + public static function getSemesters() { + $sql = "CALL `GetSemesters`()"; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function toArray() { + $semesters = self::getSemesters(); + $list = array(); + + foreach ($semesters as $row) { + $row['Num'] = ($row['Num'] == 1) ? 'Осенний' : 'Весенний'; + $list[] = $row; + } + + return $list; + } +} \ No newline at end of file diff --git a/~dev_rating/application/classes/Model/Student.php b/~dev_rating/application/classes/Model/Student.php index 72c588e365b8e34d01047d1837228c9296b78fa2..4e826ef39e1dd021bf2e6b88348d00cea200672a 100644 --- a/~dev_rating/application/classes/Model/Student.php +++ b/~dev_rating/application/classes/Model/Student.php @@ -2,33 +2,99 @@ class Model_Student extends Model { - public function getAllDisciplines($id) - { - $sql = "CALL `GetDisciplinesForStudent`('$id'); "; - return DB::query(Database::SELECT, $sql)->execute(); + private $id; + + public static function load($id) { + $student = new self(); + $student->id = (int) $id; + + // todo: there should be a function to load data from db + // Student_Get(id): array + + return $student; } - - public function getDisciplineMap($student_id, $subject_id) - { - $sql = "CALL `GetMapForStudent`('$student_id', '$subject_id'); "; - return DB::query(Database::SELECT, $sql)->execute(); + + /** + * Create new student from a source data. + * + * todo: no activation code (move the check to a controller) + * todo: make Student_Create instead of CreateStudent + * todo: test me + * + * @param $lastName + * @param $firstName + * @param $secondName + * @param $gradeID + * @param $activationCode + * @return $this; + */ + public static function create($lastName, $firstName, $secondName, $gradeID, $activationCode) { + $sql = 'SELECT `CreateStudent`(:last, :first, :second, :grade, :code)'; + + $id = DB::query(Database::SELECT, $sql) + ->parameters([ + 'last' => $lastName, + 'first' => $firstName, + 'second' => $secondName, + 'grade' => $gradeID, + 'code' => $activationCode, + ]) + ->execute(); + + return self::load($id); } - - public function getDisciplineInfoByID($discipline_id) - { - $sql = "CALL `GetDisciplineInfoByID`('$discipline_id'); "; - return DB::query(Database::SELECT, $sql)->execute(); + + + // getters and setters + function __get($name) { + if ($name == 'id') + return (int) $this->id; + return null; + } + + function __set($name, $value) { } + + // todo implementation + public function update() { + throw new BadMethodCallException('Method is not implemented yet!'); + } + + /** + * @see students_groups.IsStudyLeave + * @deprecated cause it's not implemented yet + * @return boolean true, if the student is on leave + */ + public function inAcademicLeave() { + throw new BadMethodCallException("Method is not implemented yet!"); + } + + /** + * Send the student to an academic leave. + * @return $this; + */ + public function toAcademicLeave() { + $sql = "CALL `ControlStudentGroup`(:id, -1, true);"; + + DB::query(Database::SELECT, $sql) + ->param(':id', $this->id) + ->execute(); + + return $this; + } + + /** + * Cancel the student's leave. + * @param $group int group id + * @return $this; + */ + public function returnFromAcademicLeave($group) { + $sql = "CALL `ControlStudentGroup`(:id, :group, false);"; + + DB::query(Database::SELECT, $sql) + ->param(':id', $this->id) + ->param(':group', (int) $group) + ->execute(); + + return $this; } - - public function getTeachersForDiscipline($discipline_id) - { - $sql = "CALL `GetTeachersForDiscipline`('$discipline_id'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getSemesterInfo($id) // TODO: перенести РІ common.php - { - $sql = "CALL `GetSemesterInfo`('$id'); "; - return DB::query(Database::SELECT, $sql)->execute()->offsetGet(0); - } } diff --git a/~dev_rating/application/classes/Model/Students.php b/~dev_rating/application/classes/Model/Students.php new file mode 100644 index 0000000000000000000000000000000000000000..dbf4b7bdbc4e11f1945a7d811dd8876d5890b27b --- /dev/null +++ b/~dev_rating/application/classes/Model/Students.php @@ -0,0 +1,70 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Students extends Model +{ + public static function ofDiscipline($id) { + $sql = "CALL `GetStudentsForDiscipline`('$id'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + /** + * @param $group int group id + * @return Database_Result + */ + public static function ofGroup($group) { + $sql = "CALL `GetStudents`('$group'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + /** + * @param $grade int grade id + * @param $faculty int faculty id + * @return Database_Result + */ + public static function getGroups($grade, $faculty) { + $sql = "CALL `GetGroups`('$grade', '$faculty'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function getGradeID($gradeNum, $degree) { + $degree = Database::instance()->escape($degree); + $sql = "SELECT `GetGradeID`('$gradeNum', $degree) AS `ID`; "; + return DB::query(Database::SELECT, $sql)->execute()->get('ID'); + } + + public static function byStudyGroup($groupID) { + return self::collect(self::ofGroup($groupID)); + } + + public static function byFaculty($facultyID, $gradeID, $groupID) { + $sql = "CALL `GetStudentsByFaculty`('$facultyID', '$gradeID', $groupID); "; + $students = DB::query(Database::SELECT, $sql)->execute(); + return self::collect($students); + } + + public static function searchStudents($GradeID, $GroupID, $FacultyID, $Name, $DisciplineID) { + $Name = Database::instance()->escape($Name); + $sql = "CALL `SearchStudents`('$GradeID', '$GroupID', '$FacultyID', $Name, '$DisciplineID'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + private static function collect($students) { + $studentsHandled = array(); + foreach($students as $row) { + $row['Degree'] = Model_Grades::getDegreeTitle($row['Degree']); + $studentsHandled[] = $row; + } + return $studentsHandled; + } + + public static function NotAttendingDiscipline($GradeID, $GroupID, $FacultyID, $Name, $DisciplineID) { + $students = self::searchStudents($GradeID, $GroupID, $FacultyID, $Name, $DisciplineID); + return self::collect($students); + } + + /* + * TODO: + * a wrapper around `view_students` table + * see GetStudents, SearchStudents procedures. + */ +} \ No newline at end of file diff --git a/~dev_rating/application/classes/Model/Subjects.php b/~dev_rating/application/classes/Model/Subjects.php new file mode 100644 index 0000000000000000000000000000000000000000..47f2e0c837c6d1c47c84fffe5adb6513408c38a2 --- /dev/null +++ b/~dev_rating/application/classes/Model/Subjects.php @@ -0,0 +1,54 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Subjects +{ + const MARK_UNDEFINED = 'Undefined'; + const MARK_F = 'ECTS-F'; + const MARK_FX = 'ECTS-FX'; + const MARK_E = 'ECTS-E'; + const MARK_D = 'ECTS-D'; + const MARK_C = 'ECTS-C'; + const MARK_B = 'ECTS-B'; + const MARK_A = 'ECTS-A'; + + /** + * @param $rate int rate of student + * @param $current int current max rate of discipline + * @param $examRate int exam rate of student + * @return string mark name + */ + public static function getECTSMark($rate, $current, $examRate) { + if ($current <= 0) + return self::MARK_UNDEFINED; + if ($examRate !== NULL AND $examRate < 22) + return self::MARK_FX; + return self::compute_mark($rate / $current); + } + + private static function compute_mark($percent) { + if ($percent < 0.31) return self::MARK_F; + if ($percent < 0.60) return self::MARK_FX; + if ($percent < 0.65) return self::MARK_E; + if ($percent < 0.71) return self::MARK_D; + if ($percent < 0.85) return self::MARK_C; + if ($percent < 0.95) return self::MARK_B; + return self::MARK_A; + } + + public static function getSubjects($facultyID) { + $sql = "CALL `GetSubjects`('$facultyID');"; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function byFaculty($FacultyID) { + $subjects = self::getSubjects($FacultyID); + + $list = array(); + foreach ($subjects as $row) { + $row['Title'] = $row['Name']; // fixme: row must contain Title field by default + $list[] = $row; + } + + return $list; + } +} diff --git a/~dev_rating/application/classes/Model/Teacher.php b/~dev_rating/application/classes/Model/Teacher.php index 60fbca5c9ffcdf9a2b6230b49a215c1a9fc8c9a7..0ea9ec628ed46a7ec96dfbbd15d16b2f5b958b73 100644 --- a/~dev_rating/application/classes/Model/Teacher.php +++ b/~dev_rating/application/classes/Model/Teacher.php @@ -2,9 +2,4 @@ class Model_Teacher extends Model { - public function getDisciplines($teacherID) - { - $sql = "CALL `GetDisciplinesForTeacher`('$teacherID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } } diff --git a/~dev_rating/application/classes/Model/Teacher/Index.php b/~dev_rating/application/classes/Model/Teacher/Index.php deleted file mode 100644 index c2fed8723cd7324bd2aa589ad66f81e799754b55..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/Teacher/Index.php +++ /dev/null @@ -1,16 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_Teacher_Index extends Model -{ - public function getDisciplinesForTeacher($teacherID) - { - $sql = "CALL `GetDisciplinesForTeacher`('$teacherID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getTeachersForDiscipline($disciplineID) - { - $sql = "CALL `GetTeachersForDiscipline`('$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } -} diff --git a/~dev_rating/application/classes/Model/Teacher/Rating.php b/~dev_rating/application/classes/Model/Teacher/Rating.php deleted file mode 100644 index 57936a707c488037566bab4e61bd2ba8dd88e5c6..0000000000000000000000000000000000000000 --- a/~dev_rating/application/classes/Model/Teacher/Rating.php +++ /dev/null @@ -1,77 +0,0 @@ -<?php defined('SYSPATH') or die('No direct script access.'); - -class Model_Teacher_Rating extends Model -{ - public function getStudentsForDiscipline($teacherID, $disciplineID) - { - $sql = "CALL `getStudentsForDiscipline`('$teacherID', '$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function GetStudentsForRating($teacherID, $disciplineID) - { - $sql = "CALL `GetStudentsForRating`('$teacherID', '$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getMapForDiscipline($teacherID, $disciplineID) - { - $sql = "CALL `GetMapForDiscipline`('$teacherID', '$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getMapForStudent($studentID, $disciplineID) - { - $sql = "CALL `GetMapForStudent`('$studentID', '$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getMapForStudentExam($studentID, $disciplineID) - { - $sql = "CALL `GetMapForStudentExam`('$studentID', '$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function GetMapForDisciplineExam($teacherID, $disciplineID) - { - $sql = "CALL `GetMapForDisciplineExam`('$teacherID', '$disciplineID'); "; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function SetStudentRate($teacherID, $studentID, $submoduleID, $rate) - { - $sql = "SELECT `SetStudentRate`('$teacherID', '$studentID', '$submoduleID', '$rate') AS `Num`;"; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function GetStudentRate($studentID, $disciplineID) - { - $sql = "SELECT `GetRateForDisc`('$studentID', '$disciplineID') AS `Num`;"; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getRatesForStudentsGroup($teacherID, $disciplineID, $groupID) - { - $sql = "CALL `GetRatesForStudentsGroup`($teacherID, $disciplineID, $groupID)"; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getAttestationData($disciplineID, $groupID) - { - $sql = "CALL `GetAttestationData`($disciplineID, $groupID)"; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getFinalFormInfo($disciplineID, $groupID) - { - $sql = "CALL `GetFinalFormInfo`($disciplineID, $groupID)"; - return DB::query(Database::SELECT, $sql)->execute(); - } - - public function getDisciplinesForGroup($groupID) - { - $sql = "CALL `GetDisciplinesForGroup`($groupID)"; - return DB::query(Database::SELECT, $sql)->execute(); - } - -} diff --git a/~dev_rating/application/classes/Model/Teachers.php b/~dev_rating/application/classes/Model/Teachers.php new file mode 100644 index 0000000000000000000000000000000000000000..0d0cc20e39f6ab9c0b129fb0171c56c54989cd62 --- /dev/null +++ b/~dev_rating/application/classes/Model/Teachers.php @@ -0,0 +1,99 @@ +<?php defined('SYSPATH') or die('No direct script access.'); + +class Model_Teachers extends Model +{ + public static function getFaculties() { + $sql = "CALL `GetFaculties`(); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function getJobPositions() { + $sql = "CALL `GetJobPositions`(); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public function getTeachersByFaculty($facultyID) { + $sql = "CALL `GetTeachersByFaculty`('$facultyID'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function byFaculty($facultyID) { + $list = array(); + + if ($facultyID > 0) { + $teachers = self::getTeachersByFaculty($facultyID); + + foreach ($teachers as $row) { + $row['DepartmentID'] = $row['DepID']; + $row['DepartmentName'] = $row['DepName']; + $list[] = $row; + } + } + + return $list; + } + + public static function getTeachersByDepartment($departmentID) { + $sql = "CALL `GetTeachersByDepartment`('$departmentID'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function byDepartment($departmentID) { + $teachers = self::getTeachersByDepartment($departmentID); + $list = array(); + + foreach ($teachers as $row) { + $row['DepartmentName'] = $row['DepName']; + $list[] = $row; + } + + return $list; + } + + /** + * @param $id int discipline id + * @return Database_Result select from <tt>view_disciplines_teachers</tt> table + */ + public static function ofDiscipline($id) { + $sql = "CALL `GetTeachersForDiscipline`('$id'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function forDiscipline($disciplineID, $asConcat = false, $asInitials = false) { + $teachers = self::ofDiscipline($disciplineID); + $list = array(); + + foreach ($teachers as $row) { + if ($asInitials) { + $row['FirstName'] = UTF8::substr($row['FirstName'], 0, 1) . '. '; + if (!empty($row['SecondName'])) + $row['SecondName'] = UTF8::substr($row['SecondName'], 0, 1) . '. '; + } + + if ($asConcat) + $list[] = $row['LastName'] . $row['FirstName'] . $row['SecondName']; + else + $list[] = $row; + } + + return $list; + } + + public static function searchTeachers($FacultyID, $DepartmentID, $Last, $First, $Second) { + $db = Database::instance(); + $Last = $db->escape($Last); + $Second = $db->escape($Second); + $First = $db->escape($First); + $sql = "CALL `SearchTeachers`('$FacultyID', '$DepartmentID', $Last, $First, $Second); "; + return DB::query(Database::SELECT, $sql)->execute(); + } + + public static function searchTeacherNew($FacultyID, $DepartmentID, $Last, $First, $Second, $DisciplineID) { + $db = Database::instance(); + $Last = $db->escape($Last); + $Second = $db->escape($Second); + $First = $db->escape($First); + $sql = "CALL `SearchTeacherNew`('$FacultyID', '$DepartmentID', $Last, $First, $Second, '$DisciplineID'); "; + return DB::query(Database::SELECT, $sql)->execute(); + } +} \ No newline at end of file diff --git a/~dev_rating/application/views/admin/accounts/index.twig b/~dev_rating/application/views/admin/accounts/index.twig index 50aeedde6f32e13dd2dd6c289d4dcec80c9c5e92..08686022bfc33b5919852649d8458021857e25df 100644 --- a/~dev_rating/application/views/admin/accounts/index.twig +++ b/~dev_rating/application/views/admin/accounts/index.twig @@ -14,10 +14,10 @@ <h1>С‹</h1> </div> <div class="action_bar"> - {{ admin.action(URL.site('admin/accounts/getCodes'), URL.site('media/img/codes.png'), 'Получить РєРѕРґС‹ активации', + {{ admin.action(URL.site('admin/accounts/getActivationCodes'), URL.site('media/img/codes.png'), 'Получить РєРѕРґС‹ активации', 'Получить РєРѕРґС‹ активации для неактивированных аккаунтов. '~ 'Система '~System.Title~' сгенерирует PDF-файлы, РІ которых аккаунты Р±СѓРґСѓС‚ отсортированны РїРѕ курсам Рё группам или кафедрам для выбранного факультета') }} - {{ admin.action(URL.site('admin/accounts/getCodes'), URL.site('media/img/codes.png'), 'Получить РєРѕРґС‹ активации', + {{ admin.action(URL.site('admin/accounts/getActivationCodes'), URL.site('media/img/codes.png'), 'Получить РєРѕРґС‹ активации', 'Получить РєРѕРґС‹ активации для неактивированных аккаунтов. '~ 'Система '~System.Title~' сгенерирует PDF-файлы, РІ которых аккаунты Р±СѓРґСѓС‚ отсортированны РїРѕ курсам Рё группам или кафедрам для выбранного факультета') }} </div> diff --git a/~dev_rating/application/views/admin/base.twig b/~dev_rating/application/views/admin/base.twig index 067ded5bbc8cec2720e4cb5a369fbb19307895ae..bb81d0d224a235a7bd610dbc34f9914be1924275 100644 --- a/~dev_rating/application/views/admin/base.twig +++ b/~dev_rating/application/views/admin/base.twig @@ -34,10 +34,15 @@ <title>{% block title %}{% endblock %} | Admin - {{ System.Title }}</title> {{ HTML.style('media/css/admin/base.css')|raw }} {{ HTML.style('media/css/admin/macro.css')|raw }} - {{ HTML.style('media/css/actionButton.css')|raw }} - {{ HTML.script('media/js/jquery-1.11.1.min.js')|raw }} - {{ HTML.script('media/js/config.js')|raw }} - {% block media %}{% endblock %} + {{ HTML.style('media/css/actionButton.css')|raw }} + + + {{ HTML.script('media/js/jquery-1.11.1.min.js')|raw }} + {{ HTML.script('media/js/config.js')|raw }} + + {{ HTML.script('media/js/event_inspector/event_inspector.js')|raw }} + + {% block media %}{% endblock %} </head> <body> <div id="wrap"> @@ -50,7 +55,7 @@ {{ HTML.anchor('/admin', 'Панель администратора', {'title': 'Перейти РЅР° главную'})|raw }} </div> <div class="top_user"> - {{ User.First }} {{ User.Last }} | + {{ User.FirstName }} {{ User.LastName }} | {{ HTML.anchor('sign/out', 'Выход', {'title': 'Выход РёР· аккаунта'})|raw }} </div> </div> diff --git a/~dev_rating/application/views/admin/students/add.twig b/~dev_rating/application/views/admin/students/add.twig index b2880ebce3c9164163bc4706a526c17525e3b5a7..d9b47261634fdee4ce063f61d99f294b00f9a894 100644 --- a/~dev_rating/application/views/admin/students/add.twig +++ b/~dev_rating/application/views/admin/students/add.twig @@ -52,7 +52,7 @@ </optgroup> {% endfor %} </select> - <select id="studyGroupSelect"> + <select id="groupSelect"> <option value="0">--- Учебная РіСЂСѓРїРїР° ---</option> </select> </div> diff --git a/~dev_rating/application/views/admin/students/index.twig b/~dev_rating/application/views/admin/students/index.twig index 225eeb1770d79f599577258d430c0ae110915b71..420eb959d957913ef8551a34d4b056c61d432cce 100644 --- a/~dev_rating/application/views/admin/students/index.twig +++ b/~dev_rating/application/views/admin/students/index.twig @@ -46,7 +46,7 @@ </select> </div> <div class='filter'> - <select id="studyGroupSelect"> + <select id="groupSelect"> <option value="0">--- Учебная РіСЂСѓРїРїР° ---</option> </select> </div> diff --git a/~dev_rating/application/views/admin/students/profile.twig b/~dev_rating/application/views/admin/students/profile.twig index d3f191002913ae6d59f615231532b1b498f8e1fb..64fab11ae85febe9b109e83e4803f049f573299e 100644 --- a/~dev_rating/application/views/admin/students/profile.twig +++ b/~dev_rating/application/views/admin/students/profile.twig @@ -11,7 +11,7 @@ {% block main_content %} <div class="profilePage"> <div class="profile_clearFix"> - <div class="username">{{ Profile.First }} {{ Profile.Second }} {{ Profile.Last }}</div> + <div class="username">{{ Profile.FirstName }} {{ Profile.SecondName }} {{ Profile.LastName }}</div> </div> <div class="profile_clearFix"> <div class="label">Подразделение:</div> diff --git a/~dev_rating/application/views/admin/teachers/handler/listOutput.twig b/~dev_rating/application/views/admin/teachers/handler/listOutput.twig index def9e157c53b99ca70b91a6da2dc640f37e243a3..e88ce746d05d53fe6e75b7dd0114338a7bcaa08a 100644 --- a/~dev_rating/application/views/admin/teachers/handler/listOutput.twig +++ b/~dev_rating/application/views/admin/teachers/handler/listOutput.twig @@ -11,7 +11,7 @@ <div class="search_item"> <div class="search_item_info"> <div class="search_item_firstLine">{{ HTML.anchor('admin/profile/teacher/' ~ row.AccountID, - row.Last ~ ' ' ~ row.First ~ ' ' ~ row.Second)|raw }}</div> + row.LastName ~ ' ' ~ row.FirstName ~ ' ' ~ row.SecondName)|raw }}</div> <div class="search_item_secondLine">{{ row.JobPositionName }}, {{ row.DepartmentName|default('---') }}</div> </div> <div class="search_item_actions"> diff --git a/~dev_rating/application/views/admin/teachers/profile.twig b/~dev_rating/application/views/admin/teachers/profile.twig index da96c66d853a649909cc78fd7d939b111b6a651e..278632cbbe25ab800f876aac1801acf68503dc01 100644 --- a/~dev_rating/application/views/admin/teachers/profile.twig +++ b/~dev_rating/application/views/admin/teachers/profile.twig @@ -11,7 +11,7 @@ {% block main_content %} <div class="profilePage"> <div class="profile_clearFix"> - <div class="username">{{ Profile.First }} {{ Profile.Second }} {{ Profile.Last }}</div> + <div class="username">{{ Profile.FirstName }} {{ Profile.SecondName }} {{ Profile.LastName }}</div> </div> <div class="profile_clearFix"> <div class="label">Подразделение:</div> diff --git a/~dev_rating/application/views/base.twig b/~dev_rating/application/views/base.twig index bd916009b725efc58a91d2ef4dcaf914da1c00e7..47c0e4b35e3c2e3a3d838a15f0fdc1ad72fa5b04 100644 --- a/~dev_rating/application/views/base.twig +++ b/~dev_rating/application/views/base.twig @@ -33,7 +33,7 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>{% block title %}{% endblock %} | {{ System.Title }}</title> <meta http-equiv="Cache-Control" content="no-cache"> - <link href='http://fonts.googleapis.com/css?family=PT+Sans&subset=cyrillic-ext,latin' rel='stylesheet' type='text/css'> + <link href='https://fonts.googleapis.com/css?family=PT+Sans&subset=cyrillic-ext,latin' rel='stylesheet' type='text/css'> {# -------------------------------------------------------------------------------------------------------------- #} {{ HTML.style('media/less/common.css')|raw }} {# @@ -91,7 +91,7 @@ include 'messages/messages' #} <div id="username"> {{ HTML.image('media/img/user.png', {'height': '11px'})|raw }} - {{ User.First }} {{ User.Last }} + {{ User.FirstName }} {{ User.LastName }} </div> | {% if (User.RoleMark b-and 16) != 0 %} diff --git a/~dev_rating/application/views/dean_office/index.twig b/~dev_rating/application/views/dean_office/index.twig index 5dc89ae3ae88ac2b36f3c62f329a21492347f6de..e3a73a51fa51d43b72f9579e308bb4995f3a8d43 100644 --- a/~dev_rating/application/views/dean_office/index.twig +++ b/~dev_rating/application/views/dean_office/index.twig @@ -13,28 +13,34 @@ {% block main_content %} <div data-role="page" id="dean_office" style="text-align: center"> - <p><b>Шаг 1. Выберите форму аттестации</b></p> <div class="LayerSection"> + <p><b>Шаг 1. Выберите форму аттестации</b></p> <div class="itemBlock"> <div class="title">Форма контроля:</div> <div class="field"> <div class="ExamTypeDiv"> - <input id="ExamChoice" name="DisciplineType" type="radio" value="exam"> Ркзамен + <label> + <input id="ExamChoice" name="DisciplineType" type="radio" value="exam"> + Ркзамен + </label> </div> <div class="ExamTypeDiv"> - <input id="CreditChoice" name="DisciplineType" type="radio" value="credit" checked> Зачет + <label> + <input id="CreditChoice" name="DisciplineType" type="radio" value="credit" checked> + Зачет + </label> </div> </div> </div> </div> - <p><b>Шаг 2. Выберите РєСѓСЂСЃ</b></p> <div class="LayerSection"> + <p><b>Шаг 2. Выберите РєСѓСЂСЃ</b></p> <div class="itemBlock"> <div class="title">РљСѓСЂСЃ:</div> <div class="field"> - <select class="SelectGrade default_select" id="SelectGrade"> - <option>-РќРµ выбран-</option> + <select class="SelectGrade defaultForm" id="SelectGrade"> + <option>– РќРµ выбран –</option> {% for Grade in GradesList %} <option value="{{ Grade.ID }}" >{{ Grade.Title }}</option> {% endfor %} @@ -43,17 +49,19 @@ </div> </div> - <p><b>Шаг 3. Выберите РіСЂСѓРїРїСѓ</b></p> <div class="LayerSection"> + <p><b>Шаг 3. Выберите РіСЂСѓРїРїСѓ</b></p> <div class="itemBlock"> <div class="title">Группа:</div> <div class="field"> - <select class="SelectGroup default_select" id="SelectGroup" disabled> - <option>-РќРµ выбрана-</option> + <select class="SelectGroup defaultForm" id="SelectGroup" disabled> + <option>– РќРµ выбрана –</option> </select> </div> </div> - <button class="default_BlueButton" id="DownloadStatement" disabled>Скачать</button> + <div style="margin-top: 15px"> + <button class="defaultForm BlueButton" id="DownloadStatement" disabled="disabled">Скачать</button> + </div> </div> <div class="LayerSection" id="SelectDisciplineDiv" > @@ -61,19 +69,17 @@ <div class="itemBlock"> <div class="title">Дисциплина:</div> <div class="field"> - <select class="SelectDiscipline default_select" id="SelectDiscipline" disabled> - <option>-РќРµ выбрана-</option> + <select class="SelectDiscipline defaultForm" id="SelectDiscipline" disabled> + <option>– РќРµ выбрана –</option> </select> </div> </div> - <button class="default_BlueButton" id="DownloadExamDocument" disabled>Скачать</button> - <button class="default_BlueButton" id="BlockExamDiscipline" disabled>Блокировать</button> - <button class="default_BlueButton" id="BlockAndPrintExam" disabled>Блокировать Рё Скачать</button> + <div style="margin-top: 20px"> + <button class="defaultForm BlueButton HalfWidth" id="DownloadExamDocument" disabled="disabled">Скачать</button> + <button class="defaultForm BlueButton HalfWidth" id="BlockExamDiscipline" disabled="disabled">Блокировать</button> + <button class="defaultForm BlueButton HalfWidth" id="BlockAndPrintExam" disabled="disabled">Блокировать Рё Скачать</button> + </div> </div> - - - </div> - {% endblock %} diff --git a/~dev_rating/application/views/dean_office/students/handler/listOutput.twig b/~dev_rating/application/views/dean_office/students/handler/listOutput.twig new file mode 100644 index 0000000000000000000000000000000000000000..8d051a5a8b78248a92626e14bc1d2da57d3a6859 --- /dev/null +++ b/~dev_rating/application/views/dean_office/students/handler/listOutput.twig @@ -0,0 +1,37 @@ + +{# Вывод СЃРїРёСЃРєРѕРІ студентов #} +{% set pageNum = 1 %} +<div id="listPage{{ pageNum }}" class='paginatorPage'> +{% for row in List %} + {% if loop.index % 16 == 0 %} + {% set pageNum = pageNum + 1 %} + </div> + <div id="listPage{{ pageNum }}" class='paginatorPage hiddenPage'> + {% endif %} + <div class="search_item"> + <div class="search_item_info"> + <div class="search_item_firstLine">{{ HTML.anchor('dean_office/students/' ~ row.AccountID, + row.LastName ~ ' ' ~ row.FirstName ~ ' ' ~ row.SecondName)|raw }} ({{ row.Degree }}, {{ row.GradeNum }} РєСѓСЂСЃ, {{ row.GroupNum }} РіСЂСѓРїРїР°)</div> + </div> + <div class="search_item_actions"> + <a href="#" onclick="giveLeave({{ row.AccountID }})">Р’ академ</a> / + <a href="#" onclick="stopLeave({{ row.AccountID }})">РР· академа</a> + </div> + </div> +{% else %} + Нет результатов! +{% endfor %} +</div> + +{% if pageNum > 1 %} + <div class="paginator"> + <div class="paginator_title">Страницы:</div> + {% for i in range(1, pageNum) %} + {% if loop.first %} + <a href="#" class="paginatorLink" id='listPage{{ loop.index }}'><div class="paginator_item selectedPageNum">{{ loop.index }}</div></a> + {% else %} + <a href="#" class="paginatorLink" id='listPage{{ loop.index }}'><div class="paginator_item">{{ loop.index }}</div></a> + {% endif %} + {% endfor %} + </div> +{% endif %} diff --git a/~dev_rating/application/views/dean_office/students/index.twig b/~dev_rating/application/views/dean_office/students/index.twig new file mode 100644 index 0000000000000000000000000000000000000000..7d8cde28a48ce8b1d5bf4ab9afac280d5b7cd595 --- /dev/null +++ b/~dev_rating/application/views/dean_office/students/index.twig @@ -0,0 +1,67 @@ +{% extends 'base' %} + +{% block title %}Деканат > Ведомости{% endblock %} +{% block media %} + {{ HTML.style('media/css/admin/searchBox.css')|raw }} + {{ HTML.script('media/js/admin/students/index.js')|raw }} + {{ HTML.script('media/js/common/Studentslist.js')|raw }} +{% endblock %} + +{% block main_top_title %}Деканат > Студенты{% endblock %} +{% block main_content %} + <div class='search'> + <div class='search_box'> + <div class='search_inputs'> + <!--div class='search_mainInput'> + <input type='text' placeholder="РџРѕРёСЃРє РїРѕ фамилии, имени, отчеству"> + </div--> + <div class='search_inputFilters'> + <div class='filterLarge'> + <select id="facultySelect"> + <option value="0">--- Подразделение ЮФУ ---</option> + {% for row in Faculties %} + <option value="{{ row.ID }}">{{ row.Name }} ({{ row.Abbr }})</option> + {% endfor %} + </select> + </div> + <div class='filter'> + <select id="gradeSelect"> + <option value="0">--- РљСѓСЂСЃ ---</option> + {% for Degree in Grades %} + <optgroup label="{{ Degree.Title }}"> + {% for Grade in Degree.Grades %} + <option value="{{ Grade.ID }}">{{ Grade.Num }} РєСѓСЂСЃ</option> + {% endfor %} + </optgroup> + {% endfor %} + </select> + </div> + <div class='filter'> + <select id="groupSelect"> + <option value="0">--- Учебная РіСЂСѓРїРїР° ---</option> + </select> + </div> + </div> + </div> + </div> + <div class='search_results'> + <div class='search_results_title' id="search_title"> + + </div> + <div class='results' id='search_results'> + <div class='search_results_title'>Для отображения СЃРїРёСЃРєР° студентов <b>выберите</b> РѕРґРёРЅ РёР· пунктов или <b>введите</b> запрос РІ РїРѕРёСЃРєРѕРІРѕРµ поле.</div> + </div> + </div> + </div> + + <script type="application/javascript"> + function giveLeave(id) { + $.get(URLdir + 'handler/admStudents/giveLeave/?id=' + id); + } + + function stopLeave(id) { + $.get(URLdir + 'handler/admStudents/stopLeave/?id=' + id); + } + </script> +{% endblock %} + diff --git a/~dev_rating/application/views/profile/student.twig b/~dev_rating/application/views/profile/student.twig index 09d0903412a00a3091aba418892a4538c18df0b1..8ffb1191efb693df147487862092bddc36b21b4c 100644 --- a/~dev_rating/application/views/profile/student.twig +++ b/~dev_rating/application/views/profile/student.twig @@ -1,6 +1,6 @@ <div class="profile_wrapper" id="profileInfo" style="display: none;"> <div class="clearFix"> - <div class="username">{{ User.First }} {{ User.Second }} {{ User.Last }}</div> + <div class="username">{{ User.FirstName }} {{ User.SecondName }} {{ User.LastName }}</div> </div> <div class="clearFix"> <div class="label">Подразделение:</div> diff --git a/~dev_rating/application/views/profile/teacher.twig b/~dev_rating/application/views/profile/teacher.twig index 567363d84db1071a3c3e753f1e67471e5ab70691..8b2c4135438734ac1df1fd7770b8a5cc649ed849 100644 --- a/~dev_rating/application/views/profile/teacher.twig +++ b/~dev_rating/application/views/profile/teacher.twig @@ -1,6 +1,6 @@ <div class="profile_wrapper" id="profileInfo" style="display: none;"> <div class="clearFix"> - <div class="username">{{ User.First }} {{ User.Second }} {{ User.Last }}</div> + <div class="username">{{ User.FirstName }} {{ User.SecondName }} {{ User.LastName }}</div> </div> <div class="clearFix"> <div class="label">Подразделение:</div> diff --git a/~dev_rating/application/views/sign/up.twig b/~dev_rating/application/views/sign/up.twig index 9f854c6d4854a8d807d95b701e057c0890b329f6..aef48d40ec62722725166704cc3938bf049382b4 100644 --- a/~dev_rating/application/views/sign/up.twig +++ b/~dev_rating/application/views/sign/up.twig @@ -2,13 +2,11 @@ {% block title %}Активация аккаунта{% endblock %} {% block forms %} - <div> - {{ sign.input('activation_code', 'text', '', 'РљРѕРґ активации') }} - {{ sign.input('login', 'text', '', 'Логин') }} - {{ sign.input('password', 'password', '', 'Пароль') }} - {{ sign.input('confirm_password', 'password', '', 'Подтверждение пароля') }} - {{ sign.input('email', 'text', '', 'E-Mail адрес') }} - </div> + {{ sign.input('activation_code', 'text', '', 'РљРѕРґ активации') }} + {{ sign.input('login', 'text', '', 'Логин') }} + {{ sign.input('password', 'password', '', 'Пароль') }} + {{ sign.input('confirm_password', 'password', '', 'Подтверждение пароля') }} + {{ sign.input('email', 'text', '', 'E-Mail адрес') }} {{ sign.input('signup_b', 'button', 'Активировать') }} <div class='footer'> {{ HTML.anchor('sign/in', 'Войти РІ существующий аккаунт')|raw }} diff --git a/~dev_rating/application/views/student/subject.twig b/~dev_rating/application/views/student/subject.twig index 85633f01fe97771d1994fa800a5b651b5e14573d..7ff4982cdc4c1faee749aa1b3e30b0cc21cbd6b4 100644 --- a/~dev_rating/application/views/student/subject.twig +++ b/~dev_rating/application/views/student/subject.twig @@ -63,16 +63,16 @@ {% set FirstConjuction = ',' %} {% set SecondConjuction = ' Рё' %} {% elseif (Discipline.PracticeCount) or (Discipline.LabCount) %} - {% if Discipline.LectionCount %} + {% if Discipline.LectureCount %} {% set FirstConjuction = ' Рё' %} {% elseif Discipline.LabCount %} {% set SecondConjuction = ' Рё' %} {% endif %} {% endif %} - {% if Discipline.LectionCount %} - {{ Discipline.LectionCount }} - {{ Rus.NumEnding(Discipline.LectionCount, ['час', 'часа', 'часов']) }} + {% if Discipline.LectureCount %} + {{ Discipline.LectureCount }} + {{ Rus.NumEnding(Discipline.LectureCount, ['час', 'часа', 'часов']) }} теории{{ FirstConjuction }} {% endif %} {% if Discipline.PracticeCount %} diff --git a/~dev_rating/application/views/teacher/discipline/CreateDiscipline.twig b/~dev_rating/application/views/teacher/discipline/CreateDiscipline.twig index 5685cdb86a10b71517958c4f196e2809ad19fe2e..21fd24993800d57c351db2f8c94b926edbafd9ef 100644 --- a/~dev_rating/application/views/teacher/discipline/CreateDiscipline.twig +++ b/~dev_rating/application/views/teacher/discipline/CreateDiscipline.twig @@ -105,7 +105,7 @@ <div class="itemBlock"> <div class="title">Лекционных часов:</div> <div class="field"> - <input class="InputLectionCount defaultForm" type="text" style="width: 80px;" value="0"> + <input class="InputLectureCount defaultForm" type="text" style="width: 80px;" value="0"> </div> </div> </div> diff --git a/~dev_rating/application/views/teacher/discipline/EditGroups.twig b/~dev_rating/application/views/teacher/discipline/EditGroups.twig index 2fdb464f18bf265126be14ac28c6a66070b40fb7..c1387df0be4ae5879b4bc7711d730fc8cd56a377 100644 --- a/~dev_rating/application/views/teacher/discipline/EditGroups.twig +++ b/~dev_rating/application/views/teacher/discipline/EditGroups.twig @@ -11,7 +11,7 @@ <div class="ChangeStudyGroupDIV"> <select class="SelectStudyGroup defaultForm P1Width"> <option value="0">Выберите РіСЂСѓРїРїСѓ:</option> - {% for Group in StudyGroups %} + {% for Group in Groups %} <option value="{{ Group.ID }}">Группа {{ Group.GroupNum }}{% if Group.SpecName is not null %} - {{ Group.SpecName }}{% endif %}</option> {% endfor %} </select> diff --git a/~dev_rating/application/views/teacher/discipline/EditSettings.twig b/~dev_rating/application/views/teacher/discipline/EditSettings.twig index fe00004b66c1f7931b57cccbb3b0d106367481f4..ff0f595015f30de9ae1bdb3d17af8a58dddd7bf2 100644 --- a/~dev_rating/application/views/teacher/discipline/EditSettings.twig +++ b/~dev_rating/application/views/teacher/discipline/EditSettings.twig @@ -53,7 +53,7 @@ <div class="itemBlock"> <div class="title">РљСѓСЂСЃ:</div> <div class="field"> - <select class="SelectDisGrade defaultForm {% if Discipline.isLocked == 1 %}disabled_select{%endif%}" {% if Discipline.isLocked == 1 %}disabled{%endif%}> + <select class="SelectDisGrade defaultForm {% if Discipline.IsLocked == 1 %}disabled_select{%endif%}" {% if Discipline.IsLocked == 1 %}disabled{%endif%}> {% for Grade in GradesList %} <option value="{{ Grade.ID }}" {% if Grade.ID == Discipline.GradeID %}selected{% endif %}>{{ Grade.Title }}</option> {% endfor %} @@ -67,7 +67,7 @@ <div class="title">Бонусные баллы:</div> <div class="field"> <label> - <input name="BonusRate" class="BonusRate" type="checkbox" {% if Discipline.isLocked == 1 %}disabled{%endif%} {% if Discipline.isBonus == '1' %}checked{% endif %}> Добавить ли бонусные баллы? + <input name="BonusRate" class="BonusRate" type="checkbox" {% if Discipline.IsLocked == 1 %}disabled{%endif%} {% if Discipline.IsBonus == '1' %}checked{% endif %}> Добавить ли бонусные баллы? </label> </div> </div> @@ -78,12 +78,12 @@ <div class="field"> <div class="ExamTypeDiv"> <label> - <input name="ExamType" class="ExamType" type="radio" value="exam" {% if Discipline.isLocked == 1 %}disabled{%endif%} {% if Discipline.ExamType == 'exam' %}checked{% endif %}> Ркзамен + <input name="ExamType" class="ExamType" type="radio" value="exam" {% if Discipline.IsLocked == 1 %}disabled{%endif%} {% if Discipline.ExamType == 'exam' %}checked{% endif %}> Ркзамен </label> </div> <div class="ExamTypeDiv"> <label> - <input name="ExamType" class="ExamType" type="radio" value="credit" {% if Discipline.isLocked == 1 %}disabled{%endif%} {% if Discipline.ExamType == 'credit' %}checked{% endif %}> Зачет + <input name="ExamType" class="ExamType" type="radio" value="credit" {% if Discipline.IsLocked == 1 %}disabled{%endif%} {% if Discipline.ExamType == 'credit' %}checked{% endif %}> Зачет </label> </div> </div> @@ -93,7 +93,7 @@ <div class="itemBlock"> <div class="title">Лекционных часов:</div> <div class="field"> - <input class="InputLectionCount defaultForm" type="text" style="width: 80px;" value="{{ Discipline.LectureHours }}" {% if Discipline.isLocked == 1 %}disabled{%endif%}> + <input class="InputLectureCount defaultForm" type="text" style="width: 80px;" value="{{ Discipline.LectureHours }}" {% if Discipline.IsLocked == 1 %}disabled{%endif%}> </div> </div> </div> @@ -101,7 +101,7 @@ <div class="itemBlock"> <div class="title">Практических часов:</div> <div class="field"> - <input class="InputPracticeCount defaultForm" type="text" style="width: 80px;" value="{{ Discipline.PracticeHours }}" {% if Discipline.isLocked == 1 %}disabled{%endif%}> + <input class="InputPracticeCount defaultForm" type="text" style="width: 80px;" value="{{ Discipline.PracticeHours }}" {% if Discipline.IsLocked == 1 %}disabled{%endif%}> </div> </div> </div> @@ -109,7 +109,7 @@ <div class="itemBlock"> <div class="title">Лабораторных часов:</div> <div class="field"> - <input class="InputLabCount defaultForm" type="text" style="width: 80px;" value="{{ Discipline.LabHours }}" {% if Discipline.isLocked == 1 %}disabled{%endif%}> + <input class="InputLabCount defaultForm" type="text" style="width: 80px;" value="{{ Discipline.LabHours }}" {% if Discipline.IsLocked == 1 %}disabled{%endif%}> </div> </div> </div> diff --git a/~dev_rating/application/views/teacher/discipline/EditStructure.twig b/~dev_rating/application/views/teacher/discipline/EditStructure.twig index 0e50a898cd91c6f604d08ef948630aa8386908e8..921385c62b148e9a217936a604ef791ed8f6cef8 100644 --- a/~dev_rating/application/views/teacher/discipline/EditStructure.twig +++ b/~dev_rating/application/views/teacher/discipline/EditStructure.twig @@ -3,7 +3,7 @@ {% set step_2 = 'active' %} {% block discipline_media %} - {% if Discipline.isLocked != 1 %} + {% if Discipline.IsLocked != 1 %} {{ HTML.script('media/js/discipline/EditStructure.js')|raw }} {% else %} {{ HTML.script('media/js/discipline/EditStructureLocked.js')|raw }} @@ -21,7 +21,7 @@ <div class="name">Р’РёРґС‹ контрольных мероприятий</div> <div class="currentControl">Текущий контроль</div> <div class="landmarkControl">Рубежный контроль</div> - {% if Discipline.isLocked != 1 %} + {% if Discipline.IsLocked != 1 %} <div class="actions">Действия</div> {% endif %} </div> @@ -35,7 +35,7 @@ </div> <div class="currentControl">{{ Map[i].CurrentControl }}</div> <div class="landmarkControl">{{ Map[i].LandmarkControl }}</div> - {% if Discipline.isLocked != 1 %} + {% if Discipline.IsLocked != 1 %} <div class="actions"> <div class="deleteModule icon delete"> </div> <div class="downModule icon down"> </div> @@ -51,7 +51,7 @@ </div> <div class="currentControl"><input type="text" class="inputCredit inputCurrentControl" value="{% if Map[i][j].SubmoduleControl == 'CurrentControl' %}{{ Map[i][j].MaxRate }}{% else %}0{% endif %}"></div> <div class="landmarkControl"><input type="text" class="inputCredit inputLandmarkControl" value="{% if Map[i][j].SubmoduleControl == 'LandmarkControl' %}{{ Map[i][j].MaxRate }}{% else %}0{% endif %}"></div> - {% if Discipline.isLocked != 1 %} + {% if Discipline.IsLocked != 1 %} <div class="actions"> <div class="deleteSubmodule icon delete"></div> <div class="downSubmodule icon down"></div> @@ -61,7 +61,7 @@ </div> {% endfor %} </div> - {% if Discipline.isLocked != 1 %} + {% if Discipline.IsLocked != 1 %} <button class="addSubmodule">Добавить мероприятие</button> {% endif %} </div> @@ -88,7 +88,7 @@ <div class="empty"><p class="notification">Модули отсутствуют</p></div> {% endfor %} </div> - {% if Discipline.isLocked != 1 %} + {% if Discipline.IsLocked != 1 %} <button class="addModule">Добавить модуль</button> {% endif %} {% endblock %} diff --git a/~dev_rating/application/views/teacher/discipline/EditStudents.twig b/~dev_rating/application/views/teacher/discipline/EditStudents.twig index e144dc2afeeba9e239cdfec2fbdcf8d19ba6e5b2..ceda6a7c9dc7f7ade43ab72520528066126095df 100644 --- a/~dev_rating/application/views/teacher/discipline/EditStudents.twig +++ b/~dev_rating/application/views/teacher/discipline/EditStudents.twig @@ -9,8 +9,8 @@ {% macro outputStudent(Student) %} <div id="{{ Student.ID }}" class="Student {% if Student.Type == 'detach' %}StatusUnbind{% else %}StatusBind{% endif %}"> - <span class="Name">{{ Student.Last }} {{ Student.First }} {{ Student.Second }}</span> - {% if Student.Type == 'detach' %} + <span class="Name">{{ Student.LastName }} {{ Student.FirstName }} {{ Student.SecondName }}</span> + {% if Student.AttachType == 'detach' %} <button class="action Action_BindStudent">Прикрепить студента</button> {% else %} <button class="action Action_UnbindStudent">Отсоединить студента</button> @@ -74,7 +74,7 @@ </select> <select class="SelectStudyGroup defaultForm"> <option value="0">Выберите РіСЂСѓРїРїСѓ:</option> - {% for Group in StudyGroups %} + {% for Group in GroupsList %} <option value="{{ Group.ID }}">Группа {{ Group.GroupNum }} - {{ Group.SpecName }}</option> {% endfor %} </select> diff --git a/~dev_rating/application/views/teacher/discipline/EditTeachers.twig b/~dev_rating/application/views/teacher/discipline/EditTeachers.twig index e5c1ded5ecebd6971f10c0245638bcad096bc3b5..2549a4d829227bb0c3a50257ec52947cd5d13724 100644 --- a/~dev_rating/application/views/teacher/discipline/EditTeachers.twig +++ b/~dev_rating/application/views/teacher/discipline/EditTeachers.twig @@ -13,8 +13,8 @@ <h2 class="BlueTitle">Прикрепленные преподаватели</h2> {% for Teacher in BindTeachersList %} <div class="Teacher" id="{{ Teacher.ID }}"> - <div class="Name">{{ Teacher.Last }} {{ Teacher.First }} {{ Teacher.Second }}</div> - {% if Teacher.isAuthor == 0 %} + <div class="Name">{{ Teacher.LastName }} {{ Teacher.FirstName }} {{ Teacher.SecondName }}</div> + {% if Teacher.IsAuthor == 0 %} <button class="Action_UnbindTeacher Action">Отсоединить</button> <button class="Action_ChangeOwner Action">Передать дисциплину</button> {% else %} @@ -29,7 +29,7 @@ <input type="hidden" class="HiddenInputFacultyID" value="{{ Discipline.FacultyID }}"> <select class="SelectFaculty defaultForm"> {% for Faculty in FacultiesList %} - <option value="{{ Faculty.ID }}" {% if Discipline.FacultyID == Faculty.ID %}selected{% endif %}>{{ Faculty.Name }}</option> + <option value="{{ Faculty.ID }}" {% if User.FacultyID == Faculty.ID %}selected{% endif %}>{{ Faculty.Name }}</option> {% endfor %} </select> <select class="SelectDepartment defaultForm"> diff --git a/~dev_rating/application/views/teacher/discipline/MapBase.twig b/~dev_rating/application/views/teacher/discipline/MapBase.twig index ecb5eeaaed87b744949f5f28dddcbaca04713f2b..a7efb50992755b07fda2d0713734a80c14954146 100644 --- a/~dev_rating/application/views/teacher/discipline/MapBase.twig +++ b/~dev_rating/application/views/teacher/discipline/MapBase.twig @@ -13,7 +13,7 @@ {% block main_top_title %}Редактирование дисциплины{% endblock %} {% block main_content %} - {% if Discipline.isLocked == 1 %} + {% if Discipline.IsLocked == 1 %} <p class="Warning"> Был добавлен первый балл. Редактирование <u>базовых настроек</u>, <u>модулей</u> Рё <u>РіСЂСѓРїРї</u> невозможно. </p> diff --git a/~dev_rating/application/views/teacher/exam.twig b/~dev_rating/application/views/teacher/exam.twig index ff1f2fb1a0f86017c5e6089fa12008d0d0c3a265..8f993d58f41b2edb800a5e72e0182e33c52ae765 100644 --- a/~dev_rating/application/views/teacher/exam.twig +++ b/~dev_rating/application/views/teacher/exam.twig @@ -19,7 +19,7 @@ {% endif %} </h2> - {{ HTML.anchor('rate/'~disciplineInfo.ID, + {{ HTML.anchor('rate/'~disciplineInfo.DisciplineID, "в†ђ Перейти Рє оцениванию", {'title': 'Оценивание', 'class': 'rate_a'})|raw }} @@ -136,7 +136,7 @@ {% set row = row + 1 %} {% set col = 1 %} <tr id="row_{{ row }}" class="group_{{ group.GroupID }}"> - <td id="student_{{ student.ID }}" class="studentCell staticCell">{{ student.Last }} {{ student.First }}</td> + <td id="student_{{ student.ID }}" class="studentCell staticCell">{{ student.LastName }} {{ student.FirstName }}</td> <td class="semesterRateResultCell staticCell">{{ student.RateSemesterResult }}</td> {% set autoPassNotAdded = true %} @@ -150,7 +150,7 @@ {% set td_class = 'additionalCell' %} {% endif %} - {% if r.Block == 'True' %} + {% if r.Block == 'True' or (r.ModuleType != 'extra' and student.RateResult < 38) %} <td class="staticCell {{ td_class }}" id="col_{{ col }}_row_{{ row }}"> <input type="text" value="{{ r.Rate }}" disabled="disabled"> </td> diff --git a/~dev_rating/application/views/teacher/index.twig b/~dev_rating/application/views/teacher/index.twig index 957898d441973cbc42308dc04d10c746ad3e2ff0..5c633d0837f13f265618ec899902f4ad63be13ac 100644 --- a/~dev_rating/application/views/teacher/index.twig +++ b/~dev_rating/application/views/teacher/index.twig @@ -36,7 +36,7 @@ {% endfor %} </td> <td class='action_cell'> - {% if Discipline.isMapCreated %} + {% if Discipline.IsMapCreated %} {{ HTML.anchor('rate/'~Discipline.ID, "Оценивание", {'title': 'Выставление баллов РїРѕ дисциплине', 'class': 'disc_button active'})|raw }} @@ -47,8 +47,8 @@ {% endif %} </td> <td class='action_cell'> - {% if Discipline.isAuthor %} - {% if Discipline.isLocked %} + {% if Discipline.IsAuthor %} + {% if Discipline.IsLocked %} {% set btnName = "Просмотр" %} {% else %} {% set btnName = "Редактирование" %} @@ -65,7 +65,7 @@ {% endif %} </td> <td class='delete_cell'> - {% if Discipline.isLocked == 0 and Discipline.isAuthor == 1 %} + {% if Discipline.IsLocked == 0 and Discipline.IsAuthor == 1 %} {{Discipline.AuthorID}} <button class="DeleteDiscipline" id="{{ Discipline.ID }}" title="Удалить дисциплину"> </button> {% else %} diff --git a/~dev_rating/application/views/teacher/rating.twig b/~dev_rating/application/views/teacher/rating.twig index 409a08192d7f182f1db7845070a9c409857f0445..8f87f5833dfdf3ceb73c81ae1ecfd515632052c6 100644 --- a/~dev_rating/application/views/teacher/rating.twig +++ b/~dev_rating/application/views/teacher/rating.twig @@ -11,25 +11,25 @@ {% block main_top_title %}Выставление баллов{% endblock %} {% block main_content %} - {% if disciplineInfo.isMilestone > 0 %} - <p class="canNotEdit"> - Семестр завершен. Выставление баллов <u>запрещено</u>. - </p> - {% endif %} - {# - {% if disciplineInfo.ExamType == 'exam' %} - <p class="canNotEdit"> - Выставление баллов Р·Р° экзамен возможно только РЅР° странице "Сессия". - </p> - {% endif %} - #} + {% if disciplineInfo.isMilestone > 0 %} + <p class="canNotEdit"> + Семестр завершен. Выставление баллов <u>запрещено</u>. + </p> + {% endif %} + {# + {% if disciplineInfo.ExamType == 'exam' %} + <p class="canNotEdit"> + Выставление баллов Р·Р° экзамен возможно только РЅР° странице "Сессия". + </p> + {% endif %} + #} <h2 class="h2_titleSubject">{{ disciplineInfo.SubjectName }}</h2> <button class="downloadExcel" style="display: none">Скачать РІ excel формате [dev version]</button> - {{ HTML.anchor('exam/'~disciplineInfo.ID, - "Перейти Рє сессии в†’", - {'title': 'Сессия', 'class': 'exam_a'})|raw }} + {{ HTML.anchor('exam/'~disciplineInfo.DisciplineID, + "Перейти Рє сессии в†’", + {'title': 'Сессия', 'class': 'exam_a'})|raw }} <div class="groupSelectorWrap"> <div class="groupSelectorText">Фильтр:</div> @@ -42,14 +42,15 @@ </div> <p class="notification notif_rating" style="display: none">Обратите внимание, что пустая клетка эквивалентна нулю</p> - + <table class="studentsRate" border="0" cellspacing="0" cellpadding="0"> <tr class="RatingTableModulesHead"> <td class="title">Модуль</td> {% set rowSpan = 1 %} {% for i in 1..headerRate.ModulesCount %} {% if headerRate[i].ModuleType != 'regular' %} {% set rowSpan=2 %} {% endif %} - <td class="subject {% if headerRate[i].ModuleType == 'bonus' %}bonus{% endif %}" rowspan="{{rowSpan}}" colspan="{{headerRate[i].SubmodulesCount}}" > + <td class="subject {% if headerRate[i].ModuleType == 'bonus' %}bonus{% endif %}" rowspan="{{rowSpan}}" + {% if headerRate[i].ModuleType != 'extra' %} colspan="{{headerRate[i].SubmodulesCount}}" {% endif %} > {{ headerRate[i].ModuleTitle }} </td> {% endfor %} @@ -81,7 +82,11 @@ {% if headerRate[i].ModuleType == "exam" %} <td class="subject" id="{{ headerRate[i][j].SubmoduleID }}">{{ headerRate[i][j].MaxRate }}</td> {% elseif headerRate[i].ModuleType == "extra" %} - <td class="subject" id="{{ headerRate[i][j].SubmoduleID }}"></td> + {% if j==1 %} + <td class="subject" id="{{ headerRate[i][j].SubmoduleID }}"></td> + {% else %} + {% set CellCount = CellCount - 1 %} {# РїСЂРё наличии второго сабмодуля Сѓ РґРѕР±РѕСЂР° выводим только первый #} + {% endif %} {% else %} {% set col = col + 1 %} <td class="subject col_{{ col }}" id="{{ headerRate[i][j].SubmoduleID }}"> @@ -94,18 +99,18 @@ </tr> <tr class="RatingTableSubmodulesInfo"> - <td class="info"/> - - {% set col = 0 %} + <td class="info"></td> + + {% set col = 0 %} {% for i in 1..headerRate.ModulesCount %} - {% for j in 1..headerRate[i].SubmodulesCount %} + {% for j in 1..headerRate[i].SubmodulesCount if headerRate[i].ModuleType != "extra" or j==1 %} {% set col = col + 1 %} - <td class="info col_{{ col }}" id="{{ headerRate[i][j].SubmoduleID }}"/> + <td class="info col_{{ col }}" id="{{ headerRate[i][j].SubmoduleID }}"></td> {% endfor %} {% endfor %} - <td class="info"/> + <td class="info"></td> </tr> - + {% set row = 0 %} {% for group in rateTable %} <tr id="group_{{ group.GroupID }}" class="group_{{ group.GroupID }}"> @@ -113,10 +118,11 @@ </tr> {% for student in group.Students %} + {% set additionalRate = 0 %} {% set row = row + 1 %} {% set j = 0 %} <tr id="row_{{ row }}" class="group_{{ group.GroupID }}"> - <td id="student_{{ student.ID }}" class="studentCell staticCell">{{ student.Last }} {{ student.First }}</td> + <td id="student_{{ student.ID }}" class="studentCell staticCell">{{ student.LastName }} {{ student.FirstName }}</td> {% for i in 1..CellCount %} {% set j = j + 1 %} {% if student.Rates[i].SubmoduleID >= 0 and disciplineInfo.isMilestone == 0 %} @@ -125,11 +131,18 @@ </td> {% else %} {% set j = j - 1 %} - <td class="staticCell{% if student.Rates[i].Type == 'exam' %} examCell{% endif %}"> - <p>{{ student.Rates[i].Rate }}</p> - </td> + {% if student.Rates[i].Type == 'extra' %} + {% set additionalRate = additionalRate + student.Rates[i].Rate %} + {% else %} + <td class="staticCell{% if student.Rates[i].Type == 'exam' %} examCell{% endif %}"> + <p>{{ student.Rates[i].Rate }}</p> + </td> + {% endif %} {% endif %} {% endfor %} + <td class="staticCell"> + <p>{% if additionalRate != 0 %}{{additionalRate}}{% endif %}</p> + </td> <td class="rateResultCell staticCell">{% if student.RateResult > 100 %} 100+ {% else %} {{ student.RateResult }} {% endif %}</td> </tr> {% endfor %} diff --git a/~dev_rating/application/views/text_content/admin/development_warning.twig b/~dev_rating/application/views/text_content/admin/development_warning.twig index b0e472a047d61c52e01c0464ebe169add3bcd614..2943c983f7215a74ccb4b6882e73fcda9788a565 100644 --- a/~dev_rating/application/views/text_content/admin/development_warning.twig +++ b/~dev_rating/application/views/text_content/admin/development_warning.twig @@ -4,13 +4,13 @@ <p> <ul> <li>{{ HTML.anchor('admin/subjects/upload', 'Загрузка СЃРїРёСЃРєР° предметов')|raw }}</li> - <li>{{ HTML.anchor('admin/studygroups/upload', 'Загрузка СЃРїРёСЃРєР° учебных РіСЂСѓРїРї')|raw }}</li> + <li>{{ HTML.anchor('admin/groups/upload', 'Загрузка СЃРїРёСЃРєР° учебных РіСЂСѓРїРї')|raw }}</li> <li>{{ HTML.anchor('admin/students/upload', 'Загрузка СЃРїРёСЃРєР° студентов')|raw }}</li> <li>{{ HTML.anchor('admin/departaments/upload', 'Загрузка СЃРїРёСЃРєР° кафедр')|raw }}</li> <li>{{ HTML.anchor('admin/teachers/upload', 'Загрузка СЃРїРёСЃРєР° преподавателей')|raw }}</li> <li>{{ HTML.anchor('admin/students/add', 'Добавление РЅРѕРІРѕРіРѕ студента СЃ созданием аккаунта')|raw }}</li> <li>{{ HTML.anchor('admin/teachers/add', 'Добавление РЅРѕРІРѕРіРѕ преподавателя СЃ созданием аккаунта')|raw }}</li> - <li>{{ HTML.anchor('admin/accounts/activationРЎodes/get', 'Получение РєРѕРґРѕРІ активации для аккаунтов')|raw }}</li> + <li>{{ HTML.anchor('admin/accounts/getActivationCodes', 'Получение РєРѕРґРѕРІ активации для аккаунтов')|raw }}</li> <li>{{ HTML.anchor('admin/students/edit', 'Редактирование персональных данных студента')|raw }}</li> </ul> </p> \ No newline at end of file diff --git a/~dev_rating/index.php b/~dev_rating/index.php index 82fd3794dcff1df330c5e450a5f17121453bf544..0e5b82376e30c971eece0acd279cec0eab62baaf 100644 --- a/~dev_rating/index.php +++ b/~dev_rating/index.php @@ -133,8 +133,8 @@ else * Execute the main request. A source of the URI can be passed, eg: $_SERVER['PATH_INFO']. * If no source is specified, the URI will be automatically detected. */ - echo Request::factory(TRUE, array(), FALSE) + echo Request::factory($uri = TRUE, $client_params = array(), $allow_external = TRUE) ->execute() - ->send_headers(TRUE) + ->send_headers($replace_existing_headers = TRUE) ->body(); } diff --git a/~dev_rating/media/css/admin/base.css b/~dev_rating/media/css/admin/base.css index 24c55b7ea598871af0317d1e4a49aca339e05e2e..49656e572dfd9391ff54aa98291c17a48cabc9b3 100644 --- a/~dev_rating/media/css/admin/base.css +++ b/~dev_rating/media/css/admin/base.css @@ -245,7 +245,42 @@ html,body /*------------------------------------------------------------------------------------*/ - +#message { + height: 300px; + resize: vertical; +} +.EventInspectorList { + position: fixed; + height: auto; + min-width: 200px; + width: 15%; + top: 50px; + right: 20px; +} +.EventInspectorList .EventItem { + width: auto; + padding: 10px 15px; + margin-bottom: 10px; + border-radius: 4px; + font-size: 0.8em; + z-index: 500; +} +.EventInspectorList .success { + color: #3c763d; + background-color: #dff0d8; + border: 1px solid #d6e9c6; +} +.EventInspectorList .success:hover { + border-color: #80d570; +} +.EventInspectorList .error { + color: #a94442; + background-color: #f2dede; + border: 1px solid #ebccd1; +} +.EventInspectorList .error:hover { + border-color: #e09595; +} diff --git a/~dev_rating/media/css/discipline.css b/~dev_rating/media/css/discipline.css index 51764f2e0f5ee21fb89f4260561f7fe27d09f094..c0e9b57e1e918f9c801333c999fa211986eb41e0 100644 --- a/~dev_rating/media/css/discipline.css +++ b/~dev_rating/media/css/discipline.css @@ -133,7 +133,8 @@ color: #666666; } .LayerSection .itemBlock { - margin: 15px 0px; + margin: 10px 0; + display: inline-block; } .LayerSection .itemBlock .title { display: inline; diff --git a/~dev_rating/media/js/admin/accounts/codes.js b/~dev_rating/media/js/admin/accounts/codes.js index 7289277d987fb43a084b5f7fb53e7443f4079b8a..4de5992e2706983f36003297f965d8288349c1a4 100644 --- a/~dev_rating/media/js/admin/accounts/codes.js +++ b/~dev_rating/media/js/admin/accounts/codes.js @@ -56,11 +56,11 @@ $(function() 'facultyID': $('#facultySelect option:selected').val() }, successCallback: function (url) { - $('#downloadTeacherPDF').removeAttr('disabled'); + $('#downloadTeacherPDF').removeAttr('disabled'); }, failCallback: function (html, url) { - $('#downloadTeacherPDF').removeAttr('disabled'); - alert(html); + $('#downloadTeacherPDF').removeAttr('disabled'); + EventInspector_ShowMsg("Отсутствуют неактивированные аккаунты!", "success"); } }); }); @@ -75,11 +75,11 @@ $(function() 'gradeID': $('#gradeSelect option:selected').val() }, successCallback: function (url) { - $('#downloadStudentPDF').removeAttr('disabled'); + $('#downloadStudentPDF').removeAttr('disabled'); }, failCallback: function (html, url) { - $('#downloadStudentPDF').removeAttr('disabled'); - alert(html); + $('#downloadStudentPDF').removeAttr('disabled'); + EventInspector_ShowMsg("Отсутствуют неактивированные аккаунты!", "success"); } }); }); diff --git a/~dev_rating/media/js/admin/students/add.js b/~dev_rating/media/js/admin/students/add.js index 0ebe9988f3d816ac25b19f49213854b2d26f7b7b..24393e35dbe13aff17b43c810a6b9744d7b62879 100644 --- a/~dev_rating/media/js/admin/students/add.js +++ b/~dev_rating/media/js/admin/students/add.js @@ -2,9 +2,9 @@ $(function() { $("#facultySelect [value='0']").attr('selected', 'selected'); $("#gradeSelect [value='0']").attr('selected', 'selected'); - $("#studyGroupSelect [value='0']").attr('selected', 'selected'); + $("#groupSelect [value='0']").attr('selected', 'selected'); $('#gradeSelect').attr('disabled', 'disabled'); - $('#studyGroupSelect').attr('disabled', 'disabled'); + $('#groupSelect').attr('disabled', 'disabled'); $('#inputGroupSubmit').attr('disabled', 'disabled'); // Выбор факультета @@ -13,46 +13,46 @@ $(function() $("#search_results").html(''); $('#gradeSelect').removeAttr('disabled'); - $('#studyGroupSelect').attr('disabled', 'disabled'); - $("#studyGroupSelect").html('<option value="0">--- Учебная РіСЂСѓРїРїР° ---</option>'); + $('#groupSelect').attr('disabled', 'disabled'); + $("#groupSelect").html('<option value="0">--- Учебная РіСЂСѓРїРїР° ---</option>'); } else { $('#gradeSelect').attr('disabled', 'disabled'); - $('#studyGroupSelect').attr('disabled', 'disabled'); + $('#groupSelect').attr('disabled', 'disabled'); } }); // Выбор РєСѓСЂСЃР° $('#gradeSelect').change(function(){ $("#search_results").html(''); - $('#studyGroupSelect').attr('disabled', 'disabled'); - $("#studyGroupSelect").html('<option value="0">--- Учебная РіСЂСѓРїРїР° ---</option>'); + $('#groupSelect').attr('disabled', 'disabled'); + $("#groupSelect").html('<option value="0">--- Учебная РіСЂСѓРїРїР° ---</option>'); if (($('#gradeSelect option:selected').val()!= '0')) { - $.post(URLdir + 'handler/admStudents/getStudyGroups', + $.post(URLdir + 'handler/admStudents/getGroups', { 'facultyID': $('#facultySelect option:selected').val(), 'gradeNum': $('#gradeSelect option:selected').val() }, function(data){ $.each(data, function(i){ - $("#studyGroupSelect").append('<optgroup label="'+data[i].SpecName+'">'); + $("#groupSelect").append('<optgroup label="'+data[i].SpecName+'">'); $.each(data[i].Groups, function(j) { - $("#studyGroupSelect").append('<option value="'+data[i].Groups[j].ID+'">'+data[i].Groups[j].Num+' РіСЂСѓРїРїР°</option>'); + $("#groupSelect").append('<option value="'+data[i].Groups[j].ID+'">'+data[i].Groups[j].Num+' РіСЂСѓРїРїР°</option>'); }); - $("#studyGroupSelect").append('</optgroup>'); + $("#groupSelect").append('</optgroup>'); }); - $("#studyGroupSelect").removeAttr("disabled"); + $("#groupSelect").removeAttr("disabled"); }, "json"); } }); // Выбор РіСЂСѓРїРїС‹ - $('#studyGroupSelect').change(function(){ - if (($('#studyGroupSelect option:selected').val()!= '0')) { + $('#groupSelect').change(function(){ + if (($('#groupSelect option:selected').val()!= '0')) { $('#inputGroupSubmit').removeAttr('disabled'); } }); @@ -65,7 +65,7 @@ $(function() 'secondName': $('#secondName').val(), 'lastName': $('#lastName').val(), 'gradeNum': $('#gradeSelect option:selected').val(), - 'groupNum': $('#studyGroupSelect option:selected').val(), + 'groupNum': $('#groupSelect option:selected').val(), 'facultyID': $('#facultySelect option:selected').val() }, function(data){ diff --git a/~dev_rating/media/js/admin/students/index.js b/~dev_rating/media/js/admin/students/index.js index 416c335c63277fe3a6af6d6348380dab34299dbb..9954084f8cbc8eaaa860b879ace1bf0a06d363fe 100644 --- a/~dev_rating/media/js/admin/students/index.js +++ b/~dev_rating/media/js/admin/students/index.js @@ -2,10 +2,10 @@ $(function() { $("#facultySelect [value='0']").attr('selected', 'selected'); $("#gradeSelect [value='0']").attr('selected', 'selected'); - $("#studyGroupSelect [value='0']").attr('selected', 'selected'); + $("#groupSelect [value='0']").attr('selected', 'selected'); $('#gradeSelect').attr('disabled', 'disabled'); - $('#studyGroupSelect').attr('disabled', 'disabled'); + $('#groupSelect').attr('disabled', 'disabled'); // Переключение страниц $('body').on('click', '.paginatorLink', function(){ @@ -17,71 +17,60 @@ $(function() // Выбор факультета $('#facultySelect').change(function(){ - getStudentsList(); + //getStudentsList(); if (($('#facultySelect option:selected').val()!= '0')) { - - //$("#search_results").html('<div class="search_load"><img src="' + URLdir + 'media/img/load.gif"/></div>'); $('#gradeSelect').removeAttr('disabled'); - - //$.post(URLdir + 'handler/admStudents/getStudentsByFaculty', - //$.post(URLdir + 'handler/AdmStudents/getStudentsList', - //{ - // 'facultyID': $('#facultySelect option:selected').val(), - // 'gradeID': $('#gradeSelect option:selected').val(), - // 'groupID': $('#studyGroupSelect option:selected').val() - //}, - //function(data){ - // $("#search_results").replaceWith(GenerateInfoList(data)) - //}); } else { - $('#gradeSelect').attr('disabled', 'disabled'); + $('#gradeSelect').attr('disabled', 'disabled'); } - $('#studyGroupSelect').attr('disabled', 'disabled'); + $('#groupSelect').attr('disabled', 'disabled'); $("#studyGroupSelect").html('<option value="0">--- Учебная РіСЂСѓРїРїР° ---</option>'); }); // Выбор РєСѓСЂСЃР° $('#gradeSelect').change(function(){ - getStudentsList(); - $('#studyGroupSelect').attr('disabled', 'disabled'); - $("#studyGroupSelect").html('<option value="0">--- Учебная РіСЂСѓРїРїР° ---</option>'); + //getStudentsList(); + $('#groupSelect').attr('disabled', 'disabled'); + $("#groupSelect").empty(); + $("#groupSelect").html('<option value="0">--- Учебная РіСЂСѓРїРїР° ---</option>'); + if (($('#gradeSelect option:selected').val()!= '0')) { - $.post(URLdir + 'handler/admStudents/getStudyGroups', + $.post(URLdir + 'handler/admStudents/getGroups', { 'facultyID': $('#facultySelect option:selected').val(), 'gradeNum': $('#gradeSelect option:selected').val() }, function(data){ $.each(data, function(i){ - $("#studyGroupSelect").append('<optgroup label="'+data[i].SpecName+'">'); + //$("#groupSelect").append('<optgroup label="'+data[i].SpecName+'">'); $.each(data[i].Groups, function(j) { - $("#studyGroupSelect").append('<option value="'+data[i].Groups[j].ID+'">'+data[i].Groups[j].Num+' РіСЂСѓРїРїР°</option>'); + $("#groupSelect").append('<option value="'+data[i].Groups[j].ID+'">'+data[i].Groups[j].Num+' РіСЂСѓРїРїР°</option>'); }); - $("#studyGroupSelect").append('</optgroup>'); + $("#groupSelect").append('</optgroup>'); }); - $("#studyGroupSelect").removeAttr("disabled"); + $("#groupSelect").removeAttr("disabled"); }, "json"); } }); // Выбор РіСЂСѓРїРїС‹ - $('#studyGroupSelect').change(getStudentsList); + $('#groupSelect').change(getStudentsList); function getStudentsList() { $("#search_results").html('<div class="search_load"><img src="' + URLdir + 'media/img/load.gif"/></div>'); - $.post(URLdir + 'handler/admStudents/getStudentsList', + $.post(URLdir + 'handler/admStudents/getStudentsList?dean', { 'facultyID': $('#facultySelect option:selected').val(), 'gradeID': $('#gradeSelect option:selected').val(), - 'groupID': $('#studyGroupSelect option:selected').val() + 'groupID': $('#groupSelect option:selected').val() }, function(data){ $("#search_results").html(data); diff --git a/~dev_rating/media/js/dean_office/dean_office.js b/~dev_rating/media/js/dean_office/dean_office.js index 501aa5d05d5ba7bfbce49acd7fb64b36220382f5..5ff232b93e6a8d43806eedc32693eb6334053b3f 100644 --- a/~dev_rating/media/js/dean_office/dean_office.js +++ b/~dev_rating/media/js/dean_office/dean_office.js @@ -1,4 +1,5 @@ var $ = jQuery; +var langNotChosen = '– РќРµ выбрана –'; $(function() { @@ -39,8 +40,8 @@ $(function() { if(d.success === true) { console.log(d.data); var i = 0; - jSelectGroup.html("<option>-РќРµ выбрана-</option>"); - jSelectDiscipline.html("<option>-РќРµ выбрана-</option>"); + jSelectGroup.html("<option>" + langNotChosen + "</option>"); + jSelectDiscipline.html("<option>" + langNotChosen + "</option>"); for (i in d.data) { group = d.data[i]; @@ -55,11 +56,11 @@ $(function() { else { jSelectGroup.attr("disabled", "disabled"); - jSelectGroup.html("<option>-РќРµ выбрана-</option>"); + jSelectGroup.html("<option>" + langNotChosen + "</option>"); jDownloadStatement.attr("disabled", "disabled"); } - jDownloadExamDocument.attr("disabled", 1); + jDownloadExamDocument.attr("disabled", "disabled"); }); $("#SelectGroup").change(function() { @@ -78,7 +79,7 @@ $(function() { if (d.success === true) { console.log(d.data); var i = 0; - jSelectDiscipline.html("<option>-РќРµ выбрана-</option>"); + jSelectDiscipline.html("<option>" + langNotChosen + "</option>"); for (i in d.data) { discipline = d.data[i]; if (discipline.ExamType !== 'exam') @@ -93,14 +94,14 @@ $(function() { } else jDownloadStatement.attr("disabled", "disabled"); - jDownloadExamDocument.attr("disabled", 1); + jDownloadExamDocument.attr("disabled", "disabled"); }); $("#SelectDiscipline").change(function() { var disciplineID = parseInt($(this).val()) || 0; if (disciplineID > 0) jDownloadExamDocument.removeAttr("disabled"); - else jDownloadExamDocument.attr("disabled", 1); + else jDownloadExamDocument.attr("disabled", "disabled"); }); // Скачать ведомость diff --git a/~dev_rating/media/js/discipline/CreateDiscipline.js b/~dev_rating/media/js/discipline/CreateDiscipline.js index 15c5d5bef38d1f8cb13744a0a20bfffd8aa6478c..3d83078972f99e608caa9cfab2dec643e2003136 100644 --- a/~dev_rating/media/js/discipline/CreateDiscipline.js +++ b/~dev_rating/media/js/discipline/CreateDiscipline.js @@ -11,7 +11,7 @@ $(function() { { var errCount = 0; var jThis = $(this); - jThis.attr("disabled", true); + jThis.attr("disabled", true); var bonusRate = $(".BonusRate").prop("checked"); var subjectID = parseInt(jSubjectSelect.val()); @@ -40,7 +40,7 @@ $(function() { "SubjectID": subjectID, "BonusRate": bonusRate, "ExamType": examType, - "LectionCount": $("input.InputLectionCount").val(), + "LectureCount": $("input.InputLectureCount").val(), "LabCount": $("input.InputLabCount").val(), "PracticeCount": $("input.InputPracticeCount").val(), "FacultyID": $("select.SelectFaculty").val() @@ -49,10 +49,14 @@ $(function() { { data = $.parseJSON(data); if(data.success === true) { - setTimeout("location.replace('"+g_URLdir+"discipline/structure/"+data.DisciplineID+"')", 800); + setTimeout("location.replace('"+g_URLdir+"discipline/structure/"+data.DisciplineID+"')", 500); } else { jThis.removeAttr("disabled"); - EventInspector_ShowMsg("Ошибка РїСЂРё добавлении дисциплины", "error"); + + if (parseInt(data.code) === 1) + EventInspector_ShowMsg("Дисциплина СЃ таким РєСѓСЂСЃРѕРј уже существует", "error"); + else + EventInspector_ShowMsg("Ошибка РїСЂРё добавлении дисциплины", "error"); } } ); @@ -81,7 +85,7 @@ $(function() { // Р’ inputs часы (практ., лекц., лаб.) писать можно только цифры - $("input.InputLectionCount").keydown(function(event) { + $("input.InputLectureCount").keydown(function(event) { KeyDownOnlyNumber(event); }); diff --git a/~dev_rating/media/js/discipline/EditGroups.js b/~dev_rating/media/js/discipline/EditGroups.js index b3bb01c305f7cba87ee12cae1f605ec4c0952e92..5682e5cb4d3b3244072f2ddfb291f43f81c08ab6 100644 --- a/~dev_rating/media/js/discipline/EditGroups.js +++ b/~dev_rating/media/js/discipline/EditGroups.js @@ -31,7 +31,7 @@ $(function() { $.post( g_URLdir + "handler/map/BindGroup", { - "StudyGroupID": studyGroupID, + "GroupID": studyGroupID, "DisciplineID": g_disciplineID }, function(data) @@ -74,7 +74,7 @@ $(function() { $.post( g_URLdir + "handler/map/UnbindGroup", { - "StudyGroupID": studyGroupID, + "GroupID": studyGroupID, "DisciplineID": g_disciplineID }, function(data) diff --git a/~dev_rating/media/js/discipline/EditSettings.js b/~dev_rating/media/js/discipline/EditSettings.js index 21ca5944e6a256c1093441e8678b2f0e9555681b..bc605d2f49c7b4fe22055879dc02b32b88f577a5 100644 --- a/~dev_rating/media/js/discipline/EditSettings.js +++ b/~dev_rating/media/js/discipline/EditSettings.js @@ -5,7 +5,7 @@ $(function() { var bonusOld = $("input.BonusRate").prop("checked"); var controlOld = $("input.ExamType").filter(":checked"); - var lectionCount = parseInt($("input.InputLectionCount").val()); + var lectionCount = parseInt($("input.InputLectureCount").val()); var labCount = parseInt($("input.InputLabCount").val()); var practiceCount = parseInt($("input.InputPracticeCount").val()); @@ -46,7 +46,8 @@ $(function() { g_URLdir + "handler/map/ChangeDisciplineGrade", { "DisciplineID": g_disciplineID, - "GradeID": jThis.val() + "GradeID": jThis.val(), + "SubjectID": $("select.SelectSubject").val() }, function(data) { @@ -56,7 +57,11 @@ $(function() { } else { jThis.val(gradeOld); - EventInspector_ShowMsg("Ошибка: Рзменение РєСѓСЂСЃР°", "error"); + + if (parseInt(data.code) === 1) + EventInspector_ShowMsg("Дисциплина СЃ таким РєСѓСЂСЃРѕРј уже существует", "error"); + else + EventInspector_ShowMsg("Ошибка РїСЂРё изменении РєСѓСЂСЃР°", "error"); } jThis.removeAttr("disabled"); } @@ -129,7 +134,7 @@ $(function() { }; // Рзменение лекционных часов - $("input.InputLectionCount").focusout(function() + $("input.InputLectureCount").focusout(function() { var jThis = $(this); var value = parseInt($(this).val()); diff --git a/~dev_rating/media/js/discipline/EditStudents.js b/~dev_rating/media/js/discipline/EditStudents.js index 1aeb00c521de99923f673b45ff3c44cad667b9db..1e4e653dcecf97d33d01a7157ab5052c766aa98e 100644 --- a/~dev_rating/media/js/discipline/EditStudents.js +++ b/~dev_rating/media/js/discipline/EditStudents.js @@ -12,17 +12,17 @@ $(function() { var jSearchResult = $(".SearchResult").first(); var jStList = $("div.AttachedStudentsList"); - var jStudentPrototype = $($.parseHTML( "<div id='0' class='Student'>\ - <span class='Name'></span> \ - <span id='0' class='From'></span> \ - <button class='action'></button> \ - </div>")); + var jStudentPrototype = $($.parseHTML( "<div id='0' class='Student'>"+ + "<span class='Name'></span>"+ + "<span id='0' class='From'></span>"+ + "<button class='action'></button>"+ + "</div>")); var jStudentEmptyPrototype = $($.parseHTML( "<p class='notification'>Нет результатов... Возможно, студенты, соответствующие критериям РїРѕРёСЃРєР°, уже прикреплены.</p>")); - var jGroupWrapPrototype = $($.parseHTML( "<select class='SelectStudyGroup default_select'>\ + var jGroupWrapPrototype = $($.parseHTML( "<select class='SelectStudyGroup defaultForm'>\ <option value='0'>Выберите РіСЂСѓРїРїСѓ:</option>")); @@ -77,11 +77,7 @@ $(function() { return jClone; } - - - - function SearchStudents() - { + function SearchStudents() { var temp = $(".InputStudentName").val(); $.post( @@ -126,23 +122,31 @@ $(function() { ); //!post } + var typewatch = (function() { + var timer = 0; + return function(callback, ms) { + clearTimeout(timer); + timer = setTimeout(callback, ms); + }; + })(); - $(".searchBtn").click(function(){ - SearchStudents(); - $(this).blur(); - }); - - $(".InputStudentName").keydown(function(e) { - if(e.which == 13) { + var updateList = function(e) { + typewatch(function() { SearchStudents(); $(this).blur(); - } - }); + }, 700); + }; + + $(".searchBtn").click(updateList); + + jStudentInput + .keyup(updateList) + .bind("paste", updateList); - function GetStudyGroups() { + function GetGroups() { $.post( - g_URLdir + "handler/map/GetStudyGroups", + g_URLdir + "handler/map/GetGroups", { "FacultyID": g_facultyID, "GradeID": jGradeSelect.val() @@ -171,8 +175,8 @@ $(function() { ); //!post } - $(".SelectGrade").change(function(){ - GetStudyGroups(); + jGradeSelect.change(function(){ + GetGroups(); }); diff --git a/~dev_rating/media/js/discipline/EditTeachers.js b/~dev_rating/media/js/discipline/EditTeachers.js index af0cc26a59de7ef6dba4fbc941a3688408448244..d829ca451342b6d09c67b11823aebde98b7e3c46 100644 --- a/~dev_rating/media/js/discipline/EditTeachers.js +++ b/~dev_rating/media/js/discipline/EditTeachers.js @@ -32,8 +32,12 @@ $(function() { // РџРѕРёСЃРє преподавателей function CallSearchTeachers(){ - var name = []; - name = jNameFilterInput.val().split(" "); + /* + It is a bad idea to make an ajax request every time, you want to refresh list. + The better solution: use list.js extension, and load the whole list with the first page load. + */ + var source = jNameFilterInput.val(); + var name = source.split(" "); $.post( URLdir + "handler/map/SearchTeachers", { @@ -100,18 +104,26 @@ $(function() { // } // }); + var typewatch = (function() { + var timer = 0; + return function(callback, ms) { + clearTimeout(timer); + timer = setTimeout(callback, ms); + }; + })(); - $(".searchBtn").click(function(){ - CallSearchTeachers(); - $(this).blur(); - }); - - $(".InputStudentName").keydown(function(e) { - if(e.which == 13) { + var updateList = function(e) { + typewatch(function() { CallSearchTeachers(); $(this).blur(); - } - }); + }, 700); + }; + + $(".searchBtn").click(updateList); + + $(".InputTeacherName") + .keyup(updateList) + .bind("paste", updateList); // Конец РїРѕРёСЃРєР° преподавателей diff --git a/~dev_rating/media/js/discipline/general.js b/~dev_rating/media/js/discipline/general.js index 589444dc989be15408e0265b09859023640a656b..0418f70db0622c3dfc02f712515a2a5422164eca 100644 --- a/~dev_rating/media/js/discipline/general.js +++ b/~dev_rating/media/js/discipline/general.js @@ -11,29 +11,34 @@ $(function() { // Получить СЃРїРёСЃРѕРє РІ память function GetSubjectsList() { - var g_facultyID = 0; var optionVal = parseInt($("select.SelectFaculty").children("option:selected").val()); if (optionVal <= 0) return; - - var g_facultyID = optionVal; + + selectSubject.attr("disabled", true); $.post( g_URLdir + "handler/map/GetSubjectsList", { - "FacultyID": g_facultyID + "FacultyID": optionVal }, function(data) { selectSubject.select2("val", ""); - selectSubject.attr("disabled", true); data = (data !== "") ? $.parseJSON(data) : {}; var jProto = $($.parseHTML("<option></option>")); selectSubject.html(""); - + + selectSubject.append($.parseHTML("<option></option>")); $.each(data, function (key, cur) { jProto.html(cur.Title).val(cur.ID); selectSubject.append(jProto.clone()); - }); + }); + } + ).always( + function(success) + { + if (selectSubject.children().first().is(":selected")) + selectSubject.select2({placeholder: "Выберите предмет", allowClear: true}); selectSubject.removeAttr("disabled"); } ); diff --git a/~dev_rating/media/js/rating.js b/~dev_rating/media/js/rating.js index 6ad262cf72225577f1c33630b15c6d16ecc5ad32..7a7835e5622f29adc1d82cb2dda9e97e672b26a8 100644 --- a/~dev_rating/media/js/rating.js +++ b/~dev_rating/media/js/rating.js @@ -21,28 +21,28 @@ $(function() { $("div.main_content").ready(AdjustTable); $(window).resize(AdjustTable); + function controlRowVisualization(jRow) { + var jAutoPassCheckBox = jRow.children(".autoPass").children(".autoPassCheck"); + var semesterRate = parseInt(jRow.children(".semesterRateResultCell").text()); + var absence = jRow.children(".absenceCell").children(".absenceCheck").is(":checked"); + if ((semesterRate < 60) || (absence)) + jAutoPassCheckBox.attr("disabled", true); + else + jAutoPassCheckBox.removeAttr("disabled"); + } - - function controlRowVisualization(jRow) { - var jAutoPassCheckBox = jRow.children(".autoPass").children(".autoPassCheck"); - var semesterRate = parseInt(jRow.children(".semesterRateResultCell").text()); - var absence = jRow.children(".absenceCell").children(".absenceCheck").is(":checked"); - if ((semesterRate < 60) || (absence)) - jAutoPassCheckBox.attr("disabled", true); - else - jAutoPassCheckBox.removeAttr("disabled"); - } - - function controlVisualization() { - $(".autoPassCheck") + function controlVisualization() { + $(".autoPassCheck") .each( function() { - controlRowVisualization($(this).parent().parent()); - }); - } + controlRowVisualization($(this).parent().parent()); + }); + } - // on page loaded controlVisualization(); - + + // on page loaded + //controlVisualization(); + var g_col; var g_row; var g_isFocusCell = false; // Стоит фокус РЅР° ячейки или нет @@ -62,20 +62,19 @@ $(function() { // + ID - id дисциплины // + studyGroupID_Filter - studyGroupID для фильтра (Рффект памяти) var json_settings = $.parseJSON($("#hidden_div").html()); - //console.log(json_settings); $("#hidden_div").remove(); - filterGroups(json_settings.StudyGroupID_Filter); - $(".groupSelector [value='"+ json_settings.StudyGroupID_Filter +"']").attr("selected", "selected"); + filterGroups(json_settings.GroupID_Filter); + $(".groupSelector [value='"+ json_settings.GroupID_Filter +"']").attr("selected", "selected"); // Скрываем РІСЃРµ остальные РіСЂСѓРїРїС‹ // 0 - показать РІСЃРµ function filterGroups(groupID) { if (groupID == 0) { $(".studentsRate tbody") - .children() - .each( function() { + .children() + .each( function() { $(this).show(); - }); + }); } else { $(".studentsRate tbody") .children(":gt(2)") @@ -91,10 +90,10 @@ $(function() { // Ставим подстветку function TdFocus(jThis){ g_col = jThis.attr('id'); - g_col = parseInt(g_col.substr(4)); + g_col = parseInt(g_col.substr(4)); g_row = jThis.parent('tr').attr('id'); - g_row = parseInt(g_row.substr(4)); - + g_row = parseInt(g_row.substr(4)); + g_oldRateCell = jThis.children("input").val(); $("td#col_" + g_col + ".commonCell").each(function(){ $(this).children('input').css("background-color", "#f1f1f1"); @@ -112,7 +111,7 @@ $(function() { }); jThis.children('input').css("background-color", "#fff"); } - + // Убираем подстветку function TdUnFocus(){ $("td#col_" + g_col + ".commonCell").each(function(){ @@ -130,39 +129,38 @@ $(function() { $(this).children('input').css("background-color", "#fff"); }); } - + function TdInfo(jThis) { - var disciplineType = json_settings.ExamType; - var disciplinePassRate = 60; // credit pass rate - if (disciplineType === "exam") - disciplinePassRate = 38; + var disciplineType = json_settings.ExamType; + var disciplinePassRate = 60; // credit pass rate + if (disciplineType === "exam") + disciplinePassRate = 38; // Получаем подмодуль var jCurSubmoduleInfo = $(".RatingTableSubmodulesInfo .col_"+g_col+":first"); var jCurSubmoduleHead = $(".RatingTableSubmodulesHead .col_"+g_col+":first"); - g_submoduleID = parseInt(jCurSubmoduleInfo.attr("id")); + g_submoduleID = parseInt(jCurSubmoduleInfo.attr("id")); g_submoduleTitle = jCurSubmoduleHead.text(); if (jCurSubmoduleHead.length < 1 && $(".RatingTableModulesHead .bonus").length > 0 ) g_submoduleTitle = 'Бонусные баллы'; - g_submoduleMaxRate = parseInt($(".RatingTableSubmodulesHeadMaxRate .col_"+g_col).text()); - console.log(g_col); + g_submoduleMaxRate = parseInt($(".RatingTableSubmodulesHeadMaxRate .col_"+g_col).text()); + - - // Проверяем допустимое значение (только для РґРѕР±РѕСЂР°) + // Проверяем допустимое значение (только для РґРѕР±РѕСЂР°) if (jThis.attr("class").indexOf("additionalCell") >= 0) { - var semesterRate = parseInt(jThis.siblings(".semesterRateResultCell").text()); - if (semesterRate <= disciplinePassRate) - g_submoduleMaxRate = disciplinePassRate - semesterRate; - else - g_submoduleMaxRate = 0; + var semesterRate = parseInt(jThis.siblings(".semesterRateResultCell").text()); + if (semesterRate <= disciplinePassRate) + g_submoduleMaxRate = disciplinePassRate - semesterRate; + else + g_submoduleMaxRate = 0; } // Получаем студента g_studentID = jThis.siblings('.studentCell').attr("id"); - g_studentID = g_studentID.substr(8); - + g_studentID = g_studentID.substr(8); + g_stdName = jThis.siblings('.studentCell').text(); jTdInfo_wrap.show(); @@ -186,172 +184,290 @@ $(function() { oldRate = parseInt(oldRate); // Здесь jThis - div rateCell, Р° РЅРµ input, который является дочкой jThis.children("input").attr("disabled", true); - - var newRate = 0; - if (jThis.children("input").val() !== "") - newRate = parseInt(jThis.children("input").val()); - var rateResult = newRate; - - // считаем баллы РїРѕ строке - if ($("#pageType").val() === "exam") //(jThis.attr("class").indexOf("attemptCell") >= 0) - { - // страница сессии - rateResult += parseInt(jThis.siblings(".semesterRateResultCell").text()); - - jThis.siblings(".additionalCell").each(function(){ - if ($(this).children("input").val() !== "") - rateResult += parseInt($(this).children("input").val()); - }); - } - else if ($("#pageType").val() === "rating") - { - // страница оценивания - jThis.siblings(".commonCell").each(function(){ // добавим СЃСѓРјРјСѓ баллов РІ соседних ячейках - var rate = $(this).children("input").val(); - if (rate) - rateResult += parseInt(rate); - }); - var examRateStr = jThis.siblings(".examCell").children("p").text(); - if (examRateStr) - rateResult += parseInt(examRateStr); - } - - if (newRate <= g_submoduleMaxRate) - { - $.ajax({ - type: "POST", - url: URLdir + "handler/rating/setRate", - data: "student="+g_studentID+"&submodule="+g_submoduleID+"&rate="+newRate, - statusCode: { - 403: function() { - EventInspector_ShowMsg("Сессия истекла", "error"); - jThis.children("input").val(oldRate); - jThis.children("input").removeAttr("disabled"); - window.location.replace(URLdir); - }, - 200: function(data) { - data = $.parseJSON(data); - if(data.success === true) { - var correctRate = (rateResult > 100) ? '100+' : rateResult; - jThis.siblings(".rateResultCell").text(correctRate); - EventInspector_ShowMsg("Балл добавлен/изменен", "success"); - } - else EventInspector_ShowMsg("РќРµ удалось добавить/изменить балл", "error"); - jThis.children("input").removeAttr("disabled"); - } - } - }); - } - else { - if (oldRate <= g_submoduleMaxRate) - jThis.children("input").val(oldRate); - else - jThis.children("input").val("0"); - - EventInspector_ShowMsg("Текущий балл превышает максимальный для данного модуля", "error"); - jThis.children("input").removeAttr("disabled"); - } + + var newRate = 0; + if (jThis.children("input").val() !== "") + newRate = parseInt(jThis.children("input").val()); + var rateResult = newRate; + + // считаем баллы РїРѕ строке + if ($("#pageType").val() === "exam") //(jThis.attr("class").indexOf("attemptCell") >= 0) + { + // страница сессии + rateResult += parseInt(jThis.siblings(".semesterRateResultCell").text()); + + jThis.siblings(".additionalCell").each(function(){ + if ($(this).children("input").val() !== "") + rateResult += parseInt($(this).children("input").val()); + }); + + /* + if (jThis.hasClass("additionalCell")) { + //console.log(jThis); + nextAdditionalCell = $("#col_"+(g_col + 1)+"_row_"+g_row);//.removeAttr("disabled"); + console.log(nextAdditionalCell); + + placeholder_max = (rateResult <= 60) ? (60 - rateResult) : (60 - oldRate); + + nextAdditionalCell.find("input").attr("placeholder", "макс. "+(placeholder_max)); + nextAdditionalCell.find("input").removeAttr("disabled"); + + //alert(col); + }*/ + } + else if ($("#pageType").val() === "rating") + { + // страница оценивания + jThis.siblings(".commonCell").each(function(){ // добавим СЃСѓРјРјСѓ баллов РІ соседних ячейках + var rate = $(this).children("input").val(); + if (rate) + rateResult += parseInt(rate); + }); + var examRateStr = jThis.siblings(".examCell").children("p").text(); + if (examRateStr) + rateResult += parseInt(examRateStr); + var additionalRateStr = jThis.siblings(".staticCell").children("p").text(); + if (additionalRateStr) + rateResult += parseInt(additionalRateStr); + } + + + if (newRate <= g_submoduleMaxRate) + { + + $.ajax({ + type: "POST", + url: URLdir + "handler/rating/setRate", + data: "student="+g_studentID+"&submodule="+g_submoduleID+"&rate="+newRate, + complete: function(jqXHR, textStatus) { + switch(jqXHR.status) { + case 403: + EventInspector_ShowMsg("Сессия истекла", "error"); + jThis.children("input").val(oldRate); + jThis.children("input").removeAttr("disabled"); + window.location.replace(URLdir); + break; + case 200: + data = $.parseJSON(jqXHR.responseText); + if(data.success === true) { + var correctRate = (rateResult > 100) ? '100+' : rateResult; + jThis.siblings(".rateResultCell").text(correctRate); + + // Открываем доступ СЃ след. ячейки РґРѕР±РѕСЂР° балла + if (jThis.hasClass("additionalCell")) { + //console.log(jThis); + nextAdditionalCell = $("#col_"+(g_col + 1)+"_row_"+g_row);//.removeAttr("disabled"); + console.log(nextAdditionalCell); + + placeholder_max = (rateResult <= 60) ? (60 - rateResult) : (60 - oldRate); + + nextAdditionalCell.find("input").attr("placeholder", "макс. "+(placeholder_max)); + nextAdditionalCell.find("input").removeAttr("disabled"); + } + + EventInspector_ShowMsg("Балл добавлен/изменен", "success"); + } + else EventInspector_ShowMsg("РќРµ удалось добавить/изменить балл", "error"); + jThis.children("input").removeAttr("disabled"); + break; + default: + EventInspector_ShowMsg(" "+statusCode, "success"); + } + + } + //statusCode: { + // 403: function() { + // EventInspector_ShowMsg("Сессия истекла", "error"); + // jThis.children("input").val(oldRate); + // jThis.children("input").removeAttr("disabled"); + // window.location.replace(URLdir); + // }, + // 200: function(data) { + // data = $.parseJSON(data); + // if(data.success === true) { + // var correctRate = (rateResult > 100) ? '100+' : rateResult; + // jThis.siblings(".rateResultCell").text(correctRate); + // EventInspector_ShowMsg("Балл добавлен/изменен", "success"); + // } + // else EventInspector_ShowMsg("РќРµ удалось добавить/изменить балл", "error"); + // jThis.children("input").removeAttr("disabled"); + // } + //} + }); + } + else { + if (oldRate <= g_submoduleMaxRate) + { + if(oldRate != -1) + jThis.children("input").val(oldRate); + else + jThis.children("input").val(""); + } + else + jThis.children("input").val("0"); + + EventInspector_ShowMsg("Текущий балл превышает максимальный для данного модуля", "error"); + jThis.children("input").removeAttr("disabled"); + } } - + $(".commonCell").mouseenter(function(){ if (g_isFocusCell === false) TdFocus($(this)); }); - + $(".commonCell").mouseleave(function(){ if (g_isFocusCell === false) TdUnFocus(); }); - + var oldRate = 0; $(".commonCell").focusin(function(){ g_isFocusCell = true; TdFocus($(this)); TdInfo($(this)); + if ($(this).children("input").val() !== "") + { oldRate = $(this).children("input").val(); - else oldRate = 0; + } + else oldRate = -1; }); - + $(".commonCell").focusout(function(){ g_isFocusCell = false; var newRate = 0; + + //alert(123); if ($(this).children("input").val() !== "") - newRate = $(this).children("input").val(); - if (newRate != oldRate) - Rating($(this), oldRate); + { + + newRate = parseInt($(this).children("input").val()); + + if (newRate != oldRate) + { + Rating($(this), oldRate); + } + } + TdUnFocus(); UnsetTdInfo($(this)); - controlRowVisualization($(this).parent()); + controlRowVisualization($(this).parent()); }); - - $(".commonCell").keyup(function(e){ - - var jThis = $(this); + + var Direction = { + Up: 0, + Right: 1, + Down: 2, + Left: 3 + }; + + /** + * @param direction Direction РІ каком направлении искать следующую ячейку для перемещения фокуса + * @return jQuery клетка, РІ которую надо переместиться или null, если РІ этом направлении нет подходящих ячеек + */ + function getDesiredCell(direction) { + /** Будем искать ячейку РІ направлении {@see direction} РґРѕ тех РїРѕРєР° РЅРµ найдем её Рё РїРѕРєР° РЅРµ + * кончатся ячейки РІ этом направлении */ var row = g_row; var col = g_col; + var currentCell; + switch (direction) { + case Direction.Up: + do { + row--; + currentCell = $("tr#row_" + row + " td#col_" + g_col + ".commonCell") + } while ((currentCell.length > 0) && + (currentCell.children("input").attr("disabled") == "disabled")); + return currentCell; + case Direction.Right: + do { + col++; + currentCell = $("tr#row_" + g_row + " td#col_" + col + ".commonCell") + } while ((currentCell.length > 0) && + (currentCell.children("input").attr("disabled") == "disabled")); + return currentCell; + case Direction.Down: + do { + row++; + currentCell = $("tr#row_" + row + " td#col_" + g_col + ".commonCell") + } while ((currentCell.length > 0) && + (currentCell.children("input").attr("disabled") == "disabled")); + return currentCell; + case Direction.Left: + do { + col--; + currentCell = $("tr#row_" + g_row + " td#col_" + col + ".commonCell") + } while ((currentCell.length > 0) && + (currentCell.children("input").attr("disabled") == "disabled")); + return currentCell; + } + return null; + } - // РџСЂРё нажатие Enter (переход Рє оцениванию след. студента, С‚.Рµ. ниже) - if(e.keyCode==13) - row = row + 1; - - // Стрелка вверх - if(e.keyCode==38) - row = row - 1; - - // Стрелка вправо - if(e.keyCode==39) - col = col + 1; - - // Стрелка РІРЅРёР· - if(e.keyCode==40) - row = row + 1; - - // Стрелка влево - if(e.keyCode==37) - col = col - 1; - - if ((e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 ) { - var jTempObj = $("tr#row_" + row + " td#col_" + col + ".commonCell"); - if (jTempObj.length > 0) { - TdUnFocus(); - g_row = row; - g_col = col; - jTempObj.children("input").focus(); - } + $(".commonCell").keydown(function(e){ + var row = g_row; + var col = g_col; + var direction; + switch (e.keyCode) { + case 13: // enter + direction = Direction.Down; + break; + case 38: // up arrow + direction = Direction.Up; + break; + case 39: // right arrow + direction = Direction.Right; + break; + case 40: // down arrow + direction = Direction.Down; + break; + case 37: // left arrow + direction = Direction.Left; + break; + default: + return; } + var whereToMoveFocus = getDesiredCell(direction); + if (whereToMoveFocus.length > 0) { + TdUnFocus(); + g_row = row; + g_col = col; + whereToMoveFocus.children("input").focus(); + } else + $(this).children("input").blur(); }); - + $(".commonCell input").focusin(function(){ $(this).select(); }); - + // РџСЂРё нажатии РЅР° элемент commonCell дочерный input получает фокус $(".commonCell ").click(function(){ $(this).children("input").focus(); } ); - + // Р’ inputCredit (РіРґРµ баллы вводить) разрешаем вводить только цифры $(".commonCell").children("input").keydown(function(event) { KeyDownOnlyNumber(event); }); - - // Нажатие РЅР° чекбокс "Автомат" - $(".absenceCheck").click(function(event) { - controlRowVisualization($(this).parent().parent()); + + // Нажатие РЅР° чекбокс "Неявка" + $(".absenceCheck").click(function(event) { + controlRowVisualization($(this).parent().parent()); }); // Фильтр РїРѕ РіСЂСѓРїРїРµ $(".groupSelector").change(function() { - var group = $(this).val(); + var group = $(this).val(); if (group >= 0) { filterGroups(group); $.post( URLdir + "handler/rating/SelectGroup", - { + { "disciplineID": g_disciplineID, - "groupSelected": group + "groupSelected": group }, function(data){ data = $.parseJSON(data); @@ -367,7 +483,7 @@ $(function() { $(".downloadExcel").click(function(){ $.fileDownload(URLdir + 'handler/FileCreator/GenerateExcelRatingTable', { httpMethod: "POST", - data: + data: { 'disciplineID': g_disciplineID }, @@ -381,10 +497,10 @@ $(function() { }); // Ведомость РІ формате excel - $('body').on('click', '.downloadExcelStatement', function(){ + $('body').on('click', '.downloadExcelStatement', function(){ $.fileDownload(URLdir + 'handler/FileCreator/GenerateFinalForm', { httpMethod: "POST", - data: + data: { "disciplineID": g_disciplineID, "studyGroupID": parseInt($(this).attr("id").substr(6)) @@ -398,7 +514,7 @@ $(function() { }); }); - + }); diff --git a/~dev_rating/media/js/select2.js b/~dev_rating/media/js/select2.js index 7590b82295325b277441528766d83e9010f00c27..6e5fe0ba49fcc8eb5674a32bfa0d6b40c61b8ca3 100644 --- a/~dev_rating/media/js/select2.js +++ b/~dev_rating/media/js/select2.js @@ -3509,7 +3509,18 @@ the specific language governing permissions and limitations under the Apache Lic formatSearching: function () { return "Searching…"; } }; - $.extend($.fn.select2.defaults, $.fn.select2.locales['en']); + $.fn.select2.locales['ru'] = { + formatMatches: function (matches) { if (matches === 1) { return "One result is available, press enter to select it."; } return matches + " results are available, use up and down arrow keys to navigate."; }, + formatNoMatches: function () { return "Совпадений РЅРµ найдено"; }, + formatAjaxError: function (jqXHR, textStatus, errorThrown) { return "Загрузка прервалась"; }, + formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " or more character" + (n == 1 ? "" : "s"); }, + formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1 ? "" : "s"); }, + formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); }, + formatLoadMore: function (pageNumber) { return "Загрузка…"; }, + formatSearching: function () { return "Поиск…"; } + }; + + $.extend($.fn.select2.defaults, $.fn.select2.locales['ru']); $.fn.select2.ajaxDefaults = { transport: $.ajax, diff --git a/~dev_rating/media/js/sign.js b/~dev_rating/media/js/sign.js index 55617a532364622edfe0373705431faf64beadb2..de7e9acb31c6d59e86d13f64db42018dae9d6dd3 100644 --- a/~dev_rating/media/js/sign.js +++ b/~dev_rating/media/js/sign.js @@ -33,7 +33,7 @@ $(function() } else { - $('#remind').val('Что-то пошло РЅРµ так :('); + EventInspector_ShowMsg(data.error, "error"); } }); @@ -113,6 +113,10 @@ $(function() { $('#signin_b').trigger('click'); } + else if($('#email').is(':focus')) + { + $('#email').siblings('input[type=button]').trigger('click'); + } } }); diff --git a/~dev_rating/media/less/teacher/discipline/EditStudents.css b/~dev_rating/media/less/teacher/discipline/EditStudents.css index c62250e302591917c5ee8174b7d5d0da81dc565c..f608412dfb941faf25ff0738166da9486a959377 100644 --- a/~dev_rating/media/less/teacher/discipline/EditStudents.css +++ b/~dev_rating/media/less/teacher/discipline/EditStudents.css @@ -67,7 +67,7 @@ } .StudentsList .GroupContainerAttached .Student { float: right; - width: 880px; + /*width: 880px;*/ margin-top: 10px; padding: 7px 10px; } diff --git a/~dev_rating/media/less/teacher/discipline/EditStudents.less b/~dev_rating/media/less/teacher/discipline/EditStudents.less index 74bbb484a03a930b2efe1e5c8d2c1a871ece1b6b..11272ad57133b008bf9f754af1ad20d251808bf4 100644 --- a/~dev_rating/media/less/teacher/discipline/EditStudents.less +++ b/~dev_rating/media/less/teacher/discipline/EditStudents.less @@ -76,7 +76,7 @@ .StudentsList .GroupContainerAttached .Student { float: right; - width: 880px; + /*width: 880px;*/ margin-top: 10px; padding: 7px 10px; } diff --git a/~dev_rating/modules/account/classes/Kohana/Account.php b/~dev_rating/modules/account/classes/Kohana/Account.php index b5578f0046d4cf2a89fcd6fb62a61542407b5fd5..8adc650fd91ba18751ad7e65c00ccc3b887ba2e4 100644 --- a/~dev_rating/modules/account/classes/Kohana/Account.php +++ b/~dev_rating/modules/account/classes/Kohana/Account.php @@ -50,7 +50,7 @@ class Kohana_Account { /** * Вовзращает экземпляр класса (singleton-паттерн) * - * @return instance + * @return self */ public static function instance() { if(!isset(self::$_instance)) @@ -161,7 +161,9 @@ class Kohana_Account { $UserFullName = $this->_model->createRecoveryToken($email, $requestToken); if (!$UserFullName) - return; // TODO: generate recovery token error + throw HTTP_Exception::factory(403, + 'Пользователь СЃ таким e-mail адресом РЅРµ зарегистрирован РІ системе!'); + $subject = ASSEMBLY_SYSTEM_NAME.": Восстановление пароля"; $twig = Twig::factory('email/recovery'); diff --git a/~dev_rating/modules/account/classes/Kohana/User.php b/~dev_rating/modules/account/classes/Kohana/User.php index d4cfda8fdbf6e4a7abb05a36225ca99710d4b3c6..399673809fc5d269f8ff75ac95a1a447dfc15d33 100644 --- a/~dev_rating/modules/account/classes/Kohana/User.php +++ b/~dev_rating/modules/account/classes/Kohana/User.php @@ -1,7 +1,35 @@ <?php -class Kohana_User implements ArrayAccess { - +/** + * Personal info + * @property $LastName string + * @property $FirstName string + * @property $SecondName string + * @property $FacultyID int + * @property $FacultyName string + * @property $FacultyAbbr string + * + * Account info + * @property $ID int + * @property $Login string + * @property $EMail string + * @property $Type string teacher / student + * @property $Role string description + * @property $RoleMark int + * @property $IsEnabled bool + * @property $Code + * @property $UserAgent + * + * Session + * @property-read $SemesterID int + * @property-read $last_active int + * @property-read $LoggedIn bool + * @property-read $UserHash string + * @property-read $PasswordHash string + * @property-read $start_time int + */ +class Kohana_User implements ArrayAccess +{ protected static $_instance; protected $_session; protected $_config; @@ -10,21 +38,19 @@ class Kohana_User implements ArrayAccess { protected static $_flag; /** - * Вовзращает экземпляр класса (singleton-паттерн) - * - * @return instance - */ + * todo: mark deprecated as singleton is an anti-pattern! + * @return self class instance (singleton-pattern) + */ public static function instance($state = false) { self::$_flag = $state; - if(!isset(self::$_instance)) - { + if (!isset(self::$_instance)) { $config = Kohana::$config->load('account'); self::$_instance = new self($config); } return self::$_instance; } - - + + private function __construct($config = array()) { $this->_config = $config; $this->_session = Session::instance(); @@ -34,20 +60,19 @@ class Kohana_User implements ArrayAccess { $this->_config['hash_method'] = 'sha256'; $isSignedIn = $this->isSignedIn(); $this->_PrepareSemester(); - - if($isSignedIn) { + + if ($isSignedIn) { $id = $this->_session->get('ID'); $this->_userInfo = $this->_getInfoFromDB($id); - + if (self::$_flag != true) { $this->_session->regenerate(); $this->_session->set('start_time', time()); } } - } - - + + protected function _PrepareSemester() { $semesterID = $this->_session->get("SemesterID"); if (!$semesterID) { @@ -55,29 +80,30 @@ class Kohana_User implements ArrayAccess { } $this->SetSemester($semesterID); } - + public function SetSemester($semesterID) { $res = $this->_model->SetSemesterID($semesterID); - if ($res >= 0) + if ($res >= 0) { $this->_session->set("SemesterID", "$semesterID"); + } } - + /** * Регистрирует РЅРѕРІРѕРіРѕ пользователя Рё осуществляет РІС…РѕРґ. - * Проверяет корректность РєРѕРґР° активации Рё существование аккаунтов СЃ такими же авторизационными данными. + * Проверяет корректность РєРѕРґР° активации Рё существование + * аккаунтов СЃ такими же авторизационными данными. * - * @param string $code РљРѕРґ активации - * @param string $email E-Mail адресс - * @param string $login - * @param string $password - * @return array - */ - public function signUp($code, $email, $login, $password) - { + * @param string $code РљРѕРґ активации + * @param string $email E-Mail адресс + * @param string $login + * @param string $password + * @return array Пару РІРёРґР° <tt>(is_ok, err_msg)</tt> + */ + public function signUp($code, $email, $login, $password) { $model = &$this->_model; $account = Account::instance(); - + $isValid = $model->isActivationCodeValid($code); if (!$isValid) { return array(false, 'invalid_code'); @@ -85,25 +111,28 @@ class Kohana_User implements ArrayAccess { $isLogin = $account->isLoginExists($login); $isMail = $account->isMailExists($email); - + if ($isLogin) { return array(false, 'login_exists'); - } else if ($isMail) { - return array(false, 'mail_exists'); + } else { + if ($isMail) { + return array(false, 'mail_exists'); + } } - + $id = $model->activateAccount($login, $password, $email, $code); $this->completeSignIn($id, $this->hash($password)); return array(true, 'ok'); } /** - * Проверяет корректность авторизационных данных Рё возвращает true, если авторизация прошла успешно, Рё false, если данные являются некорректными. + * Проверяет корректность авторизационных данных. * - * @param string $login - * @param string $password - * @return bool - */ + * @param string $login + * @param string $password + * @return bool true, если авторизация прошла успешно, + * Рё false, если данные являются некорректными. + */ public function signIn($login, $password) { $id = (int)$this->_model->checkAuth($login, $password); if ($id === -1) { @@ -112,10 +141,11 @@ class Kohana_User implements ArrayAccess { return $this->completeSignIn($id, $this->hash($password)); } } - + protected function completeSignIn($id, $passhash) { - $userHash = $this->hash($id.Request::$user_agent.Request::$client_ip).$this->_config['hash_key']; - $passwordHash = $this->hash($passhash.$this->_config['hash_key']); + $source = $id . Request::$user_agent . Request::$client_ip; + $userHash = $this->hash($source) . $this->_config['hash_key']; + $passwordHash = $this->hash($passhash . $this->_config['hash_key']); Cookie::set('userhash', $passwordHash); $this->_userInfo = $this->_getInfoFromDB($id); $this->_session->regenerate(); @@ -124,188 +154,185 @@ class Kohana_User implements ArrayAccess { $this->_session->set('UserHash', $this->hash($userHash)); $this->_session->set('PasswordHash', $passwordHash); $this->_session->set('start_time', time()); - return TRUE; - } + return true; + } /** - * Проверяет авторизационный статус пользователя Рё, если пользователь имеет useragent Рё IP, отличные РѕС‚ хранимых РІ сессии, осуществляет выход РёР· текущего сеанса. + * Проверяет авторизационный статус пользователя Рё, если + * пользователь имеет UserAgent Рё IP, отличные РѕС‚ хранимых + * РІ сессии, осуществляет выход РёР· текущего сеанса. * - * @return bool - */ - public function isSignedIn() - { + * @return bool true, если пользователь авторизован + */ + public function isSignedIn() { $session = &$this->_session; - if($session->get('LoggedIn') && !$this->checkHash()) { + if ($session->get('LoggedIn') && !$this->checkHash()) { $this->completeSignOut(); } return $this->_session->get('LoggedIn'); } - - protected function checkHash() - { + + protected function checkHash() { $id = $this->_session->get('ID'); - $userHash = $this->hash($id.Request::$user_agent.Request::$client_ip).$this->_config['hash_key']; + $source = $id . Request::$user_agent . Request::$client_ip; + $userHash = $this->hash($source) . $this->_config['hash_key']; $userCheck = $this->_session->get('UserHash') == $this->hash($userHash); $passCheck = Cookie::get('userhash') == $this->_session->get('PasswordHash'); return $userCheck AND $passCheck; - } - + } + /** * Завершает текущий сеанс пользователя. - * - * @return array - */ - public function signOut() - { - if($this->isSignedIn()) { + * @return bool + */ + public function signOut() { + if ($this->isSignedIn()) { return $this->completeSignOut(); } - return FALSE; + return false; } - - protected function completeSignOut() - { - $this->_session ->set('ID', FALSE) - ->set('LoggedIn', FALSE) - ->set('UserHash', FALSE); + + protected function completeSignOut() { + $this->_session + ->set('ID', false) + ->set('LoggedIn', false) + ->set('UserHash', false); + Cookie::delete('userhash'); unset($this->_userInfo); $this->_session->restart(); - return TRUE; + return true; } /** * Проверяет корректность данного пароля для текущего пользователя. * - * @param string $password Пароль - * @return bool - */ + * @param string $password + * @return bool + */ public function checkPassword($password) { - if(!$this->isSignedIn()) - return FALSE; - $passhash = $this->hash($password); - return $this->hash($passhash.$this->_config['hash_key']) === $this->_session->get('PasswordHash'); + if (!$this->isSignedIn()) + return false; + + $passHash = $this->hash($password); + $computed = $this->hash($passHash . $this->_config['hash_key']); + return $computed === $this->_session->get('PasswordHash'); } - - public function changePassword($old, $new) - { - if(!$this->checkPassword($old)) - return FALSE; + + public function changePassword($old, $new) { + if (!$this->checkPassword($old)) + return false; + $this->_model->changePassword($this->offsetGet('ID'), $new); - $passhash = $this->hash($this->hash($new).$this->_config['hash_key']); - Cookie::set('userhash', $passhash); + $passhash = $this->hash($this->hash($new) . $this->_config['hash_key']); $this->_session->set('PasswordHash', $passhash); - return TRUE; + Cookie::set('userhash', $passhash); + return true; } - - public function changeLogin($login) - { - if(!$this->isSignedIn() || Account::instance()->isLoginExists($login)) - return FALSE; + + public function changeLogin($login) { + if (!$this->isSignedIn() || Account::instance()->isLoginExists($login)) + return false; + $this->_model->changeLogin($this->offsetGet('ID'), $login); - return TRUE; - } - - public function changeMail($email) - { - if(!$this->isSignedIn() || Account::instance()->isMailExists($email)) - return FALSE; - $token = md5(time().$this->offsetGet('EMail').$email); + return true; + } + + public function changeMail($email) { + if (!$this->isSignedIn() || Account::instance()->isMailExists($email)) + return false; + + $token = md5(time() . $this->offsetGet('EMail') . $email); $this->_session->set('NewMail_Token', $token); $this->_session->set('NewMail_Adress', $email); return $token; - } - - public function completeChangeMail($token) - { + } + + public function completeChangeMail($token) { $email = $this->_session->get('NewMail_Adress'); - if($token == $this->_session->get('NewMail_Token') AND !Account::instance()->isMailExists($email)) - { + if ($token == $this->_session->get('NewMail_Token') AND !Account::instance()->isMailExists($email)) { $this->_model->changeMail($this->offsetGet('ID'), $email); return true; - } - else { + } else { return false; - } - } - - public function changeProfile($data) - { - if($this->offsetGet('Type') == 'teacher') - { - $this->_model->ChangeTeacherInfo( - $this->offsetGet('TeacherID'), - $data['lastName'], - $data['firstName'], - $data['secondName'], - $data['jobPositionID'], - $data['departmentID']); } } - - // ---------------------------- [INFO] ------------------------------------- - + + public function changeProfile($data) { + if ($this->offsetGet('Type') == 'teacher') { + $this->_model->ChangeTeacherInfo($this->offsetGet('TeacherID'), $data['lastName'], $data['firstName'], $data['secondName'], $data['jobPositionID'], $data['departmentID']); + } + } + + /* Info */ + /** * Возвращает массив, содержащий пользовательские данные. * * @return array */ - public function getInfoAsArray() - { - if($this->isSignedIn()) + public function toArray() { + if ($this->isSignedIn()) { return $this->_userInfo + $this->_session->as_array(); + // fixme: nobody knows what _session contains! + } else { + return array(); + } } - - protected function _getInfoFromDB($id) - { - $info = $this->_model->getPersonalInfo($id)->offsetGet(0); - $info += $this->_model->getAccountInfo($id)->offsetGet(0); + + protected function _getInfoFromDB($id) { + $info = $this->_model->getPersonalInfo($id); + $info += $this->_model->getAccountInfo($id); return $info; } - // ---------------------------- [ARRAY] ------------------------------------ - + /* Fields access */ + + function __set($name, $value) { + $this->offsetSet($name, $value); + } + + function __get($name) { + return $this->offsetGet($name); + } + public function offsetSet($offset, $value) { - if(isset($this->_userInfo[$offset])) { + if (isset($this->_userInfo[$offset])) { return $this->_userInfo[$offset]; } else { - throw new Kohana_Exception('Invalid key: '.$offset); + throw new Kohana_Exception('Invalid key: ' . $offset); } } public function offsetGet($offset) { - if(isset($this->_userInfo[$offset])) - { + if (isset($this->_userInfo[$offset])) { return $this->_userInfo[$offset]; + } else { + return $this->_session->get($offset); } - else - return FALSE; } - + public function offsetUnset($offset) { - if(isset($this->_userInfo[$offset])) - { + if (isset($this->_userInfo[$offset])) { unset($this->_userInfo[$offset]); } } - + public function offsetExists($offset) { return isset($this->_userInfo[$offset]); } - + /** * Perform a hmac hash, using the configured method. * - * @param string $str string to hash + * @param string $str string to hash * @return string */ - protected function hash($str) - { - if ( ! $this->_config['hash_key']) - { - $this->_config['hash_key'] = $key = md5(time().Request::$client_ip); + protected function hash($str) { + if (!$this->_config['hash_key']) { + $this->_config['hash_key'] = $key = md5(time() . Request::$client_ip); $this->_model->setHashKey($key); } return hash_hmac($this->_config['hash_method'], $str, $this->_config['hash_key']); - } + } } \ No newline at end of file diff --git a/~dev_rating/modules/account/classes/Model/Kohana/Account.php b/~dev_rating/modules/account/classes/Model/Kohana/Account.php index 1405085f09cab3a1b666d7652087e203715c0175..a7c768677ce2ab25b7bd4f8844acb1ddb7351e0f 100644 --- a/~dev_rating/modules/account/classes/Model/Kohana/Account.php +++ b/~dev_rating/modules/account/classes/Model/Kohana/Account.php @@ -5,16 +5,16 @@ class Model_Kohana_Account extends Model public function setHashKey($key) { $key = Database::instance()->escape($key); - $sql = "SELECT `SetHashKey`($key) AS `Key`;"; + $sql = "SELECT `SetSettings`('HashKey', '', $key) AS `Key`;"; $res = DB::query(Database::SELECT, $sql)->execute(); return $res->get('Key'); } public function getHashKey() { - $sql = "SELECT `GetHashKey`() AS `Key`;"; + $sql = "CALL `GetSettings`('HashKey');"; $key = DB::query(Database::SELECT, $sql)->execute(); - return $key->get('Key'); + return $key->get('ValS'); } public function checkAuth($login, $password) { @@ -26,7 +26,9 @@ class Model_Kohana_Account extends Model return $res->get('ID'); } - public function ChangeTeacherInfo($id, $lastName, $firstName, $secondName, $degreeID, $departamentID) + + public function ChangeTeacherInfo($id, $lastName, $firstName, $secondName, $degreeID, $departmentID) + { $db = Database::instance(); $lastName = $db->escape($lastName); @@ -37,7 +39,8 @@ class Model_Kohana_Account extends Model return $key->get('UserID'); } - public function createTeacher($lastName, $firstName, $secondName, $degreeID, $departamentID, $activationCode) + + public function createTeacher($lastName, $firstName, $secondName, $degreeID, $departmentID, $activationCode) { $db = Database::instance(); $lastName = $db->escape($lastName); @@ -49,6 +52,7 @@ class Model_Kohana_Account extends Model return $key->get('UserID'); } + public function createTeacherByDepName($lastName, $firstName, $secondName, $departamentName, $facultyID, $activationCode) { $db = Database::instance(); @@ -102,14 +106,14 @@ class Model_Kohana_Account extends Model { $sql = "CALL `GetPersonalInfo`('$id');"; $query = DB::query(Database::SELECT, $sql)->execute(); - return $query; + return $query[0]; } public function GetAccountInfo($id) { $sql = "CALL GetAccountInfo('$id');"; $query = DB::query(Database::SELECT, $sql)->execute(); - return $query; + return $query[0]; } public function changeMail($id, $mail) @@ -157,6 +161,7 @@ class Model_Kohana_Account extends Model $code = Database::instance()->escape($code); $sql = "SELECT `GetAccCountByCode`($code) AS Num;"; $res = DB::query(Database::SELECT, $sql)->execute(); + $count = $res[0]['Num']; return $count == 1; } @@ -212,10 +217,11 @@ class Model_Kohana_Account extends Model public function GetCurSemesterID() { - $sql = "SELECT `GetCurSemesterID`() AS `Num`; "; + $sql = "CALL `GetSettings`('SemesterID');"; $res = DB::query(Database::SELECT, $sql)->execute(); + $id = NULL; foreach ($res as $value) { - $id = $value['Num']; + $id = $value['Val']; } return $id; } @@ -224,6 +230,7 @@ class Model_Kohana_Account extends Model { $sql = "SELECT `SetSemesterID`('$semesterID') AS `Num`; "; $res = DB::query(Database::SELECT, $sql)->execute(); + $id = 0; foreach ($res as $value) { $id = $value['Num']; diff --git a/~dev_rating/modules/database/classes/Kohana/Database/Query.php b/~dev_rating/modules/database/classes/Kohana/Database/Query.php index 480e41b834bf3ef191a57837867f95030159f354..cd8f39b0f860df40cdcea3521ff1bb59e38432ea 100644 --- a/~dev_rating/modules/database/classes/Kohana/Database/Query.php +++ b/~dev_rating/modules/database/classes/Kohana/Database/Query.php @@ -208,7 +208,7 @@ class Kohana_Database_Query { * @param mixed $db Database instance or name of instance * @param string result object classname, TRUE for stdClass or FALSE for array * @param array result object constructor arguments - * @return object Database_Result for SELECT queries + * @return Database_RESULT Database_Result for SELECT queries * @return mixed the insert id for INSERT queries * @return integer number of affected rows for all other queries */ diff --git a/~dev_rating/modules/mail/config/mail.php b/~dev_rating/modules/mail/config/mail.php index db5b4d2857f6d998b289c298e02c866150c82ba8..b1931dec2b95837e98c3267dce6417dae71e9014 100644 --- a/~dev_rating/modules/mail/config/mail.php +++ b/~dev_rating/modules/mail/config/mail.php @@ -68,13 +68,13 @@ return array( * PHPMailer_SMTP * * @link https://github.com/PHPMailer/PHPMailer - * - * 'SMTPAuth' => TRUE - * 'Host' => 'localhost', - * 'Port' => 26, - * 'Username' => NULL, - * 'Password' => NULL - */ + */ + 'SMTPAuth' => FALSE, + 'Host' => 'class.mmcs.sfedu.ru', + 'Port' => 25, + 'Username' => NULL, + 'Password' => NULL + ) ) ); diff --git a/~dev_rating/modules/phpexcel/vendor/PHPExcel/Classes/PHPExcel/Worksheet.php b/~dev_rating/modules/phpexcel/vendor/PHPExcel/Classes/PHPExcel/Worksheet.php index 6215be8b1ce569f72db3af89611210cf32f97a05..46d5c2d5645d6239c46bb8fc211247dedfe208ae 100644 --- a/~dev_rating/modules/phpexcel/vendor/PHPExcel/Classes/PHPExcel/Worksheet.php +++ b/~dev_rating/modules/phpexcel/vendor/PHPExcel/Classes/PHPExcel/Worksheet.php @@ -1099,8 +1099,8 @@ class PHPExcel_Worksheet implements PHPExcel_IComparable /** * Set a cell value by using numeric cell coordinates * - * @param string $pColumn Numeric column coordinate of the cell (A = 0) - * @param string $pRow Numeric row coordinate of the cell + * @param string $pColumn Numeric column coordinate of the cell (>= 0) + * @param string $pRow Numeric row coordinate of the cell (>= 1) * @param mixed $pValue Value of the cell * @param bool $returnCell Return the worksheet (false, default) or the cell (true) * @return PHPExcel_Worksheet|PHPExcel_Cell Depending on the last parameter being specified diff --git a/~dev_rating/modules/unittest/composer.json b/~dev_rating/modules/unittest/composer.json index 829fefdb2f3e764667b9e6bb1d3349ab6321fd83..d239563054ae7a74e605637c6cac440ae705ec35 100644 --- a/~dev_rating/modules/unittest/composer.json +++ b/~dev_rating/modules/unittest/composer.json @@ -23,7 +23,7 @@ "composer/installers": "~1.0", "kohana/core": ">=3.3", "php": ">=5.3.3", - "phpunit/phpunit": "3.7.*" + "phpunit/phpunit": "4.5.0" }, "extra": { "branch-alias": { diff --git a/~dev_rating/modules/unittest/composer.lock b/~dev_rating/modules/unittest/composer.lock new file mode 100644 index 0000000000000000000000000000000000000000..dfc17aeae8a84f5ae5bf3f18fa28d2a3ed225e65 --- /dev/null +++ b/~dev_rating/modules/unittest/composer.lock @@ -0,0 +1,1127 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "217825c78f7a54f20307c10f45b71bb2", + "packages": [ + { + "name": "composer/installers", + "version": "v1.0.21", + "source": { + "type": "git", + "url": "https://github.com/composer/installers.git", + "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/installers/zipball/d64e23fce42a4063d63262b19b8e7c0f3b5e4c45", + "reference": "d64e23fce42a4063d63262b19b8e7c0f3b5e4c45", + "shasum": "" + }, + "replace": { + "roundcube/plugin-installer": "*", + "shama/baton": "*" + }, + "require-dev": { + "composer/composer": "1.0.*@dev", + "phpunit/phpunit": "4.1.*" + }, + "type": "composer-installer", + "extra": { + "class": "Composer\\Installers\\Installer", + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Composer\\Installers\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kyle Robinson Young", + "email": "kyle@dontkry.com", + "homepage": "https://github.com/shama" + } + ], + "description": "A multi-framework Composer library installer", + "homepage": "http://composer.github.com/installers/", + "keywords": [ + "Craft", + "Dolibarr", + "Hurad", + "MODX Evo", + "OXID", + "SMF", + "Thelia", + "WolfCMS", + "agl", + "aimeos", + "annotatecms", + "bitrix", + "cakephp", + "chef", + "codeigniter", + "concrete5", + "croogo", + "dokuwiki", + "drupal", + "elgg", + "fuelphp", + "grav", + "installer", + "joomla", + "kohana", + "laravel", + "lithium", + "magento", + "mako", + "mediawiki", + "modulework", + "moodle", + "phpbb", + "piwik", + "ppi", + "puppet", + "roundcube", + "shopware", + "silverstripe", + "symfony", + "typo3", + "wordpress", + "zend", + "zikula" + ], + "time": "2015-02-18 17:17:01" + }, + { + "name": "doctrine/instantiator", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", + "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "2.0.*@ALPHA" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Instantiator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2014-10-13 12:58:55" + }, + { + "name": "kohana/core", + "version": "v3.3.3.1", + "source": { + "type": "git", + "url": "https://github.com/kohana/core.git", + "reference": "fa66e193b56cbf4bc36aa16caec31feccf31e92a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kohana/core/zipball/fa66e193b56cbf4bc36aa16caec31feccf31e92a", + "reference": "fa66e193b56cbf4bc36aa16caec31feccf31e92a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "kohana/koharness": "*@dev", + "kohana/unittest": "3.3.*@dev" + }, + "suggest": { + "ext-curl": "*", + "ext-http": "*", + "ext-mcrypt": "*" + }, + "type": "library", + "extra": { + "installer-paths": { + "vendor/{$vendor}/{$name}": [ + "type:kohana-module" + ] + }, + "branch-alias": { + "dev-3.3/develop": "3.3.x-dev", + "dev-3.4/develop": "3.4.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kohana Team", + "email": "team@kohanaframework.org", + "homepage": "http://kohanaframework.org/team", + "role": "developer" + } + ], + "description": "Core system classes for the Kohana application framework", + "homepage": "http://kohanaframework.org", + "keywords": [ + "framework", + "kohana" + ], + "time": "2014-12-11 02:17:12" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", + "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "dflydev/markdown": "~1.0", + "erusev/parsedown": "~1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "phpDocumentor": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "mike.vanriel@naenius.com" + } + ], + "time": "2015-02-03 12:10:50" + }, + { + "name": "phpspec/prophecy", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.2", + "phpdocumentor/reflection-docblock": "~2.0" + }, + "require-dev": { + "phpspec/phpspec": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "http://phpspec.org", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2014-11-17 16:23:49" + }, + { + "name": "phpunit/php-code-coverage", + "version": "2.0.15", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "34cc484af1ca149188d0d9e91412191e398e0b67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67", + "reference": "34cc484af1ca149188d0d9e91412191e398e0b67", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "phpunit/php-file-iterator": "~1.3", + "phpunit/php-text-template": "~1.2", + "phpunit/php-token-stream": "~1.3", + "sebastian/environment": "~1.0", + "sebastian/version": "~1.0" + }, + "require-dev": { + "ext-xdebug": ">=2.1.4", + "phpunit/phpunit": "~4" + }, + "suggest": { + "ext-dom": "*", + "ext-xdebug": ">=2.2.1", + "ext-xmlwriter": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2015-01-24 10:06:35" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", + "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "File/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2013-10-10 15:34:57" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "Text/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2014-01-30 17:20:04" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "PHP/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "include-path": [ + "" + ], + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2013-08-02 07:42:54" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74", + "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2015-01-17 09:51:32" + }, + { + "name": "phpunit/phpunit", + "version": "4.5.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/5b578d3865a9128b9c209b011fda6539ec06e7a5", + "reference": "5b578d3865a9128b9c209b011fda6539ec06e7a5", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=5.3.3", + "phpspec/prophecy": "~1.3.1", + "phpunit/php-code-coverage": "~2.0", + "phpunit/php-file-iterator": "~1.3.2", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "~1.0.2", + "phpunit/phpunit-mock-objects": "~2.3", + "sebastian/comparator": "~1.1", + "sebastian/diff": "~1.1", + "sebastian/environment": "~1.2", + "sebastian/exporter": "~1.2", + "sebastian/global-state": "~1.0", + "sebastian/version": "~1.0", + "symfony/yaml": "~2.0" + }, + "suggest": { + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.5.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2015-02-05 15:51:19" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "c63d2367247365f688544f0d500af90a11a44c65" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/c63d2367247365f688544f0d500af90a11a44c65", + "reference": "c63d2367247365f688544f0d500af90a11a44c65", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "~1.0,>=1.0.1", + "php": ">=5.3.3", + "phpunit/php-text-template": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.3" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2014-10-03 05:12:11" + }, + { + "name": "sebastian/comparator", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", + "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2015-01-29 16:28:08" + }, + { + "name": "sebastian/diff", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/5843509fed39dee4b356a306401e9dd1a931fec7", + "reference": "5843509fed39dee4b356a306401e9dd1a931fec7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "http://www.github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2014-08-15 10:29:00" + }, + { + "name": "sebastian/environment", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/6e6c71d918088c251b181ba8b3088af4ac336dd7", + "reference": "6e6c71d918088c251b181ba8b3088af4ac336dd7", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2014-10-25 08:00:45" + }, + { + "name": "sebastian/exporter", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "84839970d05254c73cde183a721c7af13aede943" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", + "reference": "84839970d05254c73cde183a721c7af13aede943", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2015-01-27 07:23:06" + }, + { + "name": "sebastian/global-state", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2014-10-06 09:23:50" + }, + { + "name": "sebastian/recursion-context", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", + "reference": "3989662bbb30a29d20d9faa04a846af79b276252", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2015-01-24 09:48:32" + }, + { + "name": "sebastian/version", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/a77d9123f8e809db3fbdea15038c27a95da4058b", + "reference": "a77d9123f8e809db3fbdea15038c27a95da4058b", + "shasum": "" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2014-12-15 14:25:24" + }, + { + "name": "symfony/yaml", + "version": "v2.6.5", + "target-dir": "Symfony/Component/Yaml", + "source": { + "type": "git", + "url": "https://github.com/symfony/Yaml.git", + "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/0cd8e72071e46e15fc072270ae39ea1b66b10a9d", + "reference": "0cd8e72071e46e15fc072270ae39ea1b66b10a9d", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/phpunit-bridge": "~2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Component\\Yaml\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Symfony Yaml Component", + "homepage": "http://symfony.com", + "time": "2015-03-12 10:28:44" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.3.3" + }, + "platform-dev": [] +} diff --git a/~dev_rating/modules/unittest/guide/unittest/index.md b/~dev_rating/modules/unittest/guide/unittest/index.md deleted file mode 100644 index 9f7e314cf57a679410cce30c0b6be3e4f91278ce..0000000000000000000000000000000000000000 --- a/~dev_rating/modules/unittest/guide/unittest/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# UnitTest - -Unit tests for Kohana \ No newline at end of file diff --git a/~dev_rating/modules/unittest/guide/unittest/menu.md b/~dev_rating/modules/unittest/guide/unittest/menu.md deleted file mode 100644 index 1a707cc73af20e6f51bbfbe4819a6c9386512cd5..0000000000000000000000000000000000000000 --- a/~dev_rating/modules/unittest/guide/unittest/menu.md +++ /dev/null @@ -1,5 +0,0 @@ -## [UnitTest]() - - [Mock Objects](mockobjects) - - [Testing](testing) - - [Testing workflows](testing_workflows) - - [Troubleshooting](troubleshooting) diff --git a/~dev_rating/system/classes/Kohana/Model.php b/~dev_rating/system/classes/Kohana/Model.php index 995dde21fdf724bbe621288b03caaf4a20ea0898..34d3a802b23ead1a553b1d384f37954604cc7eb0 100644 --- a/~dev_rating/system/classes/Kohana/Model.php +++ b/~dev_rating/system/classes/Kohana/Model.php @@ -17,6 +17,7 @@ abstract class Kohana_Model { * * @param string $name model name * @return Model + * @deprecated don't use it in the project! */ public static function factory($name) { diff --git a/~dev_rating/system/classes/Kohana/Route.php b/~dev_rating/system/classes/Kohana/Route.php index 718bf179685b04e1752df27aa661b0de410e95c2..2a9e9151784eec3bdf65e42a4048df8a647169d7 100644 --- a/~dev_rating/system/classes/Kohana/Route.php +++ b/~dev_rating/system/classes/Kohana/Route.php @@ -381,7 +381,7 @@ class Kohana_Route { * [!!] Default parameters are added before filters are called! * * @throws Kohana_Exception - * @param array $callback callback string, array, or closure + * @param array|callback $callback callback string, array, or closure * @return $this */ public function filter($callback)