├── tmp └── .placeholder ├── lib ├── .htaccess ├── fpdf │ ├── .htaccess │ ├── license.txt │ ├── font │ │ ├── courier.php │ │ ├── courierb.php │ │ ├── courieri.php │ │ └── courierbi.php │ └── install.txt ├── phplot │ ├── .htaccess │ ├── fonts │ │ ├── Khula-Bold.ttf │ │ ├── Khula-Light.ttf │ │ ├── Khula-Regular.ttf │ │ ├── Khula-SemiBold.ttf │ │ └── Khula-ExtraBold.ttf │ └── contrib │ │ ├── data_table.example2.php │ │ ├── prune_labels.example.php │ │ ├── data_table.example3.php │ │ ├── color_range.example.php │ │ ├── prune_labels.test.php │ │ ├── prune_labels.php │ │ ├── color_range.test1.php │ │ ├── README.txt │ │ ├── data_table.example1.php │ │ └── color_range.test2.php ├── htmlinput.php ├── const.php ├── texttemplate.php ├── tools.php ├── lang.php ├── api.php ├── permissions.php ├── md5sums.txt ├── roles.php ├── loader.php ├── color.php ├── mailer.php ├── browser.php ├── plan.php └── boxes.php ├── index.php ├── .gitignore ├── frontend ├── img │ ├── bg.png │ ├── logo.png │ ├── vendor.png │ ├── favicon.png │ ├── vendor-logo.png │ ├── resource_types │ │ ├── Room.svg │ │ ├── Phone.svg │ │ ├── General.svg │ │ ├── Car.svg │ │ └── Computer.svg │ ├── add.svg │ ├── ok.svg │ ├── warning.svg │ ├── home.svg │ ├── swap.svg │ ├── delete.svg │ ├── code.svg │ ├── file.svg │ ├── flash-auto.svg │ ├── info-gray.svg │ ├── user.svg │ ├── clean.svg │ ├── check.svg │ ├── book.svg │ ├── email.svg │ ├── free.svg │ ├── month.svg │ ├── calendar.svg │ ├── export.svg │ ├── edit.svg │ ├── roster.svg │ ├── uncheck.svg │ ├── copy.svg │ ├── info-white.svg │ ├── chart.svg │ ├── info.svg │ ├── key.svg │ ├── anniversary.svg │ ├── note.svg │ ├── cancel.svg │ ├── ldap-directory.svg │ ├── refresh.svg │ ├── resources.svg │ ├── image.svg │ ├── lock.svg │ ├── sync.svg │ ├── grid.svg │ ├── template.svg │ ├── attach-file.svg │ ├── users.svg │ ├── checklist.svg │ ├── loader.svg │ ├── birthday.svg │ ├── roles.svg │ ├── absent.svg │ ├── ok1.svg │ ├── ok2.svg │ ├── absent-last-minute.svg │ ├── absent-approve.svg │ └── holiday.svg ├── manual │ └── de.pdf ├── css │ ├── mobile.css │ └── tux.css ├── board.inc.php ├── session.php ├── head.inc.php ├── fileprovider.php ├── views │ ├── start.php │ ├── about.php │ ├── changePassword.php │ ├── viewIcsUrl.php │ ├── holidays.php │ ├── userBirthdays.php │ ├── deployFile.php │ ├── deployNote.php │ ├── userAnniversaries.php │ ├── resources.php │ ├── editTextTemplates.php │ ├── dbMaintenance.php │ ├── roles.php │ ├── assignUsersToRoster.php │ └── copyServices.php ├── js │ └── main.js ├── ajaxHandler.php ├── export.php └── setup.php ├── template ├── icsmail_text.txt ├── mail_absence_approved1.txt ├── mail_absence_approved2.txt ├── mail_absence_declined.txt ├── icsmail_text_cancel.txt ├── mail_new_absence.txt └── mail_new_swap_service.txt ├── .github ├── screenshots │ ├── 0start.png │ ├── 1users.png │ ├── 2plan.png │ ├── 3swap.png │ ├── 1services.png │ ├── 3absence.png │ ├── 1birthdays.png │ ├── 2planfilled.png │ ├── 3myservices.png │ ├── 1usersettings.png │ ├── 2useroverview.png │ └── 1userconstraints.png └── FUNDING.yml ├── UPGRADE.md ├── api ├── html.php ├── pdf.php └── ics.php └── conf.php.example /tmp/.placeholder: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/.htaccess: -------------------------------------------------------------------------------- 1 | Deny from all 2 | -------------------------------------------------------------------------------- /lib/fpdf/.htaccess: -------------------------------------------------------------------------------- 1 | Allow from all 2 | -------------------------------------------------------------------------------- /lib/phplot/.htaccess: -------------------------------------------------------------------------------- 1 | Allow from all 2 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 'example.org'. 5 | -------------------------------------------------------------------------------- /frontend/board.inc.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | -------------------------------------------------------------------------------- /lib/fpdf/license.txt: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any person obtaining a copy 2 | of this software to use, copy, modify, distribute, sublicense, and/or sell 3 | copies of the software, and to permit persons to whom the software is furnished 4 | to do so. 5 | 6 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED. -------------------------------------------------------------------------------- /frontend/css/tux.css: -------------------------------------------------------------------------------- 1 | img#tux { 2 | position: fixed; 3 | height: 120px; 4 | top: 80px; 5 | left: -100px; 6 | animation: peek 5s ease 15s 1 forwards; 7 | } 8 | 9 | @keyframes peek { 10 | 0% { transform: translateX(0px) rotateZ(0deg); } 11 | 30% { transform: translateX(58px) rotateZ(25deg); } 12 | 70% { transform: translateX(58px) rotateZ(25deg); } 13 | 100% { transform: translateX(0px) rotateZ(0deg); } 14 | } 15 | -------------------------------------------------------------------------------- /lib/htmlinput.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/fpdf/font/courier.php: -------------------------------------------------------------------------------- 1 | array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96)); 10 | ?> 11 | -------------------------------------------------------------------------------- /lib/fpdf/font/courierb.php: -------------------------------------------------------------------------------- 1 | array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96)); 10 | ?> 11 | -------------------------------------------------------------------------------- /lib/fpdf/font/courieri.php: -------------------------------------------------------------------------------- 1 | array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96)); 10 | ?> 11 | -------------------------------------------------------------------------------- /lib/fpdf/font/courierbi.php: -------------------------------------------------------------------------------- 1 | array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96)); 10 | ?> 11 | -------------------------------------------------------------------------------- /lib/const.php: -------------------------------------------------------------------------------- 1 | $value) { 17 | $templateContent = str_replace($key, $value, $templateContent); 18 | } 19 | } 20 | 21 | return $templateContent; 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /lib/tools.php: -------------------------------------------------------------------------------- 1 | $chars ? substr($str,0,$chars)."..." : $str; 11 | } 12 | 13 | public function startsWith($haystack, $needle) { 14 | $length = strlen($needle); 15 | return (substr($haystack, 0, $length) === $needle); 16 | } 17 | 18 | public function endsWith($haystack, $needle) { 19 | $length = strlen($needle); 20 | if($length == 0) { 21 | return true; 22 | } 23 | return (substr($haystack, -$length) === $needle); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /frontend/fileprovider.php: -------------------------------------------------------------------------------- 1 | getUser($_SESSION['mp_userid']); 5 | 6 | if($_GET['type'] == 'servicefile') { 7 | $plannedServiceFile = $db->getPlannedServiceFile($_GET['id']); 8 | if($plannedServiceFile != null) { 9 | $service = $db->getService($plannedServiceFile->service_id); 10 | if($perm->isUserAssignedToRoster($currentUser, $service->roster_id) 11 | || $perm->isUserAdminForRoster($currentUser, $service->roster_id)) { 12 | header('Content-Type: application/octet-stream'); 13 | header("Content-Transfer-Encoding: Binary"); 14 | header("Content-disposition: attachment; filename=\"" . basename($plannedServiceFile->title) . "\""); 15 | echo $plannedServiceFile->file; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/lang.php: -------------------------------------------------------------------------------- 1 | dbhandle = $dbhandle; 9 | } 10 | 11 | public function checkActive() { 12 | if(boolval($this->dbhandle->getSetting('api_active'))) 13 | return true; 14 | else 15 | die('API disabled'); 16 | } 17 | 18 | public function checkAuth() { 19 | if(PHP_SAPI === 'cli') 20 | return true; 21 | 22 | $apiKey = $this->dbhandle->getSetting('api_key'); 23 | if(isset($_GET['apikey']) && $_GET['apikey'] == $apiKey) 24 | return true; 25 | if(isset($_POST['apikey']) && $_POST['apikey'] == $apiKey) 26 | return true; 27 | 28 | foreach(explode(',', $this->dbhandle->getSetting('api_allowed_ips')) as $ip) { 29 | if(trim($ip) == $_SERVER['REMOTE_ADDR']) return true; 30 | } 31 | 32 | die('API authentication failed'); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /lib/permissions.php: -------------------------------------------------------------------------------- 1 | db = $dbhandle; 9 | } 10 | 11 | public function isUserSuperadmin($user) { 12 | if($user->superadmin > 0) { 13 | return true; 14 | } else { 15 | return false; 16 | } 17 | } 18 | 19 | public function isUserAdminForRoster($user, $roster_id) { 20 | if($user->superadmin > 0) { 21 | return true; 22 | } else { 23 | foreach($this->db->getUserRostersAdmin($user->id) as $checkRoster) { 24 | if($checkRoster->roster_id == $roster_id) { 25 | return true; 26 | } 27 | } 28 | } 29 | } 30 | 31 | public function isUserAssignedToRoster($user, $roster_id) { 32 | if($user->superadmin > 0) { 33 | return true; 34 | } else { 35 | foreach($this->db->getUserRosters($user->id) as $checkRoster) { 36 | if($checkRoster->roster_id == $roster_id) { 37 | return true; 38 | } 39 | } 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /lib/phplot/contrib/data_table.example2.php: -------------------------------------------------------------------------------- 1 | array(NULL, 'X', '2Y', 'Y^2'), 14 | 'position' => array(640, 20), 15 | 'width' => 150, 16 | 'data' => $data, 17 | 'font' => 3, 18 | ); 19 | 20 | $plot = new PHPlot(800, 600); 21 | $plot->SetTitle('Line Plot with Data Table on Right Side'); 22 | $plot->SetDataValues($data); 23 | $plot->SetDataType('data-data'); 24 | $plot->SetPlotType('linepoints'); 25 | $plot->SetPlotAreaPixels(NULL, NULL, 630, NULL); 26 | $plot->SetCallback('draw_graph', 'draw_data_table', $settings); 27 | $plot->SetLegend(array('2Y', 'Y^2')); 28 | $plot->DrawGraph(); 29 | -------------------------------------------------------------------------------- /lib/phplot/contrib/prune_labels.example.php: -------------------------------------------------------------------------------- 1 | SetTitle('Example - pruned data labels'); 21 | $p->SetDataType('data-data'); 22 | $p->SetDataValues($data); 23 | $p->SetXLabelType('time', '%Y-%m-%d'); 24 | $p->SetXLabelAngle(90); 25 | $p->SetXDataLabelPos('plotdown'); 26 | $p->SetXTickLabelPos('none'); 27 | $p->SetXTickPos('none'); 28 | $p->SetDrawXGrid(False); 29 | $p->SetDrawYGrid(False); 30 | $p->SetPlotType('lines'); 31 | $p->DrawGraph(); 32 | -------------------------------------------------------------------------------- /lib/md5sums.txt: -------------------------------------------------------------------------------- 1 | 44656ed0e14293d377c87d87d0991f55 api.php 2 | b24f1273bdec1c689792d648bd26a3b4 autoplan.php 3 | 562c4622f7996e29b2744fcde9be153c boxes.php 4 | c1aae2caf63a92a44e5d64b973237278 browser.php 5 | bc4e02f745e511b24365bdb19d248d58 color.php 6 | baa481c01d9d3bf07c2e8bb3f23c11d6 const.php 7 | 57e7dfd5a0d4c34c09188d3afb1a5de7 db.php 8 | d550f33db4ca6d94663f95581b3c82c1 genhtml.php 9 | 6a8bdcfc63d88a7824a15d96b8a0bfd3 genics.php 10 | bf8db1b223db866e960eb3569d928cd7 genpdf.php 11 | 164c44d88be637c6ad81264f5e7630fe htmlinput.php 12 | 7890a4cc38540601ea01b2ab9929c3a1 lang.php 13 | 64b474bd4f7f559a68f76faa87443c01 ldapsync.php 14 | ae2316db815f9b369dd1679441d2a8e6 license.php 15 | 5363110b97e8aa027a6898439278f4ee loader.php 16 | 40f148a6c62ebf9aae18babf86c77460 mailer.php 17 | e012691bfad7cdd3e6d1968e533f24a1 permissions.php 18 | b6b6d39780d4fdc28d2138bd1312ed69 plan.php 19 | 5c8410e4773e7b9f2ce4b6d578cf4aba roles.php 20 | f3e259e50b33b1fe0e25f01f778266e7 texttemplate.php 21 | 31d3547570e03dc15aaa0756b081b334 tools.php 22 | -------------------------------------------------------------------------------- /lib/phplot/contrib/data_table.example3.php: -------------------------------------------------------------------------------- 1 | array('Metal', 'Amount'), 20 | 'data' => $data, 21 | ); 22 | 23 | $plot = new PHPlot(600, 400); 24 | $plot->SetTitle('Pie Chart with Legend and Data Table'); 25 | $plot->SetDataValues($data); 26 | $plot->SetDataType('text-data-single'); 27 | $plot->SetPlotType('pie'); 28 | foreach ($data as $row) $plot->SetLegend($row[0]); 29 | $plot->SetCallback('draw_graph', 'draw_data_table', $settings); 30 | $plot->DrawGraph(); 31 | -------------------------------------------------------------------------------- /lib/phplot/contrib/color_range.example.php: -------------------------------------------------------------------------------- 1 | SetTitle('Example - Bar Chart with gradient colors'); 22 | $p->SetDataType('text-data'); 23 | $p->SetDataValues($data); 24 | $p->SetPlotAreaWorld(0, 0, $x_values, 100); 25 | 26 | # This isn't necessary, as we do know how many data sets (bars_per_group): 27 | $n_data = count_data_sets($data, 'text-data'); 28 | # Make a gradient color map: 29 | $colors = color_range($p->SetRGBColor('SkyBlue'), 30 | $p->SetRGBColor('DarkGreen'), $n_data); 31 | $p->SetDataColors($colors); 32 | $p->SetXTickLabelPos('none'); 33 | $p->SetXTickPos('none'); 34 | $p->SetPlotType('bars'); 35 | $p->DrawGraph(); 36 | -------------------------------------------------------------------------------- /lib/roles.php: -------------------------------------------------------------------------------- 1 | dbhandle = $dbhandle; 8 | } 9 | 10 | function getUserRole($id) { 11 | $user = $this->dbhandle->getUser($id); 12 | if($user == null) return null; 13 | foreach($this->dbhandle->getUserRoles($user->id) as $ur) { 14 | $role = $this->dbhandle->getRole($ur->role_id); 15 | return $role; 16 | } 17 | return null; 18 | } 19 | 20 | function updateRoleAffiliation() { 21 | foreach($this->dbhandle->getUsers() as $u) { 22 | foreach($this->dbhandle->getUserRoles($u->id) as $ur) { 23 | $role = $this->dbhandle->getRole($ur->role_id); 24 | $this->dbhandle->updateUser( 25 | $u->id, 26 | $u->superadmin, 27 | $u->login, 28 | $u->firstname, 29 | $u->lastname, 30 | $u->fullname, 31 | $u->email, 32 | $u->phone, 33 | $u->mobile, 34 | $u->birthday, 35 | $u->start_date, 36 | $u->id_no, 37 | $u->description, 38 | $u->ldap, 39 | $u->locked, 40 | $role->max_hours_per_day, 41 | $role->max_services_per_week, 42 | $role->max_hours_per_week, 43 | $role->max_hours_per_month, 44 | $u->color 45 | ); 46 | break; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /lib/phplot/contrib/prune_labels.test.php: -------------------------------------------------------------------------------- 1 | $non_blank labels\n"; 32 | echo substr($line, 0, 80) . "\n"; # Only show first 80 chars. 33 | } 34 | 35 | /* Test cases for prune_labels */ 36 | for ($n = 7; $n <= 1000; $n *= 2) test($n, 10); 37 | for ($g = 5; $g <= 40; $g++) test(72, $g); 38 | # Edge cases 39 | test(80, 41); 40 | test(80, 40); 41 | test(80, 39); 42 | -------------------------------------------------------------------------------- /lib/phplot/contrib/prune_labels.php: -------------------------------------------------------------------------------- 1 | 0) $data[$i][0] = ''; 34 | if (++$k >= $m) $k = 0; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /api/html.php: -------------------------------------------------------------------------------- 1 | checkActive(); 6 | $api->checkAuth(); 7 | 8 | // parse parameter 9 | if(isset($_GET['view']) && isset($_GET['roster']) && isset($_GET['week'])) { 10 | $VIEW = $_GET['view']; 11 | $ROSTER = $_GET['roster']; 12 | $WEEK = $_GET['week']; 13 | } 14 | if(isset($_POST['view']) && isset($_POST['roster']) && isset($_POST['week'])) { 15 | $VIEW = $_POST['view']; 16 | $ROSTER = $_POST['roster']; 17 | $WEEK = $_POST['week']; 18 | } 19 | if(PHP_SAPI === 'cli') { 20 | foreach($argv as $arg) { 21 | if(tools::startsWith($arg, 'view=')) 22 | $VIEW = explode('=', $arg)[1]; 23 | if(tools::startsWith($arg, 'roster=')) 24 | $ROSTER = explode('=', $arg)[1]; 25 | if(tools::startsWith($arg, 'week=')) 26 | $WEEK = explode('=', $arg)[1]; 27 | } 28 | } 29 | 30 | // output 31 | if($VIEW && $ROSTER && $WEEK) { 32 | 33 | if($VIEW == 'plan') { 34 | 35 | $html = new genhtml($db); 36 | $html->createPlanHtml($ROSTER, $WEEK); 37 | echo $html->getHtmlText(); 38 | 39 | } 40 | elseif($VIEW == 'userServices') { 41 | 42 | $html = new genhtml($db); 43 | $html->createUserServicesHtml($ROSTER, $WEEK); 44 | echo $html->getHtmlText(); 45 | 46 | } 47 | elseif($VIEW == 'freeUsers') { 48 | 49 | $html = new genhtml($db); 50 | $html->createFreeUsersHtml($ROSTER, $WEEK); 51 | echo $html->getHtmlText(); 52 | 53 | } 54 | 55 | } else { 56 | die('invalid api call'); 57 | } 58 | -------------------------------------------------------------------------------- /api/pdf.php: -------------------------------------------------------------------------------- 1 | checkActive(); 6 | $api->checkAuth(); 7 | 8 | // parse parameter 9 | if(isset($_GET['view']) && isset($_GET['roster']) && isset($_GET['week'])) { 10 | $VIEW = $_GET['view']; 11 | $ROSTER = $_GET['roster']; 12 | $WEEK = $_GET['week']; 13 | } 14 | if(isset($_POST['view']) && isset($_POST['roster']) && isset($_POST['week'])) { 15 | $VIEW = $_POST['view']; 16 | $ROSTER = $_POST['roster']; 17 | $WEEK = $_POST['week']; 18 | } 19 | if(PHP_SAPI === 'cli') { 20 | foreach($argv as $arg) { 21 | if(tools::startsWith($arg, 'view=')) 22 | $VIEW = explode('=', $arg)[1]; 23 | if(tools::startsWith($arg, 'roster=')) 24 | $ROSTER = explode('=', $arg)[1]; 25 | if(tools::startsWith($arg, 'week=')) 26 | $WEEK = explode('=', $arg)[1]; 27 | } 28 | } 29 | 30 | // output 31 | if($VIEW && $ROSTER && $WEEK) { 32 | 33 | if($VIEW == 'plan') { 34 | 35 | $pdf = new genpdf($db); 36 | $pdf->createPlanPdf($ROSTER, $WEEK); 37 | $pdf->getPdfHandle()->Output('I', 'MASTERPLAN'); 38 | 39 | } 40 | elseif($VIEW == 'userServices') { 41 | 42 | $pdf = new genpdf($db); 43 | $pdf->createUserServicesPdf($ROSTER, $WEEK); 44 | $pdf->getPdfHandle()->Output('I', 'MASTERPLAN'); 45 | 46 | } 47 | elseif($VIEW == 'freeUsers') { 48 | 49 | $pdf = new genpdf($db); 50 | $pdf->createFreeUsersPdf($ROSTER, $WEEK); 51 | $pdf->getPdfHandle()->Output('I', 'MASTERPLAN'); 52 | 53 | } 54 | 55 | } else { 56 | die('invalid api call'); 57 | } 58 | -------------------------------------------------------------------------------- /lib/loader.php: -------------------------------------------------------------------------------- 1 | getUsers())); 49 | $roles = new roles($db); 50 | -------------------------------------------------------------------------------- /conf.php.example: -------------------------------------------------------------------------------- 1 | 'SUPERADMIN', 11 | 'admin' => 'SUPERADMIN', 12 | ]; 13 | 14 | ///// MySQL CONFIGURATION ///// 15 | const DB_HOST = '127.0.0.1'; 16 | const DB_NAME = 'masterplan'; 17 | const DB_USER = 'masterplan'; 18 | const DB_PASS = 'PASSWORD'; 19 | 20 | ///// LDAP CONFIGURATION (optional) ///// 21 | /* 22 | If you want to use LDAP user sync and login, please fill the following config lines. 23 | Otherwise, please set LDAP_SERVER to »null«. 24 | 25 | To sync LDAP users with the MASTERPLAN database, please execute "php lib/ldapsync.php" (via Cron) 26 | 27 | Set LDAP_SYNC_GROUP to »null« if you want to sync all users inside LDAP_QUERY_ROOT. 28 | Otherwise, insert the LDAP path of the group. 29 | */ 30 | 31 | // Example: 'ldap://192.168.56.101' (single) or 'ldaps://192.168.56.101' (secure) or 'ldaps://192.168.56.101 ldaps://192.168.56.102' (multiple) or null (disabled) 32 | const LDAP_SERVER = null; 33 | const LDAP_USER = ''; 34 | const LDAP_PASS = ''; 35 | 36 | // Example: 'subdomain.domain.tld' 37 | const LDAP_DOMAIN = ''; 38 | 39 | // Example: 'OU=Benutzer,DC=sieber,DC=systems' 40 | const LDAP_QUERY_ROOT = ''; 41 | 42 | // Example: 'CN=MasterplanUsers,OU=Benutzer,DC=sieber,DC=systems' or null 43 | const LDAP_SYNC_GROUP = null; 44 | -------------------------------------------------------------------------------- /lib/color.php: -------------------------------------------------------------------------------- 1 | > 0x10); 23 | $g = 0xFF & ($RGB >> 0x8); 24 | $b = 0xFF & $RGB; 25 | $r = ((float)$r) / 255.0; 26 | $g = ((float)$g) / 255.0; 27 | $b = ((float)$b) / 255.0; 28 | $maxC = max($r, $g, $b); 29 | $minC = min($r, $g, $b); 30 | $l = ($maxC + $minC) / 2.0; 31 | if($maxC == $minC) { 32 | $s = 0; 33 | $h = 0; 34 | } else { 35 | if($l < .5) { 36 | $s = ($maxC - $minC) / ($maxC + $minC); 37 | } else { 38 | $s = ($maxC - $minC) / (2.0 - $maxC - $minC); 39 | } 40 | if($r == $maxC) 41 | $h = ($g - $b) / ($maxC - $minC); 42 | if($g == $maxC) 43 | $h = 2.0 + ($b - $r) / ($maxC - $minC); 44 | if($b == $maxC) 45 | $h = 4.0 + ($r - $g) / ($maxC - $minC); 46 | $h = $h / 6.0; 47 | } 48 | 49 | $h = (int)round(255.0 * $h); 50 | $s = (int)round(255.0 * $s); 51 | $l = (int)round(255.0 * $l); 52 | 53 | return Array('hue' => $h, 'saturation' => $s, 'lightness' => $l); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /lib/phplot/contrib/color_range.test1.php: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 55 | -------------------------------------------------------------------------------- /frontend/img/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/views/start.php: -------------------------------------------------------------------------------- 1 | getUserRostersAdmin($currentUser->id); 5 | $userRosters = $db->getUserRosters($currentUser->id); 6 | ?> 7 | 8 |
9 | 10 |
11 |
12 |
13 | licenseUsers <= license::FREE_USERS) { ?> 14 | 15 |

16 | 17 | 18 |
19 |
20 | 21 | superadmin > 0 || count($adminRosters) > 0 || count($userRosters) > 0) { ?> 22 | 23 |
24 | 25 | licenseValid) { ?> 26 |

licenseCompany); ?>

27 | 28 | 29 | superadmin > 0) { ?> 30 |
31 | 32 | 33 | 0) { ?> 34 |
35 |
36 | 37 |
    38 | '.htmlspecialchars($ar->roster_title).''; 40 | } ?> 41 |
42 |
43 |
44 | 45 | 46 | 0) { ?> 47 |
48 |
49 | 50 |
    51 | '.htmlspecialchars($ar->roster_title).''; 53 | } ?> 54 |
55 |
56 |
57 | 58 | 59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /frontend/img/ok.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/swap.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/views/about.php: -------------------------------------------------------------------------------- 1 | 5 | 18 |
19 | 20 |
21 |
22 |
23 | 24 |

25 | 26 |

27 |

28 | 29 |

30 |

31 | https://georg-sieber.de 32 |
33 | it@georg-sieber.de 34 |

35 |
36 |
37 |
38 |

39 | 40 | 47 |
48 | -------------------------------------------------------------------------------- /frontend/img/delete.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/code.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/file.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/flash-auto.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/info-gray.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/user.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/clean.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /lib/phplot/contrib/README.txt: -------------------------------------------------------------------------------- 1 | This is the README for PHPlot Contributed Code 2 | The project web site is http://sourceforge.net/projects/phplot/ 3 | Last updated on 2011-08-05 4 | ----------------------------------------------------------------------------- 5 | 6 | The PHPlot Contributed Code directory contains code you might find useful 7 | with PHPlot, but that doesn't quite belong as part of PHPlot itself. 8 | 9 | You will have to read the comments in the code files, and see the example 10 | files, to determine what these do and if they are useful to you. None of 11 | these functions is documented in the PHPlot Reference Manual. 12 | 13 | You may include or paste these functions into your own scripts. Check the 14 | files for details, but some of these are considered "public domain" with no 15 | usage or license restrictions. 16 | 17 | ----------------------------------------------------------------------------- 18 | Contents: 19 | 20 | prune_labels: Reduce the number of labels along the X axis 21 | prune_labels.php . . . . . . . . . . . . Code 22 | prune_labels.example.php . . . . . . . . Example 23 | prune_labels.test.php . . . . . . . . . Test 24 | 25 | color_range: Create a gradient color map for data colors 26 | color_range.php . . . . . . . . . . . . Code 27 | color_range.example.php . . . . . . . . Example 28 | color_range.test1.php . . . . . . . . . Image creation test 29 | color_range.test2.php . . . . . . . . . Unit test 30 | 31 | data_table: Draw a table of data values on the plot 32 | data_table.php . . . . . . . . . . . . . Code 33 | data_table.example1.php . . . . . . . . Example: Stand-alone tables 34 | data_table.example2.php . . . . . . . . Example: Line plot with table 35 | data_table.example3.php . . . . . . . . Example: Pie chart with table 36 | 37 | ----------------------------------------------------------------------------- 38 | -------------------------------------------------------------------------------- /frontend/img/check.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/book.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/email.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/free.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/month.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/calendar.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/export.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/resource_types/Phone.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/roster.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/uncheck.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/info-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/chart.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/info.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/key.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/anniversary.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/note.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/cancel.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/ldap-directory.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/refresh.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/resources.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/image.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/lock.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/js/main.js: -------------------------------------------------------------------------------- 1 | function obj(id) { 2 | return document.getElementById(id); 3 | } 4 | function ajaxRequest(url, objID, callback) { 5 | var xhttp = new XMLHttpRequest(); 6 | xhttp.onreadystatechange = function() { 7 | if(this.readyState == 4 && this.status == 200) { 8 | if(obj(objID) != null) 9 | obj(objID).innerHTML = this.responseText; 10 | if(callback != undefined && typeof callback == 'function') 11 | callback(this.responseText); 12 | } 13 | }; 14 | xhttp.open("GET", url, true); 15 | xhttp.send(); 16 | } 17 | function ajaxRequestPost(url, body, objID, callback) { 18 | var xhttp = new XMLHttpRequest(); 19 | xhttp.onreadystatechange = function() { 20 | if(this.readyState == 4 && this.status == 200) { 21 | if(obj(objID) != null) 22 | obj(objID).innerHTML = this.responseText; 23 | if(callback != undefined && typeof callback == 'function') 24 | callback(this.responseText); 25 | } 26 | }; 27 | xhttp.open("POST", url, true); 28 | xhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 29 | xhttp.send(body); 30 | } 31 | function urlencodeObject(srcjson){ 32 | if(typeof srcjson !== "object") 33 | return null; 34 | var urljson = ""; 35 | var keys = Object.keys(srcjson); 36 | for(var i=0; i '.LANG['unable_to_change_password_ldap'].''); 10 | } 11 | 12 | if(isset($_POST['old_pw']) && isset($_POST['new_pw']) && isset($_POST['confirm_pw'])) { 13 | $error = false; 14 | 15 | if(!$error) if(!password_verify($_POST['old_pw'], $currentUser->password)) { 16 | $info = LANG['old_password_not_correct']; 17 | $infoclass = 'red'; 18 | $error = true; 19 | } 20 | if(!$error) if($_POST['new_pw'] != $_POST['confirm_pw']) { 21 | $info = LANG['passwords_do_not_match']; 22 | $infoclass = 'red'; 23 | $error = true; 24 | } 25 | 26 | if(!$error) if($db->updateUserPassword( 27 | $currentUser->id, 28 | password_hash($_POST['new_pw'], PASSWORD_DEFAULT) 29 | )) { 30 | $info = LANG['password_changed']; 31 | $infoclass = 'green'; 32 | } else { 33 | $info = LANG['password_could_not_be_changed'].' '.$db->getLastStatement()->error; 34 | $infoclass = 'red'; 35 | } 36 | } 37 | ?> 38 |
39 | 40 |
41 | 42 |
43 | 44 | 45 | 46 | 49 | 50 | 51 | 52 | 55 | 56 | 57 | 58 | 61 | 62 | 63 | 64 | 65 | 66 |
: 47 | 48 |
: 53 | 54 |
: 59 | 60 |
67 |
68 |
69 | -------------------------------------------------------------------------------- /frontend/img/resource_types/General.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/sync.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/ajaxHandler.php: -------------------------------------------------------------------------------- 1 | getUser($_SESSION['mp_userid']); 6 | 7 | 8 | if(isset($_POST['action'])) { 9 | if($_POST['action'] == 'remove_assignment' && !empty($_POST['id'])) { 10 | 11 | $ps = $db->getPlannedService($_POST['id']); 12 | if(!$perm->isUserAdminForRoster($currentUser, $ps->service_roster_id)) { 13 | die(LANG['no_admin_rights_for_this_roster']); 14 | } 15 | 16 | $plan = new plan($db); 17 | if($plan->removeAssignment($ps->id)) { 18 | die('OK'); 19 | } else { 20 | die(LANG['error'].': '.$db->getLastStatement()->error); 21 | } 22 | 23 | } 24 | elseif($_POST['action'] == 'remove_file' && !empty($_POST['id'])) { 25 | 26 | $plannedServiceFile = $db->getPlannedServiceFile($_POST['id']); 27 | if($plannedServiceFile != null) { 28 | $service = $db->getService($plannedServiceFile->service_id); 29 | if(!$perm->isUserAdminForRoster($currentUser, $service->roster_id)) { 30 | die(LANG['no_admin_rights_for_this_roster']); 31 | } 32 | 33 | if($db->removePlannedServiceFile($plannedServiceFile->id)) { 34 | die('OK'); 35 | } else { 36 | die(LANG['error'].': '.$db->getLastStatement()->error); 37 | } 38 | } 39 | 40 | } 41 | elseif($_POST['action'] == 'remove_resource' && !empty($_POST['id'])) { 42 | 43 | $plannedServiceResource = $db->getPlannedServiceResource($_POST['id']); 44 | if($plannedServiceResource != null) { 45 | $service = $db->getService($plannedServiceResource->service_id); 46 | if(!$perm->isUserAdminForRoster($currentUser, $service->roster_id)) { 47 | die(LANG['no_admin_rights_for_this_roster']); 48 | } 49 | 50 | if($db->removePlannedServiceResource($plannedServiceResource->id)) { 51 | die('OK'); 52 | } else { 53 | die(LANG['error'].': '.$db->getLastStatement()->error); 54 | } 55 | } 56 | 57 | } 58 | elseif($_POST['action'] == 'set_scroll' && !empty($_POST['scroll'])) { 59 | 60 | $_SESSION['scroll'] = $_POST['scroll']; 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /frontend/img/grid.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/template.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/attach-file.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /lib/mailer.php: -------------------------------------------------------------------------------- 1 | dbhandle = $db; 8 | } 9 | 10 | function mailNewSwap($roster_id) { 11 | // send mail to all roster users 12 | foreach($this->dbhandle->getRosterUsers($roster_id) as $u) { 13 | if(!tools::isValidEmail($u->user_email)) continue; 14 | $body = texttemplate::processTemplate('mail_new_swap_service.txt', null); 15 | mail($u->user_email, LANG['new_service_swap_request'], $body); 16 | } 17 | } 18 | 19 | function mailNewAbsence($userid) { 20 | // send mail to all roster admins for approval 21 | foreach($this->dbhandle->getUserRosters($userid) as $ur) { 22 | foreach($this->dbhandle->getRosterAdmins($ur->roster_id) as $u) { 23 | if(!tools::isValidEmail($u->user_email)) continue; 24 | $body = texttemplate::processTemplate('mail_new_absence.txt', null); 25 | mail($u->user_email, LANG['new_absence_request'], $body); 26 | } 27 | } 28 | } 29 | 30 | function mailAbsenceApproved1($absence_id) { 31 | $absence = $this->dbhandle->getAbsence($absence_id); 32 | $user = $this->dbhandle->getUser($absence->user_id); 33 | if(tools::isValidEmail($user->email)) { 34 | $body = texttemplate::processTemplate('mail_absence_approved1.txt', null); 35 | mail($user->email, LANG['absence_request_confirmed'], $body); 36 | } 37 | } 38 | 39 | function mailAbsenceApproved2($absence_id) { 40 | $absence = $this->dbhandle->getAbsence($absence_id); 41 | $user = $this->dbhandle->getUser($absence->user_id); 42 | if(tools::isValidEmail($user->email)) { 43 | $body = texttemplate::processTemplate('mail_absence_approved2.txt', null); 44 | mail($user->email, LANG['absence_request_approved'], $body); 45 | } 46 | } 47 | 48 | function mailAbsenceDeclined($absence_id) { 49 | $absence = $this->dbhandle->getAbsence($absence_id); 50 | $user = $this->dbhandle->getUser($absence->user_id); 51 | if(tools::isValidEmail($user->email)) { 52 | $body = texttemplate::processTemplate('mail_absence_declined.txt', null); 53 | mail($user->email, LANG['absence_request_declined'], $body); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /frontend/img/users.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/checklist.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 49 | 51 | 54 | 55 | 57 | 61 | 62 | 67 | 68 | -------------------------------------------------------------------------------- /frontend/img/resource_types/Car.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/img/resource_types/Computer.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 49 | 51 | 54 | 55 | 57 | 61 | 62 | 67 | 68 | -------------------------------------------------------------------------------- /frontend/views/viewIcsUrl.php: -------------------------------------------------------------------------------- 1 | id.'&auth='.md5($currentUser->password).'&view='.$view; 9 | if($roster_id != -1) $param .= '&roster='.$roster_id; 10 | $server = $_SERVER['HTTP_HOST']; 11 | $link = "$protocol://$server$path$param"; 12 | return $link; 13 | } 14 | ?> 15 | 16 | 23 | 24 |
25 |

26 |
27 | 28 |
29 |

30 | 31 | getUserRosters($currentUser->id) as $r) { ?> 32 | 33 | 34 |
35 | 36 | 48 | -------------------------------------------------------------------------------- /frontend/export.php: -------------------------------------------------------------------------------- 1 | getUser($_SESSION['mp_userid']); 8 | 9 | if(isset($_GET['export']) && isset($_GET['type'])) { 10 | if($_GET['export'] == 'plan' && !empty($_GET['roster']) && !empty($_GET['week'])) { 11 | // check user rights 12 | if($perm->isUserAdminForRoster($currentUser, $_GET['roster']) 13 | || $perm->isUserAssignedToRoster($currentUser, $_GET['roster'])) { 14 | if($_GET['type'] == 'pdf') { 15 | $pdf = new genpdf($db); 16 | $pdf->createPlanPdf($_GET['roster'], $_GET['week']); 17 | $pdf->getPdfHandle()->Output('I', 'MASTERPLAN'); 18 | die(); 19 | } 20 | } else { 21 | die(LANG['permission_error']); 22 | } 23 | } 24 | elseif($_GET['export'] == 'userServices' && !empty($_GET['roster']) && !empty($_GET['week'])) { 25 | // check user rights 26 | if($perm->isUserAdminForRoster($currentUser, $_GET['roster'])) { 27 | if($_GET['type'] == 'pdf') { 28 | $pdf = new genpdf($db); 29 | $pdf->createUserServicesPdf($_GET['roster'], $_GET['week']); 30 | $pdf->getPdfHandle()->Output('I', 'MASTERPLAN'); 31 | die(); 32 | } 33 | } else { 34 | die(LANG['permission_error']); 35 | } 36 | } 37 | elseif($_GET['export'] == 'freeUsers' && !empty($_GET['roster']) && !empty($_GET['week'])) { 38 | // check user rights 39 | if($perm->isUserAdminForRoster($currentUser, $_GET['roster'])) { 40 | if($_GET['type'] == 'pdf') { 41 | $pdf = new genpdf($db); 42 | $pdf->createFreeUsersPdf($_GET['roster'], $_GET['week']); 43 | $pdf->getPdfHandle()->Output('I', 'MASTERPLAN'); 44 | die(); 45 | } 46 | } else { 47 | die(LANG['permission_error']); 48 | } 49 | } 50 | elseif($_GET['export'] == 'absence' && !empty($_GET['user'])) { 51 | // check user rights 52 | if($perm->isUserSuperadmin($currentUser) || $currentUser->id == $_GET['user']) { 53 | if($_GET['type'] == 'pdf') { 54 | $pdf = new genpdf($db); 55 | $pdf->createAbsencePdf($_GET['user']); 56 | $pdf->getPdfHandle()->Output('I', 'MASTERPLAN'); 57 | die(); 58 | } 59 | } else { 60 | die(LANG['permission_error']); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/phplot/contrib/data_table.example1.php: -------------------------------------------------------------------------------- 1 | array("Label", 'Y1', 'Y2', 'Y3'), 32 | 'column_widths' => array(3, 1, 2, 3), 33 | 'column_formats' => array('%s', '%d', '%5.2f', '%6g'), 34 | 'width' => $tbl_width, 35 | 'height' => $tbl_height, 36 | 'data' => $data, 37 | 'column_alignments' => array('C', 'R', 'R', 'R'), 38 | ); 39 | 40 | $img = imagecreate($img_width, $img_height); 41 | $white = imagecolorresolve($img, 255, 255, 255); 42 | $red = imagecolorresolve($img, 255, 0, 0); 43 | imageline($img, 0, $cy, $img_width-1, $cy, $red); 44 | imageline($img, $cx, 0, $cx, $img_height-1, $red); 45 | 46 | draw_data_table($img, array_merge($base_settings, array( 47 | 'position' => array(10, 10), 48 | ))); 49 | draw_data_table($img, array_merge($base_settings, array( 50 | 'position' => array($cx + 10, 10), 51 | 'cellpadding' => 12, 52 | 'column_alignments' => array('R', 'L', 'R', 'R'), 53 | ))); 54 | draw_data_table($img, array_merge($base_settings, array( 55 | 'position' => array(10, $cy + 10), 56 | 'color' => array(0x66, 0x66, 0xcc), 57 | ))); 58 | draw_data_table($img, array_merge($base_settings, array( 59 | 'position' => array($cx + 10, $cy + 10), 60 | 'font' => 4, 61 | ))); 62 | 63 | imagepng($img); 64 | -------------------------------------------------------------------------------- /frontend/img/loader.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 13 | 14 | 15 | 19 | 20 | 21 | 25 | 26 | 27 | 31 | 32 | 33 | 37 | 38 | 39 | 43 | 44 | 45 | 49 | 50 | 51 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /frontend/img/birthday.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/views/holidays.php: -------------------------------------------------------------------------------- 1 | superadmin == 0) { 8 | die('
'.LANG['page_superadmin_right_needed'].'
'); 9 | } 10 | 11 | if(!empty($_POST['action'])) { 12 | if($_POST['action'] == 'removeHoliday' && !empty($_POST['id'])) { 13 | if($db->removeHoliday($_POST['id'])) { 14 | $info = LANG['holiday_removed']; 15 | $infoclass = 'green'; 16 | } else { 17 | $info = LANG['holiday_could_not_be_removed']; 18 | $infoclass = 'red'; 19 | } 20 | } 21 | } 22 | ?> 23 | 24 |
25 |

(getHolidays()); ?>)

26 | 27 |
28 | 29 | 30 |
31 |
32 | 33 | 34 |
35 |
36 | 37 | 38 | 39 | 40 | 41 | getHolidays() as $h) { 43 | $service_title = ''.LANG['all'].''; 44 | if($h->service_id != null) { 45 | $service_title = htmlspecialchars($h->service_shortname." ".$h->service_title); 46 | } 47 | 48 | echo ''; 49 | echo ''; 50 | echo ''; 51 | echo ''; 52 | echo ''; 60 | echo ''; 61 | } 62 | ?> 63 |
'.htmlspecialchars($h->title).''.htmlspecialchars($h->day).''.$service_title.'' 53 | .'' 54 | .'
' 55 | .'' 56 | .'' 57 | .'' 58 | .'
' 59 | .'
64 |
65 | -------------------------------------------------------------------------------- /frontend/img/roles.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 58 | 59 | -------------------------------------------------------------------------------- /frontend/views/userBirthdays.php: -------------------------------------------------------------------------------- 1 | superadmin == 0) { 8 | die('
Sie benötigen Superadmin-Berechtigungen um diese Seite aufzurufen
'); 9 | } 10 | 11 | $birthdayUsers = []; 12 | foreach($db->getUsers() as $u) { 13 | if(trim($u->birthday) != '') 14 | $birthdayUsers[] = $u; 15 | } 16 | usort($birthdayUsers, 'sortBirthdays'); 17 | 18 | function sortBirthdays($a, $b) { 19 | $currentYearA = date('Y'); 20 | $timeBirthdayA = strtotime($a->birthday); 21 | $timeNextBirthdayA = strtotime($currentYearA.'-'.date('m',$timeBirthdayA).'-'.date('d',$timeBirthdayA)); 22 | if($timeNextBirthdayA < strtotime(date('Y-m-d'))) 23 | $timeNextBirthdayA = strtotime('+ 1 year', $timeNextBirthdayA); 24 | 25 | $currentYearB = date('Y'); 26 | $timeBirthdayB = strtotime($b->birthday); 27 | $timeNextBirthdayB = strtotime($currentYearB.'-'.date('m',$timeBirthdayB).'-'.date('d',$timeBirthdayB)); 28 | if($timeNextBirthdayB < strtotime(date('Y-m-d'))) 29 | $timeNextBirthdayB = strtotime('+ 1 year', $timeNextBirthdayB); 30 | 31 | if($timeNextBirthdayA == $timeNextBirthdayB) { 32 | return 0; 33 | } 34 | return ($timeNextBirthdayA < $timeNextBirthdayB) ? -1 : 1; 35 | } 36 | ?> 37 | 38 |
39 |

Kommende Geburtstage

40 | 41 | 42 | 43 | 44 | 45 | birthday); 48 | $isToday = (date('m-d',$timeBirthday) == date('m-d')); 49 | 50 | $timeNextBirthday = strtotime(date('Y').'-'.date('m',$timeBirthday).'-'.date('d',$timeBirthday)); 51 | if($timeNextBirthday < strtotime(date('Y-m-d'))) 52 | $timeNextBirthday = strtotime('+ 1 year', $timeNextBirthday); 53 | 54 | echo ''; 55 | echo ''; 56 | echo ''; 57 | echo ''; 58 | echo ''; 59 | echo ''; 60 | } 61 | ?> 62 |
MitarbeiterE-MailGeburtstagAlter
'; boxes::echoUser($u); echo ''.htmlspecialchars($u->email).''.htmlspecialchars(strftime(DATE_FORMAT, $timeBirthday)).''.(date('Y', $timeNextBirthday)-date('Y', $timeBirthday)).'
63 |
64 | -------------------------------------------------------------------------------- /frontend/views/deployFile.php: -------------------------------------------------------------------------------- 1 | getService($_GET['service']); 17 | } else { 18 | die('
'.LANG['service_not_found'].'
'); 19 | } 20 | 21 | if(isset($_POST['service']) && isset($_POST['day']) && isset($_FILES['file'])) { 22 | // check user rights 23 | if($perm->isUserAdminForRoster($currentUser, $service->roster_id)) { 24 | 25 | if($db->createPlannedServiceFile($_POST['service'], $_POST['day'], $_FILES['file']['name'], file_get_contents($_FILES['file']['tmp_name']))) { 26 | echo ""; 27 | die(); 28 | } else { 29 | $info = LANG['error'].': '.$db->getLastStatement()->error; 30 | $infoclass = 'red'; 31 | } 32 | 33 | } else { 34 | $info = LANG['no_admin_rights_for_this_roster']; 35 | $infoclass = 'yellow'; 36 | } 37 | } 38 | ?> 39 |
40 |

41 | 42 |
43 | 44 |
45 | 46 | 47 | 48 | 52 | 53 | 54 | 55 | 59 | 60 | 61 | 62 | 65 | 66 | 67 | 68 | 69 | 70 |
: 49 | 50 | 51 |
: 56 | 57 | title); ?>"> 58 |
: 63 | 64 |
71 |
72 |
73 | -------------------------------------------------------------------------------- /frontend/img/absent.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 49 | 51 | 54 | 55 | 57 | 61 | 62 | 67 | 72 | 73 | -------------------------------------------------------------------------------- /frontend/views/deployNote.php: -------------------------------------------------------------------------------- 1 | getService($_GET['service']); 17 | } else { 18 | die('
'.LANG['service_not_found'].'
'); 19 | } 20 | 21 | $notes = $db->getPlannedServiceNotes($service->id, $day); 22 | 23 | if(isset($_POST['service']) && isset($_POST['day']) && isset($_POST['note'])) { 24 | // check user rights 25 | if($perm->isUserAdminForRoster($currentUser, $service->roster_id)) { 26 | 27 | if($db->updatePlannedServiceNote($_POST['service'], $_POST['day'], $_POST['note'])) { 28 | echo ""; 29 | die(); 30 | } else { 31 | $info = LANG['error'].': '.$db->getLastStatement()->error; 32 | $infoclass = 'red'; 33 | } 34 | 35 | } else { 36 | $info = LANG['no_admin_rights_for_this_roster']; 37 | $infoclass = 'yellow'; 38 | } 39 | } 40 | ?> 41 |
42 |

43 | 44 |
45 | 46 |
47 | 48 | 49 | 50 | 54 | 55 | 56 | 57 | 61 | 62 | 63 | 64 | 67 | 68 | 69 | 70 | 71 | 72 |
: 51 | 52 | 53 |
: 58 | 59 | title); ?>"> 60 |
: 65 | 66 |
73 |
74 |
75 | -------------------------------------------------------------------------------- /frontend/views/userAnniversaries.php: -------------------------------------------------------------------------------- 1 | superadmin == 0) { 8 | die('
'.LANG['page_superadmin_right_needed'].'
'); 9 | } 10 | 11 | $users = []; 12 | foreach($db->getUsers() as $u) { 13 | if(trim($u->start_date) != '') 14 | $users[] = $u; 15 | } 16 | usort($users, 'sortAnniversaries'); 17 | 18 | function sortAnniversaries($a, $b) { 19 | $currentYearA = date('Y'); 20 | $timeBirthdayA = strtotime($a->start_date); 21 | $timeNextBirthdayA = strtotime($currentYearA.'-'.date('m',$timeBirthdayA).'-'.date('d',$timeBirthdayA)); 22 | if($timeNextBirthdayA < strtotime(date('Y-m-d'))) 23 | $timeNextBirthdayA = strtotime('+ 1 year', $timeNextBirthdayA); 24 | 25 | $currentYearB = date('Y'); 26 | $timeBirthdayB = strtotime($b->start_date); 27 | $timeNextBirthdayB = strtotime($currentYearB.'-'.date('m',$timeBirthdayB).'-'.date('d',$timeBirthdayB)); 28 | if($timeNextBirthdayB < strtotime(date('Y-m-d'))) 29 | $timeNextBirthdayB = strtotime('+ 1 year', $timeNextBirthdayB); 30 | 31 | if($timeNextBirthdayA == $timeNextBirthdayB) { 32 | return 0; 33 | } 34 | return ($timeNextBirthdayA < $timeNextBirthdayB) ? -1 : 1; 35 | } 36 | ?> 37 | 38 |
39 |

40 | 41 | 42 | 43 | 44 | 45 | start_date); 48 | $isToday = (date('m-d',$timeStart) == date('m-d')); 49 | 50 | $timeNext = strtotime(date('Y').'-'.date('m',$timeStart).'-'.date('d',$timeStart)); 51 | if($timeNext < strtotime(date('Y-m-d'))) 52 | $timeNext = strtotime('+ 1 year', $timeNext); 53 | 54 | echo ''; 55 | echo ''; 56 | echo ''; 57 | echo ''; 58 | echo ''; 59 | echo ''; 60 | } 61 | ?> 62 |
'; boxes::echoUser($u); echo ''.htmlspecialchars($u->email).''.htmlspecialchars(strftime(DATE_FORMAT, $timeStart)).''.htmlspecialchars(strftime(DATE_FORMAT, $timeNext)).': '.(date('Y', $timeNext)-date('Y', $timeStart)).' Jahr(en)
63 |
64 | -------------------------------------------------------------------------------- /frontend/img/ok1.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 59 | 1 70 | 71 | -------------------------------------------------------------------------------- /frontend/img/ok2.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 30 | 50 | 54 | 59 | 2 70 | 71 | -------------------------------------------------------------------------------- /lib/browser.php: -------------------------------------------------------------------------------- 1 | checkBrowser(); 10 | } 11 | 12 | private function checkBrowser() { 13 | if($this->isInternetExplorer()) { 14 | $this->valid = false; 15 | $this->message = LANG['browser_not_supported']; 16 | } 17 | elseif($this->isFirefox()) { 18 | $this->valid = false; 19 | $this->message = LANG['browser_not_supported_calendar_field']; 20 | } 21 | elseif($this->isSafari()) { 22 | $this->valid = false; 23 | $this->message = LANG['browser_not_supported_calendar_field']; 24 | } 25 | else { 26 | $this->valid = true; 27 | } 28 | } 29 | 30 | private function isInternetExplorer() { 31 | $ua = $_SERVER["HTTP_USER_AGENT"]; 32 | return (preg_match('~MSIE|Internet Explorer~i', $ua) || (strpos($ua, 'Trident/7.0; rv:11.0') !== false)); 33 | } 34 | 35 | private function isFirefox() { 36 | $ua = $_SERVER["HTTP_USER_AGENT"]; 37 | return boolval(strpos($ua, 'Firefox')); 38 | } 39 | 40 | private function isSafari() { 41 | $ua = $_SERVER["HTTP_USER_AGENT"]; 42 | return (strpos($ua, 'Safari') && !strpos($ua, 'Chrome')); 43 | } 44 | 45 | /* functions for detecting browsers and operating systems */ 46 | public static function getOperatingSystem() { 47 | $ua = $_SERVER["HTTP_USER_AGENT"]; 48 | if(strpos($ua, 'Android')) 49 | return "Android"; 50 | elseif(strpos($ua, 'iPhone') || strpos($ua, 'iPad')) 51 | return "iPhone"; 52 | elseif(strpos($ua, 'Palm')) 53 | return "Palm"; 54 | elseif(strpos($ua, 'Linux')) 55 | return "Linux"; 56 | elseif(strpos($ua, 'Macintosh')) 57 | return "Macintosh"; 58 | elseif(strpos($ua, 'Windows')) 59 | return "Windows"; 60 | else 61 | return "Unknown"; 62 | } 63 | 64 | /*** for detecting different versions 65 | $msie_7 = strpos($ua, 'MSIE 7.0') ? true : false; 66 | $msie_8 = strpos($ua, 'MSIE 8.0') ? true : false; 67 | $firefox_2 = strpos($ua, 'Firefox/2.0') ? true : false; 68 | $firefox_3 = strpos($ua, 'Firefox/3.0') ? true : false; 69 | $firefox_3_6 = strpos($ua, 'Firefox/3.6') ? true : false; 70 | $safari_2 = strpos($ua, 'Safari/419') ? true : false; // Safari 2 71 | $safari_3 = strpos($ua, 'Safari/525') ? true : false; // Safari 3 72 | $safari_3_1 = strpos($ua, 'Safari/528') ? true : false; // Safari 3.1 73 | $safari_4 = strpos($ua, 'Safari/531') ? true : false; // Safari 4 74 | */ 75 | 76 | } 77 | -------------------------------------------------------------------------------- /frontend/views/resources.php: -------------------------------------------------------------------------------- 1 | superadmin == 0) { 8 | die('
'.LANG['page_superadmin_right_needed'].'
'); 9 | } 10 | 11 | if(!empty($_POST['action'])) { 12 | if($_POST['action'] == 'removeResource' && !empty($_POST['id'])) { 13 | if($db->removeResource($_POST['id'])) { 14 | $info = LANG['resource_removed']; 15 | $infoclass = 'green'; 16 | } else { 17 | $info = LANG['error'].': '.$db->getLastStatement()->error; 18 | $infoclass = 'red'; 19 | } 20 | } 21 | } 22 | ?> 23 | 24 |
25 |

(getResources()); ?>)

26 | 27 |
28 | 29 | 30 |
31 |
32 | 33 | 34 |
35 |
36 | 37 | 38 | 39 | 40 | 41 | getResources() as $r) { 43 | echo ''; 44 | echo ''; 48 | echo ''; 49 | echo ''; 50 | echo ''; 51 | echo ''; 59 | echo ''; 60 | } 61 | ?> 62 |
/
' 45 | .(($r->icon != null && $r->icon != '') ? ' ' : '') 46 | .' ' 47 | .''.htmlspecialchars($r->type).''.htmlspecialchars($r->title).''.htmlspecialchars(tools::shortText($r->description)).'' 52 | .'' 53 | .'
' 54 | .'' 55 | .'' 56 | .'' 57 | .'
' 58 | .'
63 |
64 | -------------------------------------------------------------------------------- /lib/plan.php: -------------------------------------------------------------------------------- 1 | dbhandle = $dbhandle; 8 | } 9 | 10 | public function getConsolidatedServicesByRosterAndDay($roster_id, $day) { 11 | // check if service is canceled because of a defined holiday 12 | $services = []; 13 | $holidays = $this->dbhandle->getHolidays(); 14 | foreach($this->dbhandle->getServicesByRosterAndDay($roster_id, $day) as $s) { 15 | if(count($holidays) == 0) { 16 | $services[] = $s; 17 | } else { 18 | foreach($holidays as $holiday) { 19 | if(!($holiday->day == $day && ($holiday->service_id == null || $holiday->service_id == $s->id))) { 20 | $services[] = $s; 21 | break; 22 | } 23 | } 24 | } 25 | } 26 | return $services; 27 | } 28 | 29 | public function removeAssignment($id) { 30 | $ps = $this->dbhandle->getPlannedService($id); 31 | if($ps == null) return false; 32 | 33 | $sendCancelMail = false; 34 | if($ps->icsmail_sent != null && $ps->icsmail_sent != 0) $sendCancelMail = true; 35 | 36 | if(!$this->dbhandle->removePlannedService($ps->id)) { 37 | return false; 38 | } else { 39 | if($sendCancelMail) { 40 | $this->sendIcsMail($ps, true); 41 | } 42 | return true; 43 | } 44 | } 45 | 46 | public function sendIcsMail($ps, $cancel) { 47 | if(tools::isValidEmail($ps->user_email)) { 48 | $icsDomain = $this->dbhandle->getSetting('ics_domain'); 49 | $icsRoster = $this->dbhandle->getRoster($ps->service_roster_id); 50 | 51 | $body = texttemplate::processTemplate('icsmail_text.txt', null); 52 | if($cancel) $body = texttemplate::processTemplate('icsmail_text_cancel.txt', null); 53 | 54 | $ics = ics::compileIcsBody( 55 | $ps->id, 56 | $icsDomain, 57 | $icsRoster->icsmail_sender_name, 58 | $icsRoster->icsmail_sender_address, 59 | $ps->user_fullname, $ps->user_email, 60 | strtotime($ps->day.' '.$ps->service_start), 61 | strtotime($ps->day.' '.$ps->service_end), 62 | $ps->service_shortname, 63 | $ps->service_title, 64 | $ps->service_location, 65 | $cancel 66 | ); 67 | $success = ics::sendIcsMail( 68 | $icsRoster->icsmail_sender_name, 69 | $icsRoster->icsmail_sender_address, 70 | $ps->user_email, 71 | $ps->service_shortname, 72 | $body, $ics 73 | ); 74 | if($cancel) { 75 | $this->dbhandle->setPlannedServiceSent($ps->id, 0); 76 | } else { 77 | $this->dbhandle->setPlannedServiceSent($ps->id, 1); 78 | } 79 | return $success; 80 | } else { 81 | return false; 82 | } 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /frontend/img/absent-last-minute.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | image/svg+xml 46 | 48 | 53 | 54 | 57 | 60 | 61 | 64 | 68 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /frontend/views/editTextTemplates.php: -------------------------------------------------------------------------------- 1 | superadmin == 0) { 8 | die('
'.LANG['page_superadmin_right_needed'].'
'); 9 | } 10 | 11 | // update 12 | if(isset($_POST['writefile']) && isset($_POST['text'])) { 13 | $escapedFilename = str_replace('/','',$_POST['writefile']); 14 | if(file_exists(TEMPLATE_FILES.'/'.$escapedFilename) && file_put_contents(TEMPLATE_FILES.'/'.$escapedFilename, $_POST['text'])) { 15 | $info = LANG['template_saved']; 16 | $infoclass = 'green'; 17 | } else { 18 | $info = LANG['template_could_not_be_saved']; 19 | $infoclass = 'red'; 20 | } 21 | } 22 | ?> 23 | 24 | 25 |
26 | 27 | 28 |
29 |

30 | 31 |
32 |
33 | 43 |
44 | 45 |
46 |
47 | 48 | 53 |
54 |

55 | 56 |
57 |
58 | 59 | 60 |
61 |

62 |

63 |
$$BASE_URL$$ -
64 |

65 | 66 |
67 |
68 | 71 |
72 |
73 |
74 | 78 | -------------------------------------------------------------------------------- /api/ics.php: -------------------------------------------------------------------------------- 1 | checkActive(); 6 | 7 | if(!empty($_GET['user']) 8 | && !empty($_GET['auth']) 9 | && !empty($_GET['view'])) { 10 | 11 | $user = $db->getUser($_GET['user']); 12 | if(md5($user->password) != $_GET['auth']) die('authentication failed'); 13 | 14 | $icsDomain = $db->getSetting('ics_domain', ''); 15 | 16 | if($_GET['view'] == 'userServices') { 17 | 18 | // query planned services 19 | $allPlannedServices = $db->getPlannedServicesByUser($user->id); 20 | foreach($allPlannedServices as $ps) { 21 | // check if roster is released 22 | $released = false; 23 | foreach($db->getReleasedPlansByRoster($ps->service_roster_id) as $rp) { 24 | if($rp->day == $ps->day) { 25 | $released = true; 26 | break; 27 | } 28 | } 29 | if($released) { 30 | $icsRoster = $db->getRoster($ps->service_roster_id); 31 | $ics = ics::compileIcsBody( 32 | $ps->id, 33 | $icsDomain, 34 | $icsRoster->icsmail_sender_name, 35 | $icsRoster->icsmail_sender_address, 36 | $ps->user_fullname, $ps->user_email, 37 | strtotime($ps->day.' '.$ps->service_start), 38 | strtotime($ps->day.' '.$ps->service_end), 39 | $ps->service_shortname, 40 | $ps->service_title, 41 | $ps->service_location, 42 | false 43 | ); 44 | echo $ics."\n\n"; 45 | } 46 | } 47 | 48 | } 49 | elseif($_GET['view'] == 'roster' && !empty($_GET['roster'])) { 50 | 51 | // check permissions 52 | if(! 53 | ($perm->isUserAdminForRoster($user, $_GET['roster']) 54 | || $perm->isUserAssignedToRoster($user, $_GET['roster'])) 55 | ) { 56 | die('permission violation'); 57 | } 58 | // query planned services 59 | $allPlannedServices = $db->getPlannedServicesWithUserByRoster($_GET['roster']); 60 | foreach($allPlannedServices as $ps) { 61 | // check if roster is released 62 | $released = false; 63 | foreach($db->getReleasedPlansByRoster($ps->service_roster_id) as $rp) { 64 | if($rp->day == $ps->day) { 65 | $released = true; 66 | break; 67 | } 68 | } 69 | if($released) { 70 | $icsRoster = $db->getRoster($ps->service_roster_id); 71 | $ics = ics::compileIcsBody( 72 | $ps->id, 73 | $icsDomain, 74 | $icsRoster->icsmail_sender_name, 75 | $icsRoster->icsmail_sender_address, 76 | $ps->user_fullname, $ps->user_email, 77 | strtotime($ps->day.' '.$ps->service_start), 78 | strtotime($ps->day.' '.$ps->service_end), 79 | $ps->service_shortname, 80 | $ps->service_title, 81 | $ps->service_location, 82 | false 83 | ); 84 | echo $ics."\n\n"; 85 | } 86 | } 87 | 88 | } 89 | else { 90 | die('invalid api call'); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /frontend/views/dbMaintenance.php: -------------------------------------------------------------------------------- 1 | superadmin == 0) { 8 | die('
'.LANG['page_superadmin_right_needed'].'
'); 9 | } 10 | 11 | // cleanup selected items 12 | if(isset($_POST['date'])) { 13 | $success = null; 14 | if($success !== false && isset($_POST['clear_old_assignments']) && $_POST['clear_old_assignments'] == 1) { 15 | $success = $db->removePlannedServicesOlderThan($_POST['date']); 16 | } 17 | if($success !== false && isset($_POST['clear_old_absences']) && $_POST['clear_old_absences'] == 1) { 18 | $success = $db->removeAbsencesOlderThan($_POST['date']); 19 | } 20 | if($success !== false && isset($_POST['clear_old_swaps']) && $_POST['clear_old_swaps'] == 1) { 21 | $success = $db->removeSwapServicesOlderThan($_POST['date']); 22 | } 23 | if($success !== false && isset($_POST['clear_old_services']) && $_POST['clear_old_services'] == 1) { 24 | $success = $db->removeExpiredServices(); 25 | } 26 | if($success === true) { 27 | $info = LANG['database_cleaned']; 28 | $infoclass = 'green'; 29 | } elseif($success === null) { 30 | $info = LANG['no_action_selected']; 31 | $infoclass = 'yellow'; 32 | } else { 33 | $info = LANG['error'].': '.$db->getLastStatement()->error; 34 | $infoclass = 'red'; 35 | } 36 | } 37 | ?> 38 |
39 |

40 | 41 |
42 | 43 |
44 | 45 |
46 |
47 | 51 |

52 | 56 |
57 | 61 |
62 | 66 |
67 | 71 |
72 | 73 |
74 |
75 |
76 | -------------------------------------------------------------------------------- /frontend/views/roles.php: -------------------------------------------------------------------------------- 1 | superadmin == 0) { 8 | die('
'.LANG['page_superadmin_right_needed'].'
'); 9 | } 10 | 11 | if(!empty($_POST['action'])) { 12 | if($_POST['action'] == 'removeRole' && !empty($_POST['id'])) { 13 | if($db->removeRole($_POST['id'])) { 14 | $info = LANG['role_removed']; 15 | $infoclass = 'green'; 16 | } else { 17 | $info = LANG['error'].': '.$db->getLastStatement()->error; 18 | $infoclass = 'red'; 19 | } 20 | } 21 | } 22 | ?> 23 | 24 |
25 |

(getRoles()); ?>)

26 | 27 |
28 | 29 | 30 |
31 |
32 | 33 | 34 |
35 |
36 | 37 | 38 | 39 | 40 | 41 | getRoles() as $r) { 43 | // count assigned users 44 | $amount_users = 0; 45 | foreach($db->getUsers() as $u) { 46 | if($r != null) foreach($db->getUserRoles($u->id) as $role) { 47 | if($r->id == $role->role_id) { 48 | $amount_users ++; 49 | } 50 | } 51 | } 52 | 53 | echo ''; 54 | echo ''; 55 | echo ''; 56 | echo ''; 57 | echo ''; 58 | echo ''; 59 | echo ''; 60 | echo ''; 68 | echo ''; 69 | } 70 | ?> 71 |
'.htmlspecialchars($r->title).''.htmlspecialchars($r->max_hours_per_day).''.htmlspecialchars($r->max_services_per_week).''.htmlspecialchars($r->max_hours_per_week).''.htmlspecialchars($r->max_hours_per_month).''.$amount_users.'' 61 | .'' 62 | .'
' 63 | .'' 64 | .'' 65 | .'' 66 | .'
' 67 | .'
72 |
73 | -------------------------------------------------------------------------------- /frontend/views/assignUsersToRoster.php: -------------------------------------------------------------------------------- 1 | superadmin == 0) { 8 | die('
'.LANG['page_superadmin_right_needed'].'
'); 9 | } 10 | 11 | $roster = null; 12 | 13 | if(isset($_GET['roster'])) { 14 | $roster = $db->getRoster($_GET['roster']); 15 | } else { 16 | die('
'.LANG['roster_not_found'].'
'); 17 | } 18 | 19 | if(!empty($_POST['roster']) && !empty($_POST['users'])) { 20 | $success = null; 21 | 22 | $db->beginTransaction(); 23 | $success = $db->removeUserToRosterByRoster($_POST['roster']); 24 | foreach($_POST['users'] as $uid) { 25 | if($success == null || $success == true) 26 | $success = $db->insertUserToRoster($uid, $_POST['roster']); 27 | } 28 | 29 | if($success) { 30 | $db->commitTransaction(); 31 | header('Location: index.php?view=rosters'); 32 | die(); 33 | } else { 34 | $db->rollbackTransaction(); 35 | $info = LANG['employee_could_not_be_assigned'].' '.$db->getLastStatement()->error; 36 | $infoclass = 'red'; 37 | } 38 | } 39 | ?> 40 |
41 |

42 | 43 |
44 | 45 |
46 | 47 | 48 | 49 | 53 | 54 | 55 | 61 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
: 50 | 51 | 52 |
56 | : 57 |
58 | 59 |
60 |
62 | 75 |
86 |
87 |
88 | -------------------------------------------------------------------------------- /frontend/setup.php: -------------------------------------------------------------------------------- 1 | existsSchema(); 8 | 9 | if($schemaExists && count($db->getUsers()) > 0) die(); 10 | 11 | if(isset($_POST['username']) && isset($_POST['password']) && isset($_POST['password2'])) { 12 | if($_POST['password'] == $_POST['password2']) { 13 | $id = $db->createUser( 14 | 1, // superadmin-flag 15 | $_POST['username'], // login 16 | '', // firstname 17 | '', // lastname 18 | 'Administrator', // fullname 19 | '', // email 20 | '', // phone 21 | '', // mobile 22 | null, // birthday 23 | date('Y-m-d'), // start date 24 | '', // id_no 25 | 'initial admin user', // description 26 | 0, // ldap-flag 27 | 0, // locked-flag 28 | -1, // max hours per day 29 | -1, // may services per week 30 | -1, // may hours per week 31 | -1, // max hours per month 32 | '#fff' // color 33 | ); 34 | $db->updateUserPassword( 35 | $id, password_hash($_POST['password'], PASSWORD_DEFAULT) 36 | ); 37 | header('Location: index.php'); 38 | die(); 39 | } else { 40 | $info = LANG['passwords_do_not_match']; 41 | $infoclass = 'yellow'; 42 | } 43 | } 44 | ?> 45 | 46 | 47 | 48 | 49 | <?php echo LANG['app_name']; ?> 50 | 51 | 52 | 53 |
54 |
style="background-image:url('img/cdtitle.jpg')"> 56 |
57 | 58 |
59 | 60 |
61 | 62 | 63 |
64 | 65 |
66 | 67 |
68 |
69 | 70 | 71 | 72 | 73 |
74 | 75 |
76 | 77 |
78 | 79 |
80 | 81 |
82 |
83 |
84 | 85 |
86 | 87 | 88 | -------------------------------------------------------------------------------- /lib/phplot/contrib/color_range.test2.php: -------------------------------------------------------------------------------- 1 | superadmin == 0) { 8 | die('
'.LANG['page_superadmin_right_needed'].'
'); 9 | } 10 | 11 | $services = []; 12 | $preselectRoster = -1; 13 | foreach(explode(',',$_GET['services']) as $service_id) { 14 | $service = $db->getService($service_id); 15 | if($service != null) { 16 | $services[] = $service; 17 | $preselectRoster = $service->roster_id; 18 | } 19 | } 20 | if(count($services) == 0) 21 | die('
'.LANG['no_services_selected'].'
'); 22 | 23 | if(!empty($_POST['roster'])) { 24 | $success = null; 25 | 26 | $db->beginTransaction(); 27 | foreach($services as $s) { 28 | if($success == null || $success == true) 29 | $success = $db->createService( 30 | $_POST['roster'], $s->shortname.$_POST['suffix'], $s->title.$_POST['suffix'], $s->location, $s->employees, $s->start, $s->end, 31 | $_POST['date_start'], $_POST['date_end'], $s->color, $s->wd1, $s->wd2, $s->wd3, $s->wd4, $s->wd5, $s->wd6, $s->wd7 32 | ); 33 | } 34 | 35 | if($success) { 36 | $db->commitTransaction(); 37 | header('Location: index.php?view=rosters'); 38 | die(); 39 | } else { 40 | $db->rollbackTransaction(); 41 | $info = LANG['services_could_not_be_copied'].' '.$db->getLastStatement()->error; 42 | $infoclass = 'red'; 43 | } 44 | } 45 | ?> 46 |
47 |

48 | 49 |
50 | 51 |
52 | 53 | 54 | 55 | 62 | 63 | 64 | 65 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
: 56 | 61 |
: 66 | 67 |
:
:
:
86 |
87 |
88 | -------------------------------------------------------------------------------- /frontend/img/absent-approve.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 49 | 51 | 54 | 55 | 57 | 61 | 62 | 70 | 77 | 80 | 85 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /frontend/img/holiday.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | image/svg+xml 46 | 48 | 53 | 54 | 57 | 60 | 64 | 68 | 72 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /lib/boxes.php: -------------------------------------------------------------------------------- 1 | color)) $extraClass = 'darkbg'; 8 | echo '
location).'" ' 10 | .'style="background-color:'.$service->color.'">'; 11 | echo '
'.htmlspecialchars($service->shortname).'
'; 12 | echo '
'.htmlspecialchars($service->start).'-'.htmlspecialchars($service->end).'
'; 13 | 14 | /// assigned resources /// 15 | $assignmentsResources = $db->getPlannedServiceResourcesByServiceAndDay($service->id, $day); 16 | foreach($assignmentsResources as $r) { 17 | $extraClass = ''; 18 | if(color::isDarkBg($r->resource_color)) $extraClass = 'darkbg'; 19 | echo '
'; 20 | echo ''; 21 | echo ' '.htmlspecialchars($r->resource_title); 22 | echo ''; 23 | echo '
'; 24 | } 25 | 26 | /// service files /// 27 | if($showFiles) { 28 | $files = $db->getPlannedServiceFilesByServiceIdAndDay($service->id, $day); 29 | foreach($files as $file) { 30 | echo ''; 36 | } 37 | } 38 | 39 | /// service note /// 40 | $notes = $db->getPlannedServiceNotes($service->id, $day); 41 | if(isset($notes[0])) 42 | echo '
'.nl2br(htmlspecialchars(tools::shortText($notes[0]->note))).'
'; 43 | 44 | echo '
'; 45 | } 46 | 47 | public static function echoAbsence($absence, $db) { 48 | $aplan = new autoplan($db); 49 | $approved = $aplan->isAbsenceApproved($absence); 50 | 51 | $extraClass = ''; 52 | if(color::isDarkBg($absence->absent_type_color)) $extraClass .= ' darkbg'; 53 | if(!$approved) $extraClass .= ' pending'; 54 | 55 | echo '
'; 58 | echo '
'.htmlspecialchars($absence->absent_type_shortname).'
'; 59 | if(!$approved) echo '
'.'Freigabe ausstehend'.'
'; 60 | echo '
'.htmlspecialchars(tools::shortText($absence->comment)).'
'; 61 | echo '
'; 62 | } 63 | 64 | public static function echoUser($user) { 65 | $extraClass = ''; if(color::isDarkBg($user->color)) $extraClass = 'darkbg'; 66 | echo '
' 68 | .htmlspecialchars(trim($user->fullname)!='' ? $user->fullname : $user->login) 69 | .'
'; 70 | } 71 | 72 | } 73 | --------------------------------------------------------------------------------