├── .gitignore ├── .travis.yml ├── Procfile ├── README.md ├── app ├── .htaccess ├── AppCache.php ├── AppKernel.php ├── DoctrineMigrations │ ├── .gitkeep │ ├── Version20130120002754.php │ ├── Version20130120012237.php │ ├── Version20130330222007.php │ ├── Version20130505173644.php │ ├── Version20130508143748.php │ ├── Version20130524152738.php │ ├── Version20130616122810.php │ ├── Version20130616165301.php │ └── Version20140327215219.php ├── Resources │ ├── TwigBundle │ │ └── views │ │ │ └── Exception │ │ │ └── error.html.twig │ └── views │ │ └── links.html.twig ├── SymfonyRequirements.php ├── autoload.php ├── cache │ └── .gitkeep ├── check.php ├── config │ ├── config.yml │ ├── config_dev.yml │ ├── config_prod.yml │ ├── config_test.yml │ ├── heroku_cleardb.php │ ├── parameters.yml.dist │ ├── routing.yml │ ├── routing_dev.yml │ └── security.yml ├── console ├── logs │ └── .gitkeep └── phpunit.xml.dist ├── composer.json ├── composer.lock ├── src ├── .htaccess └── OpenSkedge │ └── AppBundle │ ├── Command │ ├── ClockCheckLateCommand.php │ ├── ClockOutCommand.php │ ├── ClockPruneCommand.php │ ├── TestRunnerCommand.php │ └── WorkerRunCommand.php │ ├── Controller │ ├── AreaController.php │ ├── AvailabilityScheduleController.php │ ├── ClockController.php │ ├── DashboardController.php │ ├── DefaultController.php │ ├── HoursReportController.php │ ├── IPController.php │ ├── LateShiftController.php │ ├── PositionController.php │ ├── ReportController.php │ ├── ScheduleController.php │ ├── SchedulePeriodController.php │ ├── SecurityController.php │ ├── SettingsController.php │ ├── ShiftController.php │ ├── StatsController.php │ └── UserController.php │ ├── DataFixtures │ └── ORM │ │ ├── LoadClockData.php │ │ ├── LoadGroupData.php │ │ ├── LoadIPData.php │ │ ├── LoadSettingsData.php │ │ └── LoadUserData.php │ ├── DependencyInjection │ ├── Configuration.php │ └── OpenSkedgeExtension.php │ ├── Entity │ ├── ArchivedClock.php │ ├── ArchivedClockRepository.php │ ├── Area.php │ ├── AvailabilitySchedule.php │ ├── BaseEntity │ │ ├── RecordBaseEntity.php │ │ └── ShiftBaseEntity.php │ ├── Clock.php │ ├── Group.php │ ├── IP.php │ ├── LateShift.php │ ├── LateShiftRepository.php │ ├── Position.php │ ├── Schedule.php │ ├── SchedulePeriod.php │ ├── SchedulePeriodRepository.php │ ├── ScheduleRepository.php │ ├── Settings.php │ ├── Shift.php │ ├── ShiftRepository.php │ ├── User.php │ └── UserRepository.php │ ├── Form │ ├── AreaType.php │ ├── AvailabilityScheduleType.php │ ├── EventSubscriber │ │ └── PatchSubscriber.php │ ├── IPType.php │ ├── LateShiftType.php │ ├── PositionType.php │ ├── SchedulePeriodType.php │ ├── SettingsType.php │ ├── ShiftType.php │ └── UserType.php │ ├── Mailer │ ├── MailerInterface.php │ ├── NoopMailer.php │ └── TwigMailer.php │ ├── OpenSkedgeBundle.php │ ├── Resources │ ├── config │ │ ├── routing.yml │ │ └── services.yml │ ├── meta │ │ ├── GPLv3.txt │ │ └── LICENSE │ └── views │ │ ├── Area │ │ ├── edit.html.twig │ │ ├── index.html.twig │ │ ├── new.html.twig │ │ └── view.html.twig │ │ ├── AvailabilitySchedule │ │ ├── edit.html.twig │ │ ├── index.html.twig │ │ ├── new.html.twig │ │ ├── precreate.html.twig │ │ └── view.html.twig │ │ ├── Dashboard │ │ ├── clockmodule.html.twig │ │ ├── index.html.twig │ │ ├── schedulemodule.html.twig │ │ └── shifts.html.twig │ │ ├── HoursReport │ │ ├── generate.html.twig │ │ ├── index.html.twig │ │ └── view.html.twig │ │ ├── IP │ │ ├── edit.html.twig │ │ ├── index.html.twig │ │ └── new.html.twig │ │ ├── LateShift │ │ ├── index.html.twig │ │ └── latemissed.html.twig │ │ ├── Mailer │ │ ├── availschedulechange.txt.twig │ │ ├── availschedulepost.txt.twig │ │ ├── lateemployee_emp.txt.twig │ │ ├── lateemployee_sup.txt.twig │ │ ├── newsupervisor.txt.twig │ │ ├── newuser.txt.twig │ │ ├── schedulechange.txt.twig │ │ ├── shiftdenied.txt.twig │ │ ├── shiftdenied_pickedup.txt.twig │ │ ├── shiftpickedup.txt.twig │ │ ├── shiftposted_mass.txt.twig │ │ └── shiftposted_sup.txt.twig │ │ ├── ModularBlocks │ │ ├── timeresolution.html.twig │ │ └── userschedule.html.twig │ │ ├── Position │ │ ├── edit.html.twig │ │ ├── index.html.twig │ │ ├── new.html.twig │ │ ├── select.html.twig │ │ └── view.html.twig │ │ ├── Report │ │ └── index.html.twig │ │ ├── Schedule │ │ ├── edit.html.twig │ │ └── view.html.twig │ │ ├── SchedulePeriod │ │ ├── edit.html.twig │ │ ├── index.html.twig │ │ ├── new.html.twig │ │ └── view.html.twig │ │ ├── Security │ │ └── login.html.twig │ │ ├── Settings │ │ └── edit.html.twig │ │ ├── Shift │ │ ├── edit.html.twig │ │ ├── index.html.twig │ │ ├── past.html.twig │ │ ├── posted.html.twig │ │ └── view.html.twig │ │ ├── Stats │ │ └── stats.html.twig │ │ ├── User │ │ ├── edit.html.twig │ │ ├── index.html.twig │ │ ├── new.html.twig │ │ ├── new_form_fields.html.twig │ │ └── view.html.twig │ │ ├── base.html.twig │ │ └── error.html.twig │ ├── Services │ ├── AppSettingsService.php │ ├── ClockService.php │ ├── DateTimeUtils.php │ └── StatsService.php │ ├── Tests │ ├── Entity │ │ ├── ArchivedClockTest.php │ │ ├── AreaTest.php │ │ ├── AvailabilityScheduleTest.php │ │ ├── ClockTest.php │ │ ├── GroupTest.php │ │ ├── IPTest.php │ │ ├── LateShiftTest.php │ │ ├── PositionTest.php │ │ ├── SchedulePeriodTest.php │ │ ├── ScheduleTest.php │ │ ├── SettingsTest.php │ │ ├── ShiftTest.php │ │ └── UserTest.php │ ├── Services │ │ └── DateTimeUtilsTest.php │ └── Twig │ │ └── Extension │ │ └── SettingsExtensionTest.php │ └── Twig │ └── Extension │ ├── PageExtension.php │ └── SettingsExtension.php └── web ├── .htaccess ├── app.php ├── app_dev.php ├── css ├── application.css ├── bootstrap-responsive.min.css ├── bootstrap-todc.min.css ├── bootstrap.min.css ├── colorpicker.min.css ├── datepicker.min.css ├── login.css ├── select2-todc.min.css └── timepicker.min.css ├── favicon.ico ├── favicon.png ├── img ├── alpha.png ├── bg.png ├── branding_logo_large.png ├── branding_logo_small.png ├── checkmark.png ├── glyphicons-halflings-white.png ├── glyphicons-halflings.png ├── hue.png ├── navbar_bg.png ├── openskedge_logo_blue.png ├── saturation.png ├── select2-spinner.gif ├── select2.png ├── select2x2.png └── well_bg.png ├── js ├── Chart.min.js ├── application.js ├── bootstrap.colorpicker.min.js ├── bootstrap.datepicker.min.js ├── bootstrap.min.js ├── bootstrap.timepicker.min.js ├── jquery.tablesorter.min.js ├── jquery.tablesorter.widgets.min.js ├── jquery.tickingclock.js ├── scheduleEdit.js └── select2.min.js └── robots.txt /.gitignore: -------------------------------------------------------------------------------- 1 | web/bundles/ 2 | app/bootstrap* 3 | app/cache/* 4 | app/logs/* 5 | build/ 6 | vendor 7 | composer.phar 8 | app/config/parameters.yml 9 | .idea 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.5 5 | - 5.6 6 | - 7.0 7 | - hhvm 8 | 9 | matrix: 10 | allow_failures: 11 | - php: 7.0 12 | - php: hhvm 13 | 14 | before_script: composer install --no-interaction --prefer-source 15 | 16 | script: phpunit -c app 17 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: vendor/bin/heroku-php-apache2 web/ 2 | -------------------------------------------------------------------------------- /app/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all -------------------------------------------------------------------------------- /app/AppCache.php: -------------------------------------------------------------------------------- 1 | getEnvironment(), array('dev', 'test'))) { 29 | $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); 30 | $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle(); 31 | $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle(); 32 | } 33 | 34 | return $bundles; 35 | } 36 | 37 | public function registerContainerConfiguration(LoaderInterface $loader) 38 | { 39 | $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml'); 40 | } 41 | 42 | public function getName() 43 | { 44 | return 'OpenSkedge'; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/DoctrineMigrations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/app/DoctrineMigrations/.gitkeep -------------------------------------------------------------------------------- /app/DoctrineMigrations/Version20130120002754.php: -------------------------------------------------------------------------------- 1 | abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 16 | 17 | $this->skipIf($this->sm->tablesExist(array('os_archived_clock')), "os_archived_clock table already exists."); 18 | 19 | $this->addSql("CREATE TABLE os_archived_clock (id INT AUTO_INCREMENT NOT NULL, uid INT DEFAULT NULL, week DATETIME NOT NULL, sun VARCHAR(96) NOT NULL, mon VARCHAR(96) NOT NULL, tue VARCHAR(96) NOT NULL, wed VARCHAR(96) NOT NULL, thu VARCHAR(96) NOT NULL, fri VARCHAR(96) NOT NULL, sat VARCHAR(96) NOT NULL, INDEX IDX_E2AE7B56539B0606 (uid), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); 20 | $this->addSql("ALTER TABLE os_archived_clock ADD CONSTRAINT FK_E2AE7B56539B0606 FOREIGN KEY (uid) REFERENCES os_user (id)"); 21 | $this->addSql("ALTER TABLE os_clock CHANGE last_clock unix_last_clock int(11) NOT NULL"); 22 | $this->addSql("ALTER TABLE os_clock ADD last_clock DATETIME NOT NULL"); 23 | $this->addSql("UPDATE os_clock SET last_clock=FROM_UNIXTIME(unix_last_clock)"); 24 | $this->addSql("ALTER TABLE os_clock DROP unix_last_clock"); 25 | } 26 | 27 | public function down(Schema $schema) 28 | { 29 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 30 | 31 | $this->addSql("DROP TABLE os_archived_clock"); 32 | $this->addSql("ALTER TABLE os_clock CHANGE last_clock datetime_last_clock DATETIME NOT NULL"); 33 | $this->addSql("ALTER TABLE os_clock ADD last_clock int(11) NOT NULL"); 34 | $this->addSql("UPDATE os_clock SET last_clock=UNIX_TIMESTAMP(last_clock)"); 35 | $this->addSql("ALTER TABLE os_clock DROP datetime_last_clock"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/DoctrineMigrations/Version20130120012237.php: -------------------------------------------------------------------------------- 1 | abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 17 | 18 | $indices = $this->sm->listTableIndexes('os_archived_clock'); 19 | foreach($indices as $index) { 20 | if($index->getName()=='week') { 21 | $skip = true; 22 | } 23 | } 24 | $this->skipIf($skip, "Index already exists on os_archived_clock."); 25 | $this->addSql("CREATE INDEX week ON os_archived_clock (week)"); 26 | } 27 | 28 | public function down(Schema $schema) 29 | { 30 | // this down() migration is auto-generated, please modify it to your needs 31 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 32 | 33 | $this->addSql("DROP INDEX week ON os_archived_clock"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/DoctrineMigrations/Version20130330222007.php: -------------------------------------------------------------------------------- 1 | abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 14 | 15 | $this->skipIf($this->sm->tablesExist(array('os_audit_ips')), "os_audit_ips table already exists."); 16 | $this->skipIf($this->sm->tablesExist(array('os_settings')), "os_settings table already exists."); 17 | 18 | $this->addSql("CREATE TABLE os_audit_ips (id INT AUTO_INCREMENT NOT NULL, ip VARCHAR(255) NOT NULL, name VARCHAR(64) DEFAULT NULL, allowed_to_clock TINYINT(1) NOT NULL, UNIQUE INDEX UNIQ_CF6F1072A5E3B32D (ip), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); 19 | $this->addSql("CREATE TABLE os_settings (id INT AUTO_INCREMENT NOT NULL, brandName VARCHAR(64) NOT NULL, pruneAfter INT NOT NULL, weekStartDay VARCHAR(9) NOT NULL, weekStartDayClock VARCHAR(9) NOT NULL, defaultTimeResolution VARCHAR(255) NOT NULL, startHour VARCHAR(255) NOT NULL, endHour VARCHAR(255) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); 20 | $this->addSql("INSERT INTO os_settings (id, brandName, pruneAfter, weekStartDay, weekStartDayClock, defaultTimeResolution, startHour, endHour) VALUES (1, 'OpenSkedge', 12, 'sunday', 'sunday', '1 hour', '07:00:00', '23:00:00');"); 21 | $this->addSql("INSERT INTO os_audit_ips (ip, name, allowed_to_clock) VALUES ('127.0.0.1', 'Server', true);"); 22 | $this->addSql("INSERT INTO os_audit_ips (ip, name, allowed_to_clock) VALUES ('::1', 'Server', true);"); 23 | $this->addSql("INSERT INTO os_audit_ips (ip, name, allowed_to_clock) VALUES ('fe80::1', 'Server', true);"); 24 | } 25 | 26 | public function down(Schema $schema) 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 30 | 31 | $this->addSql("DROP TABLE os_audit_ips"); 32 | $this->addSql("DROP TABLE os_settings"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/DoctrineMigrations/Version20130505173644.php: -------------------------------------------------------------------------------- 1 | abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 17 | 18 | $this->skipIf($this->sm->tablesExist(array('os_audit_late')), "os_audit_late table already exists."); 19 | 20 | $this->addSql("CREATE TABLE os_audit_late (id INT AUTO_INCREMENT NOT NULL, uid INT DEFAULT NULL, sid INT DEFAULT NULL, spid INT DEFAULT NULL, pid INT DEFAULT NULL, status VARCHAR(255) NOT NULL, arrivalTime DATETIME DEFAULT NULL, creationTime DATETIME NOT NULL, notes VARCHAR(255) DEFAULT NULL, INDEX IDX_3465AAE8539B0606 (uid), INDEX IDX_3465AAE857167AB4 (sid), INDEX IDX_3465AAE8F2DFCD91 (spid), INDEX IDX_3465AAE85550C4ED (pid), INDEX lateShiftCreated (creationTime), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); 21 | $this->addSql("ALTER TABLE os_audit_late ADD CONSTRAINT FK_3465AAE8539B0606 FOREIGN KEY (uid) REFERENCES os_user (id)"); 22 | $this->addSql("ALTER TABLE os_audit_late ADD CONSTRAINT FK_3465AAE857167AB4 FOREIGN KEY (sid) REFERENCES os_schedule (id)"); 23 | $this->addSql("ALTER TABLE os_audit_late ADD CONSTRAINT FK_3465AAE8F2DFCD91 FOREIGN KEY (spid) REFERENCES os_schedule_period (id)"); 24 | $this->addSql("ALTER TABLE os_audit_late ADD CONSTRAINT FK_3465AAE85550C4ED FOREIGN KEY (pid) REFERENCES os_position (id)"); 25 | } 26 | 27 | public function down(Schema $schema) 28 | { 29 | // this down() migration is auto-generated, please modify it to your needs 30 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 31 | 32 | $this->addSql("DROP TABLE os_audit_late"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/DoctrineMigrations/Version20130508143748.php: -------------------------------------------------------------------------------- 1 | abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 17 | 18 | $this->skipIf($this->sm->tablesExist(array('os_shift')), "os_shift table already exists."); 19 | 20 | $this->addSql("CREATE TABLE os_shift (id INT AUTO_INCREMENT NOT NULL, uid INT DEFAULT NULL, puid INT DEFAULT NULL, sid INT DEFAULT NULL, spid INT DEFAULT NULL, pid INT DEFAULT NULL, status VARCHAR(255) NOT NULL, creationTime DATETIME NOT NULL, startTime DATETIME NOT NULL, endTime DATETIME NOT NULL, notes VARCHAR(255) DEFAULT NULL, INDEX IDX_2F98D1B2539B0606 (uid), INDEX IDX_2F98D1B2E6A1A094 (puid), INDEX IDX_2F98D1B257167AB4 (sid), INDEX IDX_2F98D1B2F2DFCD91 (spid), INDEX IDX_2F98D1B25550C4ED (pid), INDEX users (uid, puid), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB"); 21 | $this->addSql("ALTER TABLE os_shift ADD CONSTRAINT FK_2F98D1B2539B0606 FOREIGN KEY (uid) REFERENCES os_user (id)"); 22 | $this->addSql("ALTER TABLE os_shift ADD CONSTRAINT FK_2F98D1B2E6A1A094 FOREIGN KEY (puid) REFERENCES os_user (id)"); 23 | $this->addSql("ALTER TABLE os_shift ADD CONSTRAINT FK_2F98D1B257167AB4 FOREIGN KEY (sid) REFERENCES os_schedule (id)"); 24 | $this->addSql("ALTER TABLE os_shift ADD CONSTRAINT FK_2F98D1B2F2DFCD91 FOREIGN KEY (spid) REFERENCES os_schedule_period (id)"); 25 | $this->addSql("ALTER TABLE os_shift ADD CONSTRAINT FK_2F98D1B25550C4ED FOREIGN KEY (pid) REFERENCES os_position (id)"); 26 | } 27 | 28 | public function down(Schema $schema) 29 | { 30 | // this down() migration is auto-generated, please modify it to your needs 31 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 32 | 33 | $this->addSql("DROP TABLE os_shift"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/DoctrineMigrations/Version20130524152738.php: -------------------------------------------------------------------------------- 1 | abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 17 | 18 | $this->addSql("ALTER TABLE os_settings CHANGE id id INT NOT NULL"); 19 | } 20 | 21 | public function down(Schema $schema) 22 | { 23 | // this down() migration is auto-generated, please modify it to your needs 24 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 25 | 26 | $this->addSql("ALTER TABLE os_settings CHANGE id id INT AUTO_INCREMENT NOT NULL"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/DoctrineMigrations/Version20130616122810.php: -------------------------------------------------------------------------------- 1 | abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 17 | 18 | $tables = $schema->getTables(); 19 | foreach ($tables as $table) { 20 | if ($table->getName() === "os_user") { 21 | if ($table->hasForeignKey('FK_7BB0CD52BF396750')) { 22 | $this->addSql("ALTER TABLE os_user DROP FOREIGN KEY FK_7BB0CD52BF396750"); 23 | } 24 | } else if ($table->getName() === "os_clock") { 25 | if (!$table->hasColumn("uid")) { 26 | $this->addSql("ALTER TABLE os_clock ADD uid INT DEFAULT NULL"); 27 | $this->addSql("UPDATE os_clock SET uid = id"); 28 | } 29 | 30 | if (!$table->hasForeignKey('FK_34E85465539B0606')) { 31 | $this->addSql("ALTER TABLE os_clock ADD CONSTRAINT FK_34E85465539B0606 FOREIGN KEY (uid) REFERENCES os_user (id)"); 32 | } 33 | 34 | if (!$table->hasIndex('UNIQ_34E85465539B0606')) { 35 | $this->addSql("CREATE UNIQUE INDEX UNIQ_34E85465539B0606 ON os_clock (uid)"); 36 | } 37 | } 38 | } 39 | } 40 | 41 | public function down(Schema $schema) 42 | { 43 | // this down() migration is auto-generated, please modify it to your needs 44 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 45 | 46 | $this->addSql("ALTER TABLE os_clock DROP FOREIGN KEY FK_34E85465539B0606"); 47 | $this->addSql("DROP INDEX UNIQ_34E85465539B0606 ON os_clock"); 48 | $this->addSql("ALTER TABLE os_clock DROP uid"); 49 | $this->addSql("ALTER TABLE os_user ADD CONSTRAINT FK_7BB0CD52BF396750 FOREIGN KEY (id) REFERENCES os_clock (id)"); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/DoctrineMigrations/Version20130616165301.php: -------------------------------------------------------------------------------- 1 | abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 17 | 18 | if ($schema->hasTable('os_settings')) { 19 | $table = $schema->getTable('os_settings'); 20 | if (!$table->hasColumn('massEmail')) { 21 | $this->addSql("ALTER TABLE os_settings ADD massEmail VARCHAR(255) DEFAULT NULL"); 22 | } 23 | } 24 | } 25 | 26 | public function down(Schema $schema) 27 | { 28 | // this down() migration is auto-generated, please modify it to your needs 29 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 30 | 31 | if ($schema->hasTable('os_settings')) { 32 | $table = $schema->getTable('os_settings'); 33 | if (!$table->hasColumn('massEmail')) { 34 | $this->addSql("ALTER TABLE os_settings DROP massEmail"); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/DoctrineMigrations/Version20140327215219.php: -------------------------------------------------------------------------------- 1 | abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 17 | 18 | $this->addSql("ALTER TABLE os_position CHANGE description description VARCHAR(300) DEFAULT NULL"); 19 | } 20 | 21 | public function down(Schema $schema) 22 | { 23 | // this down() migration is auto-generated, please modify it to your needs 24 | $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'."); 25 | 26 | $this->addSql("ALTER TABLE os_position CHANGE description description VARCHAR(300) NOT NULL"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/Resources/TwigBundle/views/Exception/error.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{ appname }} - Error - {{ status_code }} 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

Oops! An Error Occurred

17 |

The server returned a "{{ status_code }} {{ status_text }}".

18 |
19 | {% if not app.request.headers.get('referer') is null %} 20 |

Return from whence you came

21 | {% endif %} 22 |
23 | 30 | 31 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/Resources/views/links.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | In this file, you can include additional menu items to be listed in FlexSkedge. 3 | e.g. as followed: 4 | 5 | 6 |
  • MyOrg Email
  • 7 |
  • MyOrg Website
  • 8 | ..etc.. 9 | #} 10 | -------------------------------------------------------------------------------- /app/autoload.php: -------------------------------------------------------------------------------- 1 | setParameter('database_driver', 'pdo_mysql'); 5 | $container->setParameter('database_host', $db['host']); 6 | $container->setParameter('database_port', $db['port']); 7 | $container->setParameter('database_name', substr($db["path"], 1)); 8 | $container->setParameter('database_user', $db['user']); 9 | $container->setParameter('database_password', $db['pass']); 10 | } 11 | -------------------------------------------------------------------------------- /app/config/parameters.yml.dist: -------------------------------------------------------------------------------- 1 | parameters: 2 | # Database Configuration 3 | database_driver: pdo_mysql 4 | database_url: "%database.url%" 5 | database_host: 127.0.0.1 6 | database_port: 3306 7 | database_name: openskedge 8 | database_user: root 9 | database_password: ~ 10 | 11 | # Mailer Configuration 12 | sender_email: no-reply@mydomain.com 13 | mailer_transport: mail 14 | mailer_encryption: ~ 15 | mailer_auth: ~ 16 | mailer_port: ~ 17 | mailer_host: ~ 18 | mailer_user: ~ 19 | mailer_password: ~ 20 | 21 | # Locale Configuration 22 | locale: en 23 | 24 | # Security Configuration 25 | secret: YOU_NEED_SOME_GOBBLEDIEGOOK_HERE 26 | protocol: http # http or https (recommended) 27 | 28 | # Session Configuration 29 | session_handler: ~ 30 | # If you want to use memcache for session storage 31 | # session_handler: session.handler.memcache 32 | session_memcache_host: 127.0.0.1 33 | session_memcache_port: 11211 34 | session_memcache_prefix: openskedge 35 | session_memcache_expire: 3600 36 | -------------------------------------------------------------------------------- /app/config/routing.yml: -------------------------------------------------------------------------------- 1 | openskedge: 2 | resource: "@OpenSkedgeBundle/Resources/config/routing.yml" 3 | prefix: / 4 | 5 | # Internal routing configuration to handle ESI 6 | # ****** WARNING ****** 7 | # This route should be enabled with caution as it can open a security vulnerability 8 | # see http://symfony.com/blog/security-release-symfony-2-0-20-and-2-1-5-released for more information 9 | # ****** WARNING ****** 10 | #_internal: 11 | # resource: "@FrameworkBundle/Resources/config/routing/internal.xml" 12 | # prefix: /_internal 13 | -------------------------------------------------------------------------------- /app/config/routing_dev.yml: -------------------------------------------------------------------------------- 1 | _main: 2 | resource: routing.yml 3 | 4 | _wdt: 5 | resource: "@WebProfilerBundle/Resources/config/routing/wdt.xml" 6 | prefix: /_wdt 7 | 8 | _profiler: 9 | resource: "@WebProfilerBundle/Resources/config/routing/profiler.xml" 10 | prefix: /_profiler 11 | 12 | _configurator: 13 | resource: "@SensioDistributionBundle/Resources/config/routing/webconfigurator.xml" 14 | prefix: /_configurator 15 | -------------------------------------------------------------------------------- /app/config/security.yml: -------------------------------------------------------------------------------- 1 | jms_security_extra: 2 | secure_all_services: false 3 | expressions: true 4 | 5 | security: 6 | encoders: 7 | OpenSkedge\AppBundle\Entity\User: sha512 8 | Symfony\Component\Security\Core\User\User: plaintext 9 | 10 | role_hierarchy: 11 | ROLE_ADMIN: [ROLE_USER] 12 | ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] 13 | 14 | providers: 15 | main: 16 | entity: { class: OpenSkedge\AppBundle\Entity\User, property: username } 17 | in_memory: 18 | memory: 19 | users: 20 | testemp: 21 | password: testemp 22 | roles: [ 'ROLE_USER' ] 23 | testsup: 24 | password: testsup 25 | roles: [ 'ROLE_ADMIN' ] 26 | testadmin: 27 | password: testadmin 28 | roles: [ 'ROLE_SUPER_ADMIN'] 29 | 30 | firewalls: 31 | main: 32 | pattern: /.* 33 | provider: main 34 | form_login: 35 | # the user is redirected here when he/she needs to login 36 | login_path: /login/ 37 | 38 | # if true, forward the user to the login form instead of redirecting 39 | use_forward: false 40 | 41 | # submit the login form here 42 | check_path: /login_check 43 | 44 | # by default, the login form *must* be a POST, not a GET 45 | post_only: true 46 | 47 | # login success redirecting options (read further below) 48 | always_use_default_target_path: false 49 | default_target_path: /dashboard/ 50 | target_path_parameter: _target_path 51 | use_referer: true 52 | 53 | # login failure redirecting options (read further below) 54 | failure_path: null 55 | failure_forward: false 56 | 57 | # field names for the username and password fields 58 | username_parameter: _username 59 | password_parameter: _password 60 | 61 | # csrf token options 62 | csrf_parameter: _csrf_token 63 | intention: authenticate 64 | logout: 65 | path: /logout 66 | target: / 67 | http_basic: 68 | realm: "OpenSkedge Authentication Required" 69 | security: true 70 | anonymous: true 71 | 72 | dev: 73 | pattern: ^/(_(profiler|wdt)|css|images|js)/ 74 | security: false 75 | 76 | access_control: 77 | _wdt: 78 | path: ^/_wdt 79 | roles: 'IS_AUTHENTICATED_ANONYMOUSLY' 80 | login: 81 | path: ^/login 82 | roles: IS_AUTHENTICATED_ANONYMOUSLY 83 | requires_channel: %protocol% 84 | main: 85 | path: ^/ 86 | roles: [ ROLE_USER, IS_AUTHENTICATED_FULLY ] 87 | requires_channel: %protocol% 88 | -------------------------------------------------------------------------------- /app/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev'); 19 | $debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(array('--no-debug', '')) && $env !== 'prod'; 20 | 21 | if ($debug) { 22 | Debug::enable(); 23 | } 24 | 25 | $kernel = new AppKernel($env, $debug); 26 | $application = new Application($kernel); 27 | $application->run($input); 28 | -------------------------------------------------------------------------------- /app/logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/app/logs/.gitkeep -------------------------------------------------------------------------------- /app/phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 17 | 18 | ../src/*/*Bundle/Tests 19 | ../src/*/Bundle/*Bundle/Tests 20 | 21 | 22 | 23 | 28 | 29 | 30 | 31 | ../src 32 | 33 | ../src/*/*Bundle/Resources 34 | ../src/*/*Bundle/Tests 35 | ../src/*/Bundle/*Bundle/Resources 36 | ../src/*/Bundle/*Bundle/Tests 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "openskedge/openskedge", 3 | "description": "A flexible employee scheduling application built upon Symfony2. Designed for companies and organizations with fluid shifts.", 4 | "license": "GPL-3.0+", 5 | "type": "project", 6 | "keywords": ["flexible", "employee", "scheduling"], 7 | "homepage": "http://www.openskedge.org", 8 | "authors": [ 9 | { 10 | "name": "Max Fierke", 11 | "email": "max@maxfierke.com", 12 | "homepage": "http://www.maxfierke.com", 13 | "role": "Developer" 14 | } 15 | ], 16 | "autoload": { 17 | "psr-0": { "": "src/" } 18 | }, 19 | "require": { 20 | "php": ">=5.3.10,!=5.3.16", 21 | "symfony/symfony": "2.7.*", 22 | "doctrine/data-fixtures": "1.0.*@dev", 23 | "doctrine/doctrine-fixtures-bundle": "dev-master", 24 | "doctrine/migrations": "dev-master", 25 | "doctrine/doctrine-migrations-bundle": "dev-master", 26 | "doctrine/orm": ">=2.2.3,<2.5-dev", 27 | "doctrine/doctrine-bundle": "1.2.*", 28 | "twig/extensions": "1.0.*@dev", 29 | "symfony/assetic-bundle": "2.7.*", 30 | "symfony/swiftmailer-bundle": "2.3.*", 31 | "symfony/monolog-bundle": "2.7.*", 32 | "sensio/distribution-bundle": "~4.0", 33 | "sensio/framework-extra-bundle": "~3.0", 34 | "sensio/generator-bundle": "2.5.*", 35 | "jms/security-extra-bundle": "1.5.*", 36 | "jms/di-extra-bundle": "1.4.*", 37 | "kriswallsmith/assetic": "~1.3", 38 | "pagerfanta/pagerfanta": "1.0.*", 39 | "white-october/pagerfanta-bundle": "dev-master", 40 | "symfony/proxy-manager-bridge": "2.7.*", 41 | "symfony/icu": "1.1.*", 42 | "incenteev/composer-parameter-handler": "~2.0" 43 | }, 44 | "require-dev": { 45 | "phpunit/php-code-coverage": "1.2.*@dev", 46 | "phpunit/phpunit": "3.7.*", 47 | "heroku/heroku-buildpack-php": "*" 48 | }, 49 | "suggest": { 50 | "ext-memcache": "Store user sessions in memcache instead of to disk." 51 | }, 52 | "scripts": { 53 | "post-install-cmd": [ 54 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", 55 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", 56 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" 57 | ], 58 | "post-update-cmd": [ 59 | "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters", 60 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap", 61 | "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile" 62 | ] 63 | }, 64 | "prefer-stable": true, 65 | "minimum-stability": "dev", 66 | "extra": { 67 | "symfony-app-dir": "app", 68 | "symfony-web-dir": "web", 69 | "branch-alias": { 70 | "dev-master": "2.7-dev" 71 | }, 72 | "incenteev-parameters": { 73 | "file": "app/config/parameters.yml" 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Command/TestRunnerCommand.php: -------------------------------------------------------------------------------- 1 | 15 | * @author Max Fierke 16 | * @license GNU General Public License, version 3 17 | * @version GIT: $Id$ 18 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 19 | */ 20 | class TestRunnerCommand extends ContainerAwareCommand 21 | { 22 | /** 23 | * {@inheritDoc} 24 | */ 25 | protected function configure() 26 | { 27 | $this->setName('tests:run') 28 | ->setDescription('Runs all available tests'); 29 | } 30 | 31 | /** 32 | * {@inheritDoc} 33 | */ 34 | protected function execute(InputInterface $input, OutputInterface $output) 35 | { 36 | // check for composer installed 37 | $executable = null; 38 | 39 | if (is_file(dirname(dirname(dirname(dirname(__DIR__)))) . '/vendor/bin/phpunit')) { 40 | $executable = realpath(dirname(dirname(dirname(dirname(__DIR__)))) . '/vendor/bin/phpunit'); 41 | } elseif (is_file(dirname(dirname(dirname(dirname(__DIR__)))) . '/vendor/phpunit/phpunit/phpunit.php')) { 42 | // perhaps no shortcut was made? 43 | $executable = 'php ' . realpath(dirname(dirname(dirname(dirname(__DIR__)))) . '/vendor/phpunit/phpunit/phpunit.php'); 44 | } else { 45 | // check if phpunit is in the path 46 | $returnVal = shell_exec("which phpunit"); 47 | if (!empty($returnVal)) { 48 | $executable = 'phpunit'; 49 | } 50 | } 51 | 52 | if (is_null($executable)) { 53 | $output->writeln("No PHPUnit test runner found in the vendor dir or your path"); 54 | } else { 55 | system($executable . ' -c app/'); 56 | } 57 | 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Controller/ClockController.php: -------------------------------------------------------------------------------- 1 | 18 | * @license GNU General Public License, version 3 19 | * @version GIT: $Id$ 20 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 21 | */ 22 | class ClockController extends Controller 23 | { 24 | /** 25 | * Mark the user as clocked in & update the clock in timestamp. 26 | * If it's a new week from their last clock in, backup their time clock 27 | * to an ArchivedClock entity. 28 | * 29 | * @param Request $request The user's request object 30 | * 31 | * @return \Symfony\Component\HttpFoundation\Response 32 | */ 33 | public function clockInAction(Request $request) 34 | { 35 | // Ensure the accessing user is authenticated and authorized ROLE_USER 36 | if (false === $this->get('security.context')->isGranted('ROLE_USER')) { 37 | throw new AccessDeniedException(); 38 | } 39 | 40 | // Grab a few services. 41 | $appSettingsService = $this->get('app_settings'); 42 | 43 | /* If running on Pagoda Box, get the user's IP directly from HTTP_X_FORWARDED_FOR, 44 | * otherwise, go to Request::getClientIp() 45 | */ 46 | $clientIp = (isset($_ENV['PAGODABOX']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $request->getClientIp()); 47 | if (!in_array($clientIp, $appSettingsService->getAllowedClockIps())) { 48 | throw new AccessDeniedException(); 49 | } 50 | 51 | $this->get('clock_utils')->clockIn($this->getUser()); 52 | 53 | return $this->redirect($this->generateUrl('dashboard')); 54 | } 55 | 56 | /** 57 | * Mark the user as clocked out & update the relevant time records. 58 | * 59 | * @param Request $request The user's request object 60 | * 61 | * @return \Symfony\Component\HttpFoundation\Response 62 | */ 63 | public function clockOutAction(Request $request) 64 | { 65 | // Ensure the accessing user is authenticated and authorized ROLE_USER 66 | if (false === $this->get('security.context')->isGranted('ROLE_USER')) { 67 | throw new AccessDeniedException(); 68 | } 69 | 70 | /* If running on Pagoda Box, get the user's IP directly from HTTP_X_FORWARDED_FOR, 71 | * otherwise, go to Request::getClientIp() 72 | */ 73 | $clientIp = (isset($_ENV['PAGODABOX']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $request->getClientIp()); 74 | if (!in_array($clientIp, $this->get('app_settings')->getAllowedClockIps())) { 75 | throw new AccessDeniedException(); 76 | } 77 | 78 | $this->get('clock_utils')->clockOut($this->getUser()); 79 | 80 | return $this->redirect($this->generateUrl('dashboard')); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Controller/DefaultController.php: -------------------------------------------------------------------------------- 1 | 13 | * @license GNU General Public License, version 3 14 | * @version GIT: $Id$ 15 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 16 | */ 17 | class DefaultController extends Controller 18 | { 19 | /** 20 | * Basic redirect of empty route to /dashboard/ 21 | * 22 | * @return \Symfony\Component\HttpFoundation\Response 23 | */ 24 | public function indexAction() 25 | { 26 | return $this->redirect($this->generateUrl('dashboard')); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Controller/ReportController.php: -------------------------------------------------------------------------------- 1 | 16 | * @license GNU General Public License, version 3 17 | * @version GIT: $Id$ 18 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 19 | */ 20 | class ReportController extends Controller 21 | { 22 | /** 23 | * Lists all available report types. 24 | * 25 | * @return \Symfony\Component\HttpFoundation\Response 26 | */ 27 | public function indexAction() 28 | { 29 | if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) { 30 | throw new AccessDeniedException(); 31 | } 32 | 33 | return $this->render('OpenSkedgeBundle:Report:index.html.twig'); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Controller/SecurityController.php: -------------------------------------------------------------------------------- 1 | 14 | * @license GNU General Public License, version 3 15 | * @version GIT: $Id$ 16 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 17 | */ 18 | class SecurityController extends Controller 19 | { 20 | /** 21 | * Process login requests and attempt to authenticate the user. 22 | * 23 | * @return \Symfony\Component\HttpFoundation\Response 24 | */ 25 | public function loginAction() 26 | { 27 | $request = $this->getRequest(); 28 | $session = $request->getSession(); 29 | 30 | // get the login error if there is one 31 | if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) { 32 | $error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR); 33 | } else { 34 | $error = $session->get(SecurityContext::AUTHENTICATION_ERROR); 35 | $session->remove(SecurityContext::AUTHENTICATION_ERROR); 36 | } 37 | 38 | return $this->render('OpenSkedgeBundle:Security:login.html.twig', array( 39 | 'error' => $error, 40 | 'last_username' => $session->get(SecurityContext::LAST_USERNAME), 41 | )); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Controller/SettingsController.php: -------------------------------------------------------------------------------- 1 | 16 | * @license GNU General Public License, version 3 17 | * @version GIT: $Id$ 18 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 19 | */ 20 | class SettingsController extends Controller 21 | { 22 | 23 | /** 24 | * Edit application settings 25 | * 26 | * @param Request $request The user's request object 27 | * @return \Symfony\Component\HttpFoundation\Response 28 | * @throws AccessDeniedException 29 | */ 30 | public function editAction(Request $request) 31 | { 32 | // Only allow access to Administrators 33 | if (false === $this->get('security.context')->isGranted('ROLE_SUPER_ADMIN')) { 34 | throw new AccessDeniedException(); 35 | } 36 | 37 | $em = $this->getDoctrine()->getManager(); 38 | 39 | $entity = $em->getRepository('OpenSkedgeBundle:Settings')->find(1); 40 | 41 | if (!$entity instanceof Settings) { 42 | throw $this->createNotFoundException('Unable to find Settings entity.'); 43 | } 44 | 45 | $editForm = $this->createForm(new SettingsType(), $entity); 46 | 47 | if ($request->getMethod() == 'POST') { 48 | $editForm->bind($request); 49 | if ($editForm->isValid()) { 50 | $em->persist($entity); 51 | $em->flush(); 52 | 53 | $request->getSession()->getFlashBag()->add('success', 'Application settings updated successfully.'); 54 | 55 | return $this->redirect($this->generateUrl('app_settings_edit')); 56 | } 57 | $request->getSession()->getFlashBag()->add('error', 'Application settings could not be updated. Check for form errors below. If the issue persists, please report it to your friendly sysadmin.'); 58 | } 59 | 60 | return $this->render('OpenSkedgeBundle:Settings:edit.html.twig', array( 61 | 'entity' => $entity, 62 | 'edit_form' => $editForm->createView(), 63 | )); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/DataFixtures/ORM/LoadClockData.php: -------------------------------------------------------------------------------- 1 | 16 | * @license GNU General Public License, version 3 17 | * @version GIT: $Id$ 18 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 19 | */ 20 | class LoadClockData extends AbstractFixture implements OrderedFixtureInterface 21 | { 22 | /** 23 | * {@inheritDoc} 24 | */ 25 | public function load(ObjectManager $manager) 26 | { 27 | $adminClock = new Clock(); 28 | $adminClock->setUser($this->getReference('admin-user')); 29 | 30 | $manager->persist($adminClock); 31 | $manager->flush(); 32 | } 33 | 34 | /** 35 | * {@inheritDoc} 36 | */ 37 | public function getOrder() 38 | { 39 | return 3; // the order in which fixtures will be loaded 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/DataFixtures/ORM/LoadGroupData.php: -------------------------------------------------------------------------------- 1 | 16 | * @license GNU General Public License, version 3 17 | * @version GIT: $Id$ 18 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 19 | */ 20 | class LoadGroupData extends AbstractFixture implements OrderedFixtureInterface 21 | { 22 | /** 23 | * {@inheritDoc} 24 | */ 25 | public function load(ObjectManager $manager) 26 | { 27 | $groupEmployee = new Group(); 28 | $groupEmployee->setName('Employee'); 29 | $groupEmployee->setRole('ROLE_USER'); 30 | $manager->persist($groupEmployee); 31 | 32 | $groupSupervisor = new Group(); 33 | $groupSupervisor->setName('Supervisor'); 34 | $groupSupervisor->setRole('ROLE_ADMIN'); 35 | $manager->persist($groupSupervisor); 36 | 37 | $groupAdmin = new Group(); 38 | $groupAdmin->setName('Admin'); 39 | $groupAdmin->setRole('ROLE_SUPER_ADMIN'); 40 | $manager->persist($groupAdmin); 41 | 42 | $manager->flush(); 43 | 44 | $this->addReference('admin-group', $groupAdmin); 45 | } 46 | 47 | /** 48 | * {@inheritDoc} 49 | */ 50 | public function getOrder() 51 | { 52 | return 1; // the order in which fixtures will be loaded 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/DataFixtures/ORM/LoadIPData.php: -------------------------------------------------------------------------------- 1 | 20 | * @license GNU General Public License, version 3 21 | * @version GIT: $Id$ 22 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 23 | */ 24 | class LoadIPData extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface 25 | { 26 | /** 27 | * @var ContainerInterface 28 | */ 29 | private $container; 30 | 31 | /** 32 | * {@inheritDoc} 33 | */ 34 | public function setContainer(ContainerInterface $container = null) 35 | { 36 | $this->container = $container; 37 | } 38 | 39 | /** 40 | * {@inheritDoc} 41 | */ 42 | public function load(ObjectManager $manager) 43 | { 44 | $localhost_ipv4 = new IP(); 45 | $localhost_ipv4->setIP('127.0.0.1') 46 | ->setName('Server') 47 | ->setClockEnabled(true); 48 | $manager->persist($localhost_ipv4); 49 | 50 | $localhost_ipv6_ll1 = new IP(); 51 | $localhost_ipv6_ll1->setIP('::1') 52 | ->setName('Server') 53 | ->setClockEnabled(true); 54 | $manager->persist($localhost_ipv6_ll1); 55 | 56 | $localhost_ipv6_ll2 = new IP(); 57 | $localhost_ipv6_ll2->setIP('fe80::1') 58 | ->setName('Server') 59 | ->setClockEnabled(true); 60 | $manager->persist($localhost_ipv6_ll2); 61 | 62 | $manager->flush(); 63 | } 64 | 65 | /** 66 | * {@inheritDoc} 67 | */ 68 | public function getOrder() 69 | { 70 | return 5; // the order in which fixtures will be loaded 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/DataFixtures/ORM/LoadSettingsData.php: -------------------------------------------------------------------------------- 1 | 19 | * @license GNU General Public License, version 3 20 | * @version GIT: $Id$ 21 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 22 | */ 23 | class LoadSettingsData extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface 24 | { 25 | /** 26 | * @var ContainerInterface 27 | */ 28 | private $container; 29 | 30 | /** 31 | * {@inheritDoc} 32 | */ 33 | public function setContainer(ContainerInterface $container = null) 34 | { 35 | $this->container = $container; 36 | } 37 | 38 | /** 39 | * {@inheritDoc} 40 | */ 41 | public function load(ObjectManager $manager) 42 | { 43 | $appSettings = new Settings(); 44 | $appSettings->setBrandName('OpenSkedge') 45 | ->setPruneAfter(12) 46 | ->setWeekStartDay('sunday') 47 | ->setWeekStartDayClock('sunday') 48 | ->setDefaultTimeResolution('1 hour') 49 | ->setStartHour('06:00:00') 50 | ->setEndHour('20:00:00'); 51 | 52 | $manager->persist($appSettings); 53 | $manager->flush(); 54 | } 55 | 56 | /** 57 | * {@inheritDoc} 58 | */ 59 | public function getOrder() 60 | { 61 | return 4; // the order in which fixtures will be loaded 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/DataFixtures/ORM/LoadUserData.php: -------------------------------------------------------------------------------- 1 | 18 | * @license GNU General Public License, version 3 19 | * @version GIT: $Id$ 20 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 21 | */ 22 | class LoadUserData extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface 23 | { 24 | /** 25 | * @var ContainerInterface 26 | */ 27 | private $container; 28 | 29 | /** 30 | * {@inheritDoc} 31 | */ 32 | public function setContainer(ContainerInterface $container = null) 33 | { 34 | $this->container = $container; 35 | } 36 | 37 | /** 38 | * {@inheritDoc} 39 | */ 40 | public function load(ObjectManager $manager) 41 | { 42 | $userAdmin = new User(); 43 | $encoder = $this->container->get('security.encoder_factory')->getEncoder($userAdmin); 44 | 45 | $userAdmin->setUsername('admin') 46 | ->setPassword($encoder->encodePassword('admin', $userAdmin->getSalt())) 47 | ->setName('Carlnater McStrangelove') 48 | ->setEmail($this->container->getParameter('sender_email')) 49 | ->setGroup($this->getReference('admin-group')); 50 | 51 | $manager->persist($userAdmin); 52 | $manager->flush(); 53 | 54 | $this->addReference('admin-user', $userAdmin); 55 | } 56 | 57 | /** 58 | * {@inheritDoc} 59 | */ 60 | public function getOrder() 61 | { 62 | return 2; // the order in which fixtures will be loaded 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/DependencyInjection/Configuration.php: -------------------------------------------------------------------------------- 1 | root('openskedge'); 22 | 23 | // Here you should define the parameters that are allowed to 24 | // configure your bundle. See the documentation linked above for 25 | // more information on that topic. 26 | 27 | return $treeBuilder; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/DependencyInjection/OpenSkedgeExtension.php: -------------------------------------------------------------------------------- 1 | processConfiguration($configuration, $configs); 24 | 25 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 26 | $loader->load('services.yml'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Entity/ArchivedClock.php: -------------------------------------------------------------------------------- 1 | id; 39 | } 40 | 41 | /** 42 | * Set user 43 | * 44 | * @param \OpenSkedge\AppBundle\Entity\User $user 45 | * @return ArchivedClock 46 | */ 47 | public function setUser(\OpenSkedge\AppBundle\Entity\User $user = null) 48 | { 49 | $this->user = $user; 50 | 51 | return $this; 52 | } 53 | 54 | /** 55 | * Get user 56 | * 57 | * @return \OpenSkedge\AppBundle\Entity\User 58 | */ 59 | public function getUser() 60 | { 61 | return $this->user; 62 | } 63 | 64 | /** 65 | * Set week 66 | * 67 | * @param \DateTime $week 68 | * @return ArchivedClock 69 | */ 70 | public function setWeek($week) 71 | { 72 | $this->week = $week; 73 | 74 | return $this; 75 | } 76 | 77 | /** 78 | * Get week 79 | * 80 | * @return \DateTime 81 | */ 82 | public function getWeek() 83 | { 84 | return $this->week; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Entity/ArchivedClockRepository.php: -------------------------------------------------------------------------------- 1 | createQueryBuilder('ac') 12 | ->select('DISTINCT ac.week') 13 | ->orderBy('ac.week', 'DESC') 14 | ->getQuery() 15 | ->getResult(); 16 | } 17 | 18 | public function supportsClass($class) 19 | { 20 | return $this->getEntityName() === $class || is_subclass_of($class, $this->getEntityName()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Entity/Clock.php: -------------------------------------------------------------------------------- 1 | status = 0; 40 | $this->lastClock = new \DateTime("now"); 41 | } 42 | 43 | /** 44 | * Get id 45 | * 46 | * @return integer 47 | */ 48 | public function getId() 49 | { 50 | return $this->id; 51 | } 52 | 53 | /** 54 | * Set user 55 | * 56 | * @param \OpenSkedge\AppBundle\Entity\User $user 57 | * @return ArchivedClock 58 | */ 59 | public function setUser(\OpenSkedge\AppBundle\Entity\User $user = null) 60 | { 61 | $this->user = $user; 62 | 63 | return $this; 64 | } 65 | 66 | /** 67 | * Get user 68 | * 69 | * @return \OpenSkedge\AppBundle\Entity\User 70 | */ 71 | public function getUser() 72 | { 73 | return $this->user; 74 | } 75 | 76 | /** 77 | * Set status 78 | * 79 | * @param boolean $status 80 | * @return Clock 81 | */ 82 | public function setStatus($status) 83 | { 84 | $this->status = $status; 85 | 86 | return $this; 87 | } 88 | 89 | /** 90 | * Get status 91 | * 92 | * @return boolean 93 | */ 94 | public function getStatus() 95 | { 96 | return $this->status; 97 | } 98 | 99 | /** 100 | * Set lastClock 101 | * 102 | * @param \DateTime $lastClock 103 | * @return Clock 104 | */ 105 | public function setLastClock($lastClock) 106 | { 107 | $this->lastClock = $lastClock; 108 | 109 | return $this; 110 | } 111 | 112 | /** 113 | * Get lastClock 114 | * 115 | * @return \DateTime 116 | */ 117 | public function getLastClock() 118 | { 119 | return $this->lastClock; 120 | } 121 | 122 | /** 123 | * Reset time clock 124 | * 125 | * @return Clock 126 | */ 127 | public function resetClock() 128 | { 129 | for ($i = 0; $i < 7; $i++) { 130 | $this->setDay($i, "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); 131 | } 132 | $this->setLastClock(new \DateTime("now")); 133 | 134 | return $this; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Entity/Group.php: -------------------------------------------------------------------------------- 1 | users = new ArrayCollection(); 41 | } 42 | 43 | public function getId() 44 | { 45 | return $this->id; 46 | } 47 | 48 | public function getName() 49 | { 50 | return $this->name; 51 | } 52 | 53 | public function setName($name) 54 | { 55 | $this->name = $name; 56 | 57 | return $this; 58 | } 59 | 60 | /** 61 | * @see RoleInterface 62 | */ 63 | public function getRole() 64 | { 65 | return $this->role; 66 | } 67 | 68 | /** 69 | * Set role 70 | * 71 | * @param string $role 72 | * @return Group 73 | */ 74 | public function setRole($role) 75 | { 76 | $this->role = $role; 77 | 78 | return $this; 79 | } 80 | 81 | /** 82 | * Add users 83 | * 84 | * @param \OpenSkedge\AppBundle\Entity\User $users 85 | * @return Group 86 | */ 87 | public function addUser(\OpenSkedge\AppBundle\Entity\User $users) 88 | { 89 | $this->users[] = $users; 90 | 91 | return $this; 92 | } 93 | 94 | /** 95 | * Remove users 96 | * 97 | * @param \OpenSkedge\AppBundle\Entity\User $users 98 | */ 99 | public function removeUser(\OpenSkedge\AppBundle\Entity\User $users) 100 | { 101 | $this->users->removeElement($users); 102 | } 103 | 104 | /** 105 | * Get users 106 | * 107 | * @return \Doctrine\Common\Collections\Collection 108 | */ 109 | public function getUsers() 110 | { 111 | return $this->users; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Entity/IP.php: -------------------------------------------------------------------------------- 1 | clockEnabled = false; 50 | } 51 | 52 | 53 | /** 54 | * Get id 55 | * 56 | * @return integer 57 | */ 58 | public function getId() 59 | { 60 | return $this->id; 61 | } 62 | 63 | /** 64 | * Set IP Address 65 | * 66 | * @param string $ip IP address 67 | * 68 | * @return IP 69 | */ 70 | public function setIp($ip) 71 | { 72 | $this->ip = $ip; 73 | 74 | return $this; 75 | } 76 | 77 | /** 78 | * Get ip 79 | * 80 | * @return string 81 | */ 82 | public function getIp() 83 | { 84 | return $this->ip; 85 | } 86 | 87 | /** 88 | * Set name 89 | * 90 | * @param string $name A friendly identifier 91 | * 92 | * @return IP 93 | */ 94 | public function setName($name) 95 | { 96 | $this->name = $name; 97 | 98 | return $this; 99 | } 100 | 101 | /** 102 | * Get name 103 | * 104 | * @return string 105 | */ 106 | public function getName() 107 | { 108 | return $this->name; 109 | } 110 | 111 | /** 112 | * Set clockEnabled 113 | * 114 | * @param boolean $clockEnabled Whether or not the IP is allowed to clock in. 115 | * 116 | * @return IP 117 | */ 118 | public function setClockEnabled($clockEnabled) 119 | { 120 | $this->clockEnabled = $clockEnabled; 121 | 122 | return $this; 123 | } 124 | 125 | /** 126 | * Get clockEnabled 127 | * 128 | * @return boolean 129 | */ 130 | public function isClockEnabled() 131 | { 132 | return $this->clockEnabled; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Entity/SchedulePeriodRepository.php: -------------------------------------------------------------------------------- 1 | getEntityManager()->createQuery('SELECT sp FROM OpenSkedgeBundle:SchedulePeriod sp 18 | WHERE (sp.startTime <= CURRENT_TIMESTAMP() AND sp.endTime >= CURRENT_TIMESTAMP()) 19 | ORDER BY sp.startTime, sp.endTime ASC') 20 | ->getResult(); 21 | } 22 | 23 | public function findSchedulePeriodsForWeek(\DateTime $week) 24 | { 25 | return $this->createQueryBuilder('sp') 26 | ->select('sp') 27 | ->where('sp.startTime <= :week') 28 | ->andWhere('sp.endTime >= :week') 29 | ->setParameter('week', $week) 30 | ->getQuery() 31 | ->getResult(); 32 | } 33 | 34 | /** 35 | * Get schedules periods and their associated availability schedules and position schedules 36 | * ordered by the end time of each scheduling period (descending) 37 | * 38 | * @param integer $uid A user ID 39 | * 40 | * @return DoctrineCollection 41 | */ 42 | public function findUserSchedulePeriodsAssoc($uid) 43 | { 44 | return $this->getEntityManager()->createQuery('SELECT sp, s, a FROM OpenSkedgeBundle:SchedulePeriod sp 45 | LEFT JOIN sp.schedules s JOIN sp.availabilitySchedules a 46 | WHERE (sp.startTime <= CURRENT_TIMESTAMP() AND sp.endTime >= CURRENT_TIMESTAMP() 47 | AND s.schedulePeriod = sp.id AND a.schedulePeriod = sp.id AND s.user = :uid 48 | AND a.user = :uid) ORDER BY sp.endTime DESC') 49 | ->setParameter('uid', $uid) 50 | ->getResult(); 51 | } 52 | 53 | /** 54 | * Get user's schedules periods for which they have availability schedules and position schedules 55 | * 56 | * @param integer $uid A user ID 57 | * 58 | * @return DoctrineCollection 59 | */ 60 | public function findUserSchedulePeriods($uid) 61 | { 62 | return $this->getEntityManager()->createQuery('SELECT sp FROM OpenSkedgeBundle:SchedulePeriod sp 63 | LEFT JOIN sp.schedules s JOIN sp.availabilitySchedules a 64 | WHERE (s.schedulePeriod = sp.id AND a.schedulePeriod = sp.id AND s.user = :uid 65 | AND a.user = :uid) ORDER BY sp.endTime DESC') 66 | ->setParameter('uid', $uid) 67 | ->getResult(); 68 | } 69 | 70 | public function supportsClass($class) 71 | { 72 | return $this->getEntityName() === $class || is_subclass_of($class, $this->getEntityName()); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Entity/ScheduleRepository.php: -------------------------------------------------------------------------------- 1 | getEntityManager()->createQuery('SELECT s FROM OpenSkedgeBundle:Schedule s 20 | WHERE (s.schedulePeriod = :spid AND s.user = :uid)') 21 | ->setParameter('uid', $uid) 22 | ->setParameter('spid', $spid) 23 | ->getResult(); 24 | } 25 | 26 | public function supportsClass($class) 27 | { 28 | return $this->getEntityName() === $class || is_subclass_of($class, $this->getEntityName()); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Entity/ShiftRepository.php: -------------------------------------------------------------------------------- 1 | getEntityManager() 22 | ->createQuery('SELECT shift FROM OpenSkedgeBundle:Shift shift 23 | WHERE (shift.startTime >= :is AND shift.startTime <= :ie AND shift.pickedUpBy = :uid AND shift.schedulePeriod = :spid AND shift.status != \'unapproved\') ORDER BY shift.startTime ASC') 24 | ->setParameter('is', $intervalStart) 25 | ->setParameter('ie', $intervalEnd) 26 | ->setParameter('uid', $uid) 27 | ->setParameter('spid', $spid) 28 | ->getResult(); 29 | } 30 | 31 | public function findPostedShifts() 32 | { 33 | return $this->getEntityManager() 34 | ->createQuery('SELECT shift FROM OpenSkedgeBundle:Shift shift 35 | WHERE (shift.endTime > CURRENT_TIMESTAMP() AND shift.status != \'unapproved\')') 36 | ->getResult(); 37 | } 38 | 39 | public function findUserPastShifts($uid) 40 | { 41 | return $this->getEntityManager()->createQuery('SELECT shift FROM OpenSkedgeBundle:Shift shift 42 | WHERE (shift.endTime < CURRENT_TIMESTAMP() AND shift.pickedUpBy = :uid AND shift.status != \'unapproved\') ORDER BY shift.endTime DESC') 43 | ->setParameter('uid', $uid) 44 | ->getResult(); 45 | } 46 | 47 | public function supportsClass($class) 48 | { 49 | return $this->getEntityName() === $class || is_subclass_of($class, $this->getEntityName()); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Entity/UserRepository.php: -------------------------------------------------------------------------------- 1 | createQueryBuilder('u') 18 | ->select('u, g') 19 | ->leftJoin('u.groups', 'g') 20 | ->where('u.username = :username OR u.email = :email') 21 | ->setParameter('username', $username) 22 | ->setParameter('email', $username) 23 | ->getQuery() 24 | ; 25 | 26 | try { 27 | // The Query::getSingleResult() method throws an exception 28 | // if there is no record matching the criteria. 29 | $user = $q->getSingleResult(); 30 | } catch (NoResultException $e) { 31 | throw new UsernameNotFoundException(sprintf('Unable to find an active admin OpenSkedgeBundle:User object identified by "%s".', $username), null, 0, $e); 32 | } 33 | 34 | return $user; 35 | } 36 | 37 | public function loadUsersByGroup($group) 38 | { 39 | $q = $this 40 | ->createQueryBuilder('u') 41 | ->select('u, g') 42 | ->leftJoin('u.groups', 'g') 43 | ->where('g.name = :group') 44 | ->setParameter('group', $group) 45 | ->getQuery() 46 | ; 47 | 48 | try { 49 | // The Query::getSingleResult() method throws an exception 50 | // if there is no record matching the criteria. 51 | $users = $q->getResult(); 52 | } catch (NoResultException $e) { 53 | throw new UsernameNotFoundException(sprintf('Unable to find an active admin AcmeUserBundle:User object identified by "%s".', $group), null, 0, $e); 54 | } 55 | 56 | return $users; 57 | } 58 | 59 | public function refreshUser(UserInterface $user) 60 | { 61 | $class = get_class($user); 62 | if (!$this->supportsClass($class)) { 63 | throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $class)); 64 | } 65 | 66 | return $this->find($user->getId()); 67 | } 68 | 69 | public function supportsClass($class) 70 | { 71 | return $this->getEntityName() === $class || is_subclass_of($class, $this->getEntityName()); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Form/AreaType.php: -------------------------------------------------------------------------------- 1 | add('name', 'text') 15 | ->add('description', 'textarea', array('required' => false)) 16 | ; 17 | } 18 | 19 | public function setDefaultOptions(OptionsResolverInterface $resolver) 20 | { 21 | $resolver->setDefaults(array( 22 | 'data_class' => 'OpenSkedge\AppBundle\Entity\Area' 23 | )); 24 | } 25 | 26 | public function getName() 27 | { 28 | return 'area'; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Form/AvailabilityScheduleType.php: -------------------------------------------------------------------------------- 1 | add('schedulePeriod', 'entity', array( 15 | 'label' => 'Schedule Period', 16 | 'class' => 'OpenSkedgeBundle:SchedulePeriod', 17 | 'empty_value' => 'Choose a Schedule Period') 18 | ) 19 | ; 20 | } 21 | 22 | public function setDefaultOptions(OptionsResolverInterface $resolver) 23 | { 24 | $resolver->setDefaults(array( 25 | 'data_class' => 'OpenSkedge\AppBundle\Entity\AvailabilitySchedule' 26 | )); 27 | } 28 | 29 | public function getName() 30 | { 31 | return 'schedulePeriod'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Form/EventSubscriber/PatchSubscriber.php: -------------------------------------------------------------------------------- 1 | bind() behavior so that it treats not set values as if they 10 | * were sent unchanged. 11 | * 12 | * Use when you don't want fields to be set to NULL when they are not displayed 13 | * on the page (or to implement PUT/PATCH requests). 14 | * 15 | * Taken from https://gist.github.com/makasim/3720535 16 | * 17 | * @category EventSubscriber 18 | * @package OpenSkedge\AppBundle\Form\EventSubscriber 19 | * @author A.S.Kozienko , Max Fierke 20 | * @license GNU General Public License, version 3 21 | * @version GIT: $Id$ 22 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 23 | */ 24 | class PatchSubscriber implements EventSubscriberInterface 25 | { 26 | public function onPreBind(FormEvent $event) 27 | { 28 | $form = $event->getForm(); 29 | $clientData = $event->getData(); 30 | $clientData = array_replace($this->unbind($form), $clientData ?: array()); 31 | $event->setData($clientData); 32 | } 33 | 34 | /** 35 | * Returns the form's data like $form->bind() expects it 36 | */ 37 | protected function unbind($form) 38 | { 39 | if ($form->count() > 0) { 40 | $ary = array(); 41 | foreach ($form->all() as $name => $child) { 42 | $ary[$name] = $this->unbind($child); 43 | } 44 | return $ary; 45 | } else { 46 | return $form->getViewData(); 47 | } 48 | } 49 | 50 | static public function getSubscribedEvents() 51 | { 52 | return array( 53 | FormEvents::PRE_BIND => 'onPreBind', 54 | ); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Form/IPType.php: -------------------------------------------------------------------------------- 1 | add('ip', 'text', array('label' => 'IP Address')) 15 | ->add('name', 'text', array('required' => false)) 16 | ->add('clockEnabled', 'checkbox', array('label' => 'Time Clock Allowed?', 'required' => false)) 17 | ; 18 | } 19 | 20 | public function setDefaultOptions(OptionsResolverInterface $resolver) 21 | { 22 | $resolver->setDefaults(array( 23 | 'data_class' => 'OpenSkedge\AppBundle\Entity\IP', 24 | )); 25 | } 26 | 27 | public function getName() 28 | { 29 | return 'ip'; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Form/LateShiftType.php: -------------------------------------------------------------------------------- 1 | addEventSubscriber($subscriber); 15 | $builder 16 | ->add('status') 17 | ->add('notes') 18 | ; 19 | } 20 | 21 | public function setDefaultOptions(OptionsResolverInterface $resolver) 22 | { 23 | $resolver->setDefaults(array( 24 | 'data_class' => 'OpenSkedge\AppBundle\Entity\LateShift', 25 | 'intention' => 'lateshift_update' 26 | )); 27 | } 28 | 29 | public function getName() 30 | { 31 | return 'lateshift'; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Form/PositionType.php: -------------------------------------------------------------------------------- 1 | add('name', 'text') 15 | ->add('description', 'textarea', array('required' => false)) 16 | ->add('area', 'entity', array( 17 | 'class' => 'OpenSkedgeBundle:Area', 18 | 'property' => 'name', 19 | 'multiple' => false, 20 | 'query_builder' => function(\Doctrine\ORM\EntityRepository $er) { 21 | $qb = $er->createQueryBuilder('a'); 22 | $qb->select('a') 23 | ->orderBy('a.name', 'ASC'); 24 | return $qb; 25 | })) 26 | ; 27 | } 28 | 29 | public function setDefaultOptions(OptionsResolverInterface $resolver) 30 | { 31 | $resolver->setDefaults(array( 32 | 'data_class' => 'OpenSkedge\AppBundle\Entity\Position' 33 | )); 34 | } 35 | 36 | public function getName() 37 | { 38 | return 'position'; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Form/SchedulePeriodType.php: -------------------------------------------------------------------------------- 1 | add('startTime', 'date', array( 15 | 'widget' => 'single_text', 16 | 'label' => 'Start Date', 17 | 'format' => 'MM-dd-yyyy', 18 | )) 19 | ->add('endTime', 'date', array( 20 | 'widget' => 'single_text', 21 | 'label' => 'End Date', 22 | 'format' => 'MM-dd-yyyy', 23 | )) 24 | ; 25 | } 26 | 27 | public function setDefaultOptions(OptionsResolverInterface $resolver) 28 | { 29 | $resolver->setDefaults(array( 30 | 'data_class' => 'OpenSkedge\AppBundle\Entity\SchedulePeriod' 31 | )); 32 | } 33 | 34 | public function getName() 35 | { 36 | return 'schedule_period'; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Form/SettingsType.php: -------------------------------------------------------------------------------- 1 | 'Sunday', 'monday' => 'Monday', 'tuesday' => 'Tuesday', 'wednesday' =>'Wednesday', 'thursday' => 'Thursday', 'friday' => 'Friday', 'saturday' => 'Saturday'); 14 | $builder 15 | ->add('brandName', 'text', array('label' => 'Brand Name')) 16 | ->add('pruneAfter', 'integer', array('attr' => array('class' => 'span12'), 'label' => 'Keep time clock data for')) 17 | ->add('weekStartDay', 'choice', array('label' => 'Week Start Day', 'choices' => $days)) 18 | ->add('weekStartDayClock', 'choice', array('label' => 'Week Start Day (Pay Period)','choices' => $days)) 19 | ->add('defaultTimeResolution', 'choice', array( 20 | 'label' => 'Default Time Resolution', 21 | 'choices' => array( 22 | '15 mins' => '15 mins', 23 | '30 mins' => '30 mins', 24 | '1 hour' => '1 hour', 25 | ), 26 | )) 27 | ->add('startHour', 'text', array( 28 | 'label' => 'Schedule Start Hour', 29 | 'attr' => array('class' => 'span12', 'data-show-inputs' => 'false') 30 | )) 31 | ->add('endHour', 'text', array( 32 | 'label' => 'Schedule End Hour', 33 | 'attr' => array('class' => 'span12', 'data-show-inputs' => 'false') 34 | )) 35 | ->add('massEmail', 'email', array( 36 | 'label' => 'Mass Email Address (e.g. LISTSERV mailing list)', 37 | 'required' => false 38 | )) 39 | ; 40 | } 41 | 42 | public function setDefaultOptions(OptionsResolverInterface $resolver) 43 | { 44 | $resolver->setDefaults(array( 45 | 'data_class' => 'OpenSkedge\AppBundle\Entity\Settings' 46 | )); 47 | } 48 | 49 | public function getName() 50 | { 51 | return 'settings'; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Form/ShiftType.php: -------------------------------------------------------------------------------- 1 | add('startTime', 'datetime', array( 15 | 'date_widget' => 'single_text', 16 | 'time_widget' => 'single_text', 17 | 'date_format' => 'yyyy-M-d', 18 | 'label' => 'Shift Start Time' 19 | )) 20 | ->add('endTime', 'datetime', array( 21 | 'date_widget' => 'single_text', 22 | 'time_widget' => 'single_text', 23 | 'date_format' => 'yyyy-M-d', 24 | 'label' => 'Shift End Time' 25 | )) 26 | ->add('status') 27 | ->add('notes', 'textarea', array( 28 | 'label' => 'Notes', 29 | 'attr' => array( 30 | 'class' => 'input-xlarge', 31 | 'rows' => 6 32 | ) 33 | )) 34 | ->add('pickedUpBy', 'entity', array( 35 | 'class' => 'OpenSkedgeBundle:User' 36 | )) 37 | ->add('schedulePeriod', 'entity', array( 38 | 'class' => 'OpenSkedgeBundle:SchedulePeriod', 39 | 'label' => 'Schedule Period', 40 | 'attr' => array('class' => 'input-xlarge') 41 | )) 42 | ->add('position', 'entity', array( 43 | 'class' => 'OpenSkedgeBundle:Position', 44 | 'attr' => array('class' => 'input-xlarge'), 45 | 'query_builder' => function(\Doctrine\ORM\EntityRepository $er) { 46 | $qb = $er->createQueryBuilder('p'); 47 | $qb->select('p') 48 | ->leftJoin('p.area', 'a') 49 | ->orderBy('a.name, p.name', 'ASC'); 50 | return $qb; 51 | }) 52 | ) 53 | ; 54 | } 55 | 56 | public function setDefaultOptions(OptionsResolverInterface $resolver) 57 | { 58 | $resolver->setDefaults(array( 59 | 'data_class' => 'OpenSkedge\AppBundle\Entity\Shift', 60 | 'intention' => 'shift_modify' 61 | )); 62 | } 63 | 64 | public function getName() 65 | { 66 | return 'shift'; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Form/UserType.php: -------------------------------------------------------------------------------- 1 | add('username', 'text') 15 | ->add('password', 'repeated', array( 16 | 'required' => false, 17 | 'first_name' => 'password', 18 | 'second_name' => 'confirm', 19 | 'type' => 'password')) 20 | ->add('name', 'text') 21 | ->add('workphone', 'text', array('required' => false, 'label' => 'Work Phone')) 22 | ->add('homephone', 'text', array('required' => false, 'label' => 'Home Phone')) 23 | ->add('location', 'text', array('required' => false)) 24 | ->add('email', 'email') 25 | ->add('min', 'integer', array('label' => 'Minimum Hours')) 26 | ->add('max', 'integer', array('label' => 'Maximum Hours')) 27 | ->add('hours', 'integer', array('label' => 'Desired Hours')) 28 | ->add('notes', 'textarea', array('required' => false)) 29 | ->add('supnotes', 'textarea', array('label' => 'Supervisor Notes', 'required' => false)) 30 | ->add('color', 'text', array('required' => false, 'attr' => array('class' => 'span12'))) 31 | ->add('isActive', 'checkbox', array('label' => 'Active', 'required' => false)) 32 | ->add('group', 'entity', array( 33 | 'label' => 'User Role', 34 | 'class' => 'OpenSkedgeBundle:Group', 35 | 'property' => 'name', 36 | 'multiple' => false)) 37 | ->add('supervisors', 'entity', array( 38 | 'attr' => array('class' => 'input-xlarge'), 39 | 'required' => false, 40 | 'label' => 'Supervisors', 41 | 'class' => 'OpenSkedgeBundle:User', 42 | 'property' => 'name', 43 | 'multiple' => true, 44 | 'query_builder' => function(\Doctrine\ORM\EntityRepository $er) { 45 | $qb = $er->createQueryBuilder('u'); 46 | $qb->select('u, g') 47 | ->leftJoin('u.group', 'g') 48 | ->where($qb->expr()->in('g.name', array('Supervisor', 'Admin'))) 49 | ->orderBy('u.name', 'DESC'); 50 | return $qb; 51 | } 52 | )) 53 | ; 54 | } 55 | 56 | public function setDefaultOptions(OptionsResolverInterface $resolver) 57 | { 58 | $resolver->setDefaults(array( 59 | 'data_class' => 'OpenSkedge\AppBundle\Entity\User' 60 | )); 61 | } 62 | 63 | public function getName() 64 | { 65 | return 'user'; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Mailer/MailerInterface.php: -------------------------------------------------------------------------------- 1 | setParameter('secret', getenv("OPENSKEDGE_SECRET")); 19 | } 20 | 21 | if (getenv("SYMFONY__SENDER__EMAIL")) { 22 | $container->setParameter('sender_email', getenv("SYMFONY__SENDER__EMAIL")); 23 | } 24 | 25 | if (extension_loaded('apc') && ini_get('apc.enabled')) { 26 | $container->setParameter('doctrine.orm.metadata_cache_driver', 'apc'); 27 | $container->setParameter('doctrine.orm.result_cache_driver', 'apc'); 28 | $container->setParameter('doctrine.orm.query_cache_driver', 'apc'); 29 | } else if (extension_loaded('memcache')) { 30 | $container->setParameter('doctrine.orm.metadata_cache_driver', 'memcache'); 31 | $container->setParameter('doctrine.orm.result_cache_driver', 'memcache'); 32 | $container->setParameter('doctrine.orm.query_cache_driver', 'memcache'); 33 | } 34 | 35 | 36 | // Get the commit id from HEAD if we're deployed as a git repo. 37 | if (is_readable(__DIR__.'/../../../.git/HEAD')) { 38 | $headref = rtrim(substr(file_get_contents(__DIR__.'/../../../.git/HEAD'), 5)); 39 | if (is_readable(__DIR__.'/../../../.git/'.$headref)) { 40 | $commit = file_get_contents(__DIR__.'/../../../.git/'.$headref); 41 | $commit = substr($commit, 0, 7); 42 | } else { 43 | $commit = null; 44 | } 45 | } else { 46 | // Not deployed as a git repo, so we have no commit id. 47 | $commit = null; 48 | } 49 | 50 | $container->setParameter('deploy_commit', (string)$commit); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/config/services.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | notify_mailer.class: OpenSkedge\AppBundle\Mailer\TwigMailer 3 | 4 | services: 5 | app_settings: 6 | class: OpenSkedge\AppBundle\Services\AppSettingsService 7 | arguments: [@doctrine.orm.default_entity_manager] 8 | 9 | clock_utils: 10 | class: OpenSkedge\AppBundle\Services\ClockService 11 | arguments: [@doctrine.orm.default_entity_manager, @dt_utils] 12 | 13 | dt_utils: 14 | class: OpenSkedge\AppBundle\Services\DateTimeUtils 15 | arguments: [@app_settings] 16 | 17 | notify_mailer: 18 | class: %notify_mailer.class% 19 | arguments: [@mailer, @twig, @logger, @app_settings, { senderEmail: %sender_email% }] 20 | lazy: true 21 | 22 | request: 23 | class: Symfony\Component\HttpFoundation\Request 24 | 25 | stats: 26 | class: OpenSkedge\AppBundle\Services\StatsService 27 | arguments: [@doctrine.orm.default_entity_manager, @dt_utils] 28 | 29 | app_settings.twig.extension: 30 | class: OpenSkedge\AppBundle\Twig\Extension\SettingsExtension 31 | arguments: [@app_settings] 32 | tags: 33 | - { name: 'twig.extension' } 34 | 35 | page.twig.extension: 36 | class: OpenSkedge\AppBundle\Twig\Extension\PageExtension 37 | arguments: [@request] 38 | tags: 39 | - { name: 'twig.extension' } 40 | 41 | worker_command: 42 | class: OpenSkedge\AppBundle\Command\WorkerRunCommand 43 | tags: 44 | - { name: monolog.logger, channel: worker } 45 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/meta/LICENSE: -------------------------------------------------------------------------------- 1 | OpenSkedge 2 | 3 | Copyright (C) 2003-2004 Brigham Young University (John Finlay) 4 | Copyright (C) 2007-2012 University of Minnesota (Joe Krall, Carl Allen, Max Fierke) 5 | Copyright (C) 2012-2013 Max Fierke 6 | 7 | This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. 8 | 9 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 10 | 11 | You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 12 | 13 | A copy of the GNU General Public License version 3 is present in the file GPLv3.txt 14 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Area/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block modulecontent %} 3 |
    4 | 9 |

    {{ entity.name }}

    10 |
    11 |
    12 | {{ form_widget(delete_form) }} 13 | 14 |
    15 |
    16 |
    17 |
    18 | {{ form_widget(edit_form) }} 19 |
    20 | 21 | Back to Area 22 |
    23 |
    24 |
    25 | {% endblock %} 26 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Area/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Areas{% endblock %} 3 | {% block javascripts %} 4 | 9 | {% endblock %} 10 | {% block modulecontent %} 11 |
    12 |

    Areas

    13 | {% if is_granted('ROLE_ADMIN') %} 14 | Add Area 15 | {% endif %} 16 |
    17 | {% if entities is empty %} 18 |
    19 | Sorry! No areas found. You should create one. 20 |
    21 | {% else %} 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% for entity in entities %} 32 | 33 | 34 | 35 | 46 | 47 | {% endfor %} 48 | 49 |
    NameDescriptionActions
    {{ entity.name }}{{ entity.description }} 36 |
    37 | View 38 | {% if is_granted('ROLE_ADMIN') %} 39 | 40 | 43 | {% endif %} 44 |
    45 |
    50 |
    51 | {{ pagerfanta(paginator, 'twitter_bootstrap') }} 52 |
    53 | {% endif %} 54 |
    55 | {% endblock %} 56 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Area/new.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block modulecontent %} 3 |
    4 | 8 |
    9 | {{ form_widget(form) }} 10 |
    11 | 12 | Back to Area List 13 |
    14 |
    15 |
    16 | {% endblock %} 17 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Area/view.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Area - {{ entity.name }}{% endblock %} 3 | {% block javascripts %} 4 | 9 | {% endblock %} 10 | {% block modulecontent %} 11 |
    12 | 16 |

    {{ entity.name }}

    17 | {% if is_granted('ROLE_ADMIN') %} 18 |
    19 |
    20 | Edit 21 | {{ form_widget(delete_form) }} 22 | 23 |
    24 |
    25 | {% endif %} 26 |

    {{ entity.description }}

    27 |
    28 | {% if is_granted('ROLE_ADMIN') %} 29 | Add Position 30 | {% endif %} 31 | {% if not positions is defined or positions is empty %} 32 |
    33 | Sorry! No positions were found for this area. 34 |
    35 | {% else %} 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {% for position in positions %} 46 | 47 | 48 | 49 | 60 | 61 | {% endfor %} 62 | 63 |
    NameDescriptionActions
    {{ position.name }}{{ position.description }} 50 |
    51 | View 52 | {% if is_granted('ROLE_ADMIN') %} 53 | 54 | 57 | {% endif %} 58 |
    59 |
    64 |
    65 | {{ pagerfanta(paginator, 'twitter_bootstrap') }} 66 |
    67 | {% endif %} 68 |
    69 | {% endblock %} 70 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/AvailabilitySchedule/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - {{ title }}{% endblock %} 3 | {% block javascripts %} 4 | 9 | {% endblock %} 10 | {% block modulecontent %} 11 |
    12 |

    {{ title }}

    13 | {% if user.id == app.user.id %} 14 | Add Schedule 15 | {% endif %} 16 |
    17 | {% if entities is empty %} 18 |
    19 | Sorry! {% if user.id == app.user.id %}It appears that you have not created any availability schedules yet. Click here to create one.{% else %}{{ user.name }} does not appear to have any schedules.{% endif %} 20 | {% else %} 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {% for entity in entities %} 31 | 32 | 33 | 34 | 45 | 46 | {% endfor %} 47 | 48 |
    Start DateEnd DateActions
    {{ entity.schedulePeriod.startTime|date('M-d-Y') }}{{ entity.schedulePeriod.endTime|date('M-d-Y') }} 35 |
    36 | View 37 | {% if entity.user.id == app.user.id %} 38 | 39 | 42 | {% endif %} 43 |
    44 |
    49 |
    50 | {{ pagerfanta(paginator, 'twitter_bootstrap') }} 51 |
    52 | {% endif %} 53 |
    54 | {% endblock %} 55 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/AvailabilitySchedule/precreate.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block modulecontent %} 3 |
    4 | 8 |

    Create a New Availability Schedule

    9 |
    10 | {{ form_widget(form) }} 11 |
    12 | 13 | Back to Schedules 14 |
    15 |
    16 |
    17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/AvailabilitySchedule/view.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - {{ avail.user.name }} - Schedule for {{ avail.schedulePeriod }}{% endblock %} 3 | {% block modulecontent %} 4 |
    5 |

    {{ avail.user.name }}'s schedule for {{ avail.schedulePeriod.startTime|date('M-d-Y') }} to {{ avail.schedulePeriod.endTime|date('M-d-Y') }}

    6 | {% if avail.user.id == app.user.id %} 7 |
    8 |
    9 | Edit 10 | {{ form_widget(delete_form) }} 11 | 12 |
    13 |
    14 | {% endif %} 15 |
    16 |
    17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
    UnavailableLow PreferenceMedium PreferenceHigh Preference
    25 | 26 |
    27 | {% include 'OpenSkedgeBundle:ModularBlocks:timeresolution.html.twig' %} 28 |
    29 |
    30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
    Total Hours AvailableTotal Hours DesiredTotal Hours Scheduled
    {{ hrsAvail }}{{ avail.user.hours }}{{ hrsSched }}
    44 | {% include 'OpenSkedgeBundle:ModularBlocks:userschedule.html.twig' %} 45 |
    46 | {% endblock %} 47 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Dashboard/clockmodule.html.twig: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | {{ date()|date("F j, Y") }} 4 |

    5 |
    6 | {% spaceless %} 7 | {% if app.user.clock.status == 1 %} 8 | {% set action = 'out' %} 9 | {% set actionpath = 'clock_out' %} 10 | {% else %} 11 | {% set action = 'in' %} 12 | {% set actionpath = 'clock_in' %} 13 | {% endif %} 14 | {% if outside %} 15 |
    16 | Sorry! You cannot clock in. It appears you're not accessing {{ app_brand_name() }} from work. 17 |
    18 | {% endif %} 19 | {% endspaceless %} 20 |
    21 | 22 |
    23 |
    24 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Dashboard/schedulemodule.html.twig: -------------------------------------------------------------------------------- 1 |
    2 | {% if avail is defined and not avail is null %} 3 |
    4 |
    5 | 6 | 11 |
    12 | {% include 'OpenSkedgeBundle:ModularBlocks:timeresolution.html.twig' %} 13 |
    14 |
    15 |
    16 | {% include 'OpenSkedgeBundle:ModularBlocks:userschedule.html.twig' %} 17 | {% else %} 18 |
    19 | Sorry! 20 | No schedule(s) found for you in any current scheduling periods. 21 |
    22 |
    23 | Hey, {{ app.user.name }}! 24 |

    Did you create an availability schedule? If you already did but you're still seeing this message, your supervisor(s) may not have scheduled you yet.

    25 |
    26 | {% endif %} 27 |
    28 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/HoursReport/generate.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Clock Report - {{ user.name }} - {{ week|date('M-d-Y') }}{% endblock %} 3 | {% block modulecontent %} 4 |
    5 | 11 |

    {{ user.name }}'s Clock Report for Week of {{ week|date('M-d-Y') }}

    12 |
    13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
    Not Scheduled and Not WorkedScheduled and WorkedScheduled and Not WorkedWorked and Not Scheduled
    21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | {% for i in 0..95 %} 36 | 37 | 38 | {% for j in 0..6 %}{% spaceless %} 39 | {% endspaceless %} 40 | {% endfor %}{% set htime = htime|date_modify("+15 mins") %} 41 | 42 | {% endfor %} 43 | 44 |
    SunMonTueWedThuFriSat
    {{ htime|date("g:i a", false) }}
    45 |
    46 | {% endblock %} 47 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/HoursReport/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Clock Reports{% endblock %} 3 | {% block modulecontent %} 4 |
    5 | 9 |

    Clock Reports

    10 |
    11 | {% if entities is empty %} 12 |
    13 | Sorry! No clock reports available. 14 |
    15 | {% else %} 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {% for entity in entities %} 25 | 26 | 27 | 30 | 31 | {% endfor %} 32 | 33 |
    Week ofActions
    {{ entity.week|date('M-d-Y') }} 28 | View Users 29 |
    34 |
    35 | {{ pagerfanta(paginator, 'twitter_bootstrap') }} 36 |
    37 | {% endif %} 38 |
    39 | {% endblock %} 40 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/HoursReport/view.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Clock Reports - {{ week|date('M-d-Y') }}{% endblock %} 3 | {% block modulecontent %} 4 |
    5 | 10 |

    Users Clocked In for Week of {{ week|date('M-d-Y') }}

    11 |
    12 | {% if not entities is defined or entities is empty %} 13 |
    14 | Sorry! No users clocked in for this week. 15 |
    16 | {% else %} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% for ac in entities %} 27 | 28 | 29 | 30 | 38 | 39 | {% endfor %} 40 | 41 |
    NameUsernameActions
    {{ ac.user.name }}{{ ac.user.username }} 31 |
    32 | 33 | 34 | 35 | 36 |
    37 |
    42 |
    43 | {{ pagerfanta(paginator, 'twitter_bootstrap') }} 44 |
    45 | {% endif %} 46 |
    47 | {% endblock %} 48 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/IP/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Settings - IP Manifest - {{ entity.ip }} - Edit{% endblock %} 3 | {% block modulecontent %} 4 |
    5 | 11 |

    {{ entity.ip }}

    12 |
    13 |
    14 | {{ form_widget(delete_form) }} 15 | 16 |
    17 |
    18 |
    19 |
    20 | {{ form_errors(edit_form) }} 21 | 22 | {{ form_row(edit_form.ip) }} 23 | {{ form_row(edit_form.name) }} 24 | 27 | {{ form_rest(edit_form) }} 28 | 29 |
    30 | 31 | Back to IP Manifest 32 |
    33 |
    34 |
    35 | {% endblock %} 36 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/IP/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Settings - IP Manifest{% endblock %} 3 | {% block javascripts %} 4 | 9 | {% endblock %} 10 | {% block modulecontent %} 11 |
    12 |

    IP Manifest

    13 | Add IP Address 14 |
    15 | {% if entities is empty %} 16 |
    17 | Sorry! No IP addresses were found. Users will not be able to clock in and out until you add an IP address from which they may clock in and out. 18 |
    19 | {% else %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {% for entity in entities %} 31 | 32 | 33 | 34 | 35 | 42 | 43 | {% endfor %} 44 | 45 |
    IP AddressNameTime Clock Allowed?Actions
    {{ entity.ip }}{{ entity.name }}{% if entity.clockEnabled == true %}Yes{% else %}No{% endif %} 36 | Edit 37 |
    38 | {{ form_widget(deleteForms[loop.index0]) }} 39 | 40 |
    41 |
    46 |
    47 | {{ pagerfanta(paginator, 'twitter_bootstrap') }} 48 |
    49 | {% endif %} 50 |
    51 | {% endblock %} 52 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/IP/new.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Settings - IP Manifest - Add an IP Address{% endblock %} 3 | {% block javascripts %} 4 | 9 | {% endblock %} 10 | {% block modulecontent %} 11 |
    12 | 17 |

    IP Creation

    18 |
    19 |
    20 | {{ form_errors(form) }} 21 | 22 | {{ form_label(form.ip) }} 23 | {{ form_widget(form.ip) }} 24 | 25 |
    26 | {{ form_row(form.name) }} 27 | 30 | {{ form_rest(form) }} 31 | 32 |
    33 | 34 | Back to IP Manifest 35 |
    36 | 37 |
    38 | {% endblock %} 39 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/availschedulechange.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] {{ user.name }} has changed their availability for {{ schedulePeriod }} 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ supervisor.name }}, 9 | 10 | This is just a notification email to let you know that your employee, {{ user.name }}, has changed their availability for the {{ schedulePeriod }} scheduling period. 11 | 12 | {{ app_brand_name() }} Management 13 | ---- 14 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 15 | {% endautoescape %} 16 | {% endblock %} 17 | {% block body_html %}{% endblock %} 18 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/availschedulepost.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] {{ user.name }} has posted their availability for {{ schedulePeriod }} 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ supervisor.name }}, 9 | 10 | This is just a notification email to let you know that your employee, {{ user.name }}, has posted their availability for the {{ schedulePeriod }} scheduling period. 11 | 12 | {{ app_brand_name() }} Management 13 | ---- 14 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 15 | {% endautoescape %} 16 | {% endblock %} 17 | {% block body_html %}{% endblock %} 18 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/lateemployee_emp.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] {{ user.name }}, you have not clocked in yet! 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ user.name }}, 9 | 10 | This is just a notification email to let you know that you have not clocked in for your {{ position.name }} - {{ position.area.name }} shift of which you are currently scheduled. This incident has been reported and your supervisors have been notified. 11 | 12 | {{ app_brand_name() }} Management 13 | ---- 14 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 15 | {% endautoescape %} 16 | {% endblock %} 17 | {% block body_html %}{% endblock %} 18 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/lateemployee_sup.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] {{ user.name }} has not clocked in yet! 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ supervisor.name }}, 9 | 10 | This is just a notification email to let you know that one of your employees, {{ user.name }}, has not clocked in for their {{ position.name }} - {{ position.area.name }} shift of which they are currently scheduled. 11 | 12 | {{ app_brand_name() }} Management 13 | ---- 14 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 15 | {% endautoescape %} 16 | {% endblock %} 17 | {% block body_html %}{% endblock %} 18 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/newsupervisor.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] {{ user.name }}, you have a new supervisor! 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ user.name }}, 9 | 10 | This is just a notification email to let you know that you have a new supervisor, {{ newSupervisor.name }}, on {{ app_brand_name() }}. {{ newSupervisor.name }} is now capable of scheduling you for positions. 11 | 12 | {{ app_brand_name() }} Management 13 | ---- 14 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 15 | {% endautoescape %} 16 | {% endblock %} 17 | {% block body_html %}{% endblock %} 18 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/newuser.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] Welcome {{ user.name }}! 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ user.name }}, 9 | 10 | Welcome to {{ app_brand_name() }}, a flexible employee scheduling application powered by OpenSkedge! Your manager or an employement administrator created an account for you with the following details below: 11 | 12 | Username: {{ user.name }} 13 | Password: {{ password }} 14 | 15 | You can login in via {{ url('login') }} 16 | 17 | {{ app_brand_name() }} Management 18 | ---- 19 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 20 | {% endautoescape %} 21 | {% endblock %} 22 | {% block body_html %} 23 | Hey {{ user.name }},
    24 |
    25 | Welcome to {{ app_brand_name() }}, a flexible employee scheduling application powered by OpenSkedge! Your manager or an employement administrator created an account for you with the following details below:
    26 |
    27 | Username: {{ user.name }}
    28 | Password: {{ password }}
    29 |
    30 | You can login in here (For plaintext users: {{ url('login') }})
    31 |
    32 | {{ app_brand_name() }} Management
    33 | ----
    34 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 35 | {% endblock %} 36 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/schedulechange.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] Your {{ schedule.position.area.name }} - {{ schedule.position.name }} schedule has changed for {{ schedule.schedulePeriod }} 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ user.name }}, 9 | 10 | This is just a notification email to let you know that your {{ schedule.position.area.name }} - {{ schedule.position.name }} schedule has changed for the {{ schedule.schedulePeriod }} scheduling period. 11 | 12 | {{ app_brand_name() }} Management 13 | ---- 14 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 15 | {% endautoescape %} 16 | {% endblock %} 17 | {% block body_html %}{% endblock %} 18 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/shiftdenied.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] {{ shift.user.name }}, your shift trade request has been denied. 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ shift.user.name }}, 9 | 10 | Unfortunately, one of your supervisors has denied your shift trade request for your {{ shift.position.name }} - {{ shift.position.area.name }} shift from {{ shift.startTime|date('Y-m-d g:i A') }} to {{ shift.endTime|date('Y-m-d g:i A') }}. You are expected to report for this shift. 11 | 12 | {{ app_brand_name() }} Management 13 | ---- 14 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 15 | {% endautoescape %} 16 | {% endblock %} 17 | {% block body_html %}{% endblock %} 18 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/shiftdenied_pickedup.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] {{ shift.pickedUpBy.name }}, your shift trade has been cancelled. 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ shift.pickedUpBy.name }}, 9 | 10 | Unfortunately, one of your supervisors has denied the shift trade request for {{ shift.user.name }}'s {{ shift.position.name }} - {{ shift.position.area.name }} shift from {{ shift.startTime|date('Y-m-d g:i A') }} to {{ shift.endTime|date('Y-m-d g:i A') }}. You should NOT and are NOT expected to report for this shift. 11 | 12 | {{ app_brand_name() }} Management 13 | ---- 14 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 15 | {% endautoescape %} 16 | {% endblock %} 17 | {% block body_html %}{% endblock %} 18 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/shiftpickedup.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] {{ shift.user.name }}, your shift has been picked up by {{ shift.pickedUpBy.name }} 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ shift.user.name }}, 9 | 10 | This is just a notification email to let you know that {{ shift.pickedUpBy.name }} has picked up your {{ shift.position.name }} - {{ shift.position.area.name }} shift from {{ shift.startTime|date('Y-m-d g:i A') }} to {{ shift.endTime|date('Y-m-d g:i A') }}. 11 | 12 | {{ app_brand_name() }} Management 13 | ---- 14 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 15 | {% endautoescape %} 16 | {% endblock %} 17 | {% block body_html %}{% endblock %} 18 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/shiftposted_mass.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] {{ shift.user.name }} has posted a shift 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey there, 9 | 10 | This is just a notification email to let you know that {{ shift.user.name }} has a posted their {{ shift.position.name }} - {{ shift.position.area.name }} shift from {{ shift.startTime|date('Y-m-d g:i A') }} to {{ shift.endTime|date('Y-m-d g:i A') }} to the shift trading area of {{ app_brand_name() }}. 11 | 12 | Details: 13 | 14 | {{ shift.notes }} 15 | 16 | {{ app_brand_name() }} Management 17 | ---- 18 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 19 | {% endautoescape %} 20 | {% endblock %} 21 | {% block body_html %} 22 | Hey there,
    23 |
    24 |

    This is just a notification email to let you know that {{ shift.user.name }} has posted their {{ shift.position.name }} - {{ shift.position.area.name }} shift from {{ shift.startTime|date('Y-m-d g:i A') }} to {{ shift.endTime|date('Y-m-d g:i A') }} to the shift trading area of {{ app_brand_name() }}.


    25 |
    26 | Details
    27 |
    {{ shift.notes }}

    28 |
    29 | {{ app_brand_name() }} Management
    30 | ----
    31 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 32 | {% endblock %} 33 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Mailer/shiftposted_sup.txt.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | {% autoescape false %} 3 | [{{ app_brand_name() }}] {{ shift.user.name }} has posted a shift 4 | {% endautoescape %} 5 | {% endblock %} 6 | {% block body_text %} 7 | {% autoescape false %} 8 | Hey {{ supervisor.name }}, 9 | 10 | This is just a notification email to let you know that one of your employees, {{ shift.user.name }}, has posted their {{ shift.position.name }} - {{ shift.position.area.name }} shift from {{ shift.startTime|date('Y-m-d g:i A') }} to {{ shift.endTime|date('Y-m-d g:i A') }} to the shift trading area of {{ app_brand_name() }}. Please approve or deny their shift posting by going to the Shift Trade Report page: {{ path('report_shifts') }} 11 | 12 | {{ app_brand_name() }} Management 13 | ---- 14 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 15 | {% endautoescape %} 16 | {% endblock %} 17 | {% block body_html %} 18 | Hey {{ supervisor.name }},
    19 |
    20 |

    This is just a notification email to let you know that one of your employees, {{ shift.user.name }}, has posted their {{ shift.position.name }} - {{ shift.position.area.name }} shift from {{ shift.startTime|date('Y-m-d g:i A') }} to {{ shift.endTime|date('Y-m-d g:i A') }} to the shift trading area of {{ app_brand_name() }}. Please approve or deny their shift posting by going to the Shift Trade Report page


    21 |
    22 | {{ app_brand_name() }} Management
    23 | ----
    24 | This is an automated email sent by OpenSkedge. Do NOT respond to this email. You will not get a reply. 25 | {% endblock %} 26 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/ModularBlocks/timeresolution.html.twig: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/ModularBlocks/userschedule.html.twig: -------------------------------------------------------------------------------- 1 | {% spaceless %} 2 | {% if resolution == "15 mins" %} 3 | {% set sectiondiv = 1 %} 4 | {% set next_section = "+15 minutes" %} 5 | {% elseif resolution == "30 mins" %} 6 | {% set sectiondiv = 2 %} 7 | {% set next_section = "+30 minutes" %} 8 | {% else %} 9 | {% set sectiondiv = 4 %} 10 | {% set next_section = "+1 hour" %} 11 | {% endif %} 12 | {% endspaceless %} 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | {% for i in (startIndex/sectiondiv)..(endIndex/sectiondiv) %} 28 | 29 | 30 | {% for j in 0..6 %} 31 | {% spaceless %} 32 | 39 | {% endfor %}{% set htime = htime|date_modify(next_section) %} 40 | 41 | {% endfor %} 42 | {% if edit|default(false) or create|default(false) %} 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | {% endif %} 54 | 55 |
    SunMonTueWedThuFriSat
    {{ htime|date("g:i a", false) }} 33 | {% if not create|default(false) %} 34 | {% for schedule in schedules %} 35 | {% if schedule.getDayOffset(j, i * sectiondiv) == '1' %}{{ schedule.position.area.name }} - {{ schedule.position.name }}{% endif %} 36 | {% endfor %} 37 | {% endif %} 38 | {% endspaceless %}
    FillFillFillFillFillFillFill
    56 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Position/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block modulecontent %} 3 |
    4 | 10 |

    {{ entity.name }}

    11 |
    12 |
    13 | {{ form_widget(delete_form) }} 14 | 15 |
    16 |
    17 |
    18 |
    19 | {{ form_widget(edit_form) }} 20 |
    21 | 22 | Back to Position 23 |
    24 |
    25 |
    26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Position/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - {{ userstitle }}{% endblock %} 3 | {% block javascripts %} 4 | 9 | {% endblock %} 10 | {% block modulecontent %} 11 |
    12 |

    {{ userstitle }}

    13 | {% if entities is empty %} 14 |
    15 |
    16 | Sorry! No positions were found. 17 |
    18 | {% else %} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | {% for entity in entities %} 29 | 30 | 31 | 32 | 33 | 36 | 37 | {% endfor %} 38 | 39 |
    AreaPositionDescription
    {{ entity.area.name }}{{ entity.name }}{{ entity.description }} 34 | View 35 |
    40 |
    41 | {{ pagerfanta(paginator, 'twitter_bootstrap') }} 42 |
    43 | {% endif %} 44 |
    45 | {% endblock %} 46 | 47 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Position/new.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block modulecontent %} 3 |
    4 | 9 |

    Create a New Position

    10 |
    11 | {{ form_widget(form) }} 12 |
    13 | 14 | Back to Area 15 |
    16 |
    17 |
    18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Position/select.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block modulecontent %} 3 |
    4 | 9 |

    Schedule a Position

    10 |
    11 | {{ form_widget(form) }} 12 |
    13 | 14 | Back to Schedule Period 15 |
    16 |
    17 |
    18 | {% endblock %} 19 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Position/view.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - {{ entity.area.name }} - {{ entity.name }}{% endblock %} 3 | {% block modulecontent %} 4 |
    5 | 10 |

    {{ entity.name }}

    11 | {% if is_granted('ROLE_ADMIN') %} 12 |
    13 |
    14 | Edit 15 | {{ form_widget(delete_form) }} 16 | 17 |
    18 |
    19 | {% endif %} 20 |

    {{ entity.description }}

    21 |
    22 |

    Schedule This Position

    23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% for schedulePeriod in schedulePeriods %} 32 | 33 | 34 | 40 | 41 | {% endfor %} 42 | 43 |
    Schedule PeriodActions
    {{ schedulePeriod }} 35 | 39 |
    44 |
    45 | {{ pagerfanta(paginator, 'twitter_bootstrap') }} 46 |
    47 |
    48 | {% endblock %} 49 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Report/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Reports{% endblock %} 3 | {% block modulecontent %} 4 |
    5 |

    Reports

    6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
    Report TypeDescription
    Clock ReportsGenerate time clock reports for users which compare clocked in hours with hours scheduled.
    Late/Missed Shift ReportView late/missed shift logs and the user supplied reason for being late/absent.
    You may also set them to excuse or unexcused.
    Shift Trade ReportView shifts posted for trade and the user supplied reason for posting.
    You may also set them to approved or unapproved.
    28 |
    29 | {% endblock %} 30 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/SchedulePeriod/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - {{ entity }} Schedule Period - Edit{% endblock %} 3 | 4 | {% block stylesheets %} 5 | {{ parent() }} 6 | 7 | {% endblock %} 8 | {% block javascripts %} 9 | 10 | 14 | {% endblock %} 15 | {% block modulecontent %} 16 |
    17 | 22 |

    Editing a Schedule Period

    23 |
    24 | {{ form_errors(edit_form) }} 25 | {{ form_label(edit_form.startTime) }} 26 |
    27 | {{ form_widget(edit_form.startTime) }} 28 | 29 |
    30 | {{ form_label(edit_form.endTime) }} 31 |
    32 | {{ form_widget(edit_form.endTime) }} 33 | 34 |
    35 | {{ form_rest(edit_form) }} 36 |
    37 | 38 | Back to Schedule Period 39 |
    40 |
    41 |
    42 | {% endblock %} 43 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/SchedulePeriod/index.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Schedule Periods{% endblock %} 3 | {% block javascripts %} 4 | 9 | {% endblock %} 10 | {% block modulecontent %} 11 |
    12 |

    Schedule Periods

    13 | Add Schedule Period 14 |
    15 | {% if entities is empty %} 16 |
    17 | Sorry! No schedule periods found. You should create one. 18 |
    19 | {% else %} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | {% for entity in entities %} 30 | 31 | 32 | 33 | 44 | 45 | {% endfor %} 46 | 47 |
    Start DateEnd DateActions
    {{ entity.startTime|date('M-d-Y') }}{{ entity.endTime|date('M-d-Y') }} 34 |
    35 | View 36 | {% if is_granted('ROLE_ADMIN') %} 37 | 38 | 41 | {% endif %} 42 |
    43 |
    48 |
    49 | {{ pagerfanta(paginator, 'twitter_bootstrap') }} 50 |
    51 | {% endif %} 52 |
    53 | {% endblock %} 54 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/SchedulePeriod/new.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - New Schedule Period{% endblock %} 3 | {% block stylesheets %} 4 | {{ parent() }} 5 | 6 | {% endblock %} 7 | {% block javascripts %} 8 | 9 | 13 | {% endblock %} 14 | {% block modulecontent %} 15 |
    16 | 20 |

    Create a New Schedule Period

    21 |
    22 | {{ form_errors(form) }} 23 | {{ form_label(form.startTime) }} 24 |
    25 | {{ form_widget(form.startTime) }} 26 | 27 |
    28 | {{ form_label(form.endTime) }} 29 |
    30 | {{ form_widget(form.endTime) }} 31 | 32 |
    33 | {{ form_rest(form) }} 34 |
    35 | 36 | Back to Schedule Periods 37 |
    38 |
    39 |
    40 | {% endblock %} 41 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Security/login.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {{ app_brand_name() }} - Login 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
    17 | {% if error %} 18 |
    19 | Error: {{ error.message }} 20 |
    21 | {% endif %} 22 | 23 | 36 |
    37 |
    38 |
    39 |

    Powered by OpenSkedge

    40 |

    Copyright © 2012-{{ "now"|date("Y") }} OpenSkedge contributors

    41 |

    Licensed under the GNU GPL version 3

    42 |
    43 |
    44 | 45 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Settings/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block stylesheets %} 3 | {{ parent() }} 4 | 5 | {% endblock %} 6 | {% block javascripts %} 7 | {{ parent() }} 8 | 9 | 13 | {% endblock %} 14 | {% block modulecontent %} 15 |
    16 |

    {{ app_brand_name() }} Settings

    17 |
    18 |
    19 | {{ form_errors(edit_form) }} 20 | 21 | {{ form_row(edit_form.brandName) }} 22 | {{ form_label(edit_form.pruneAfter) }} 23 |
    24 | {{ form_widget(edit_form.pruneAfter) }} 25 | weeks 26 |
    27 | {{ form_row(edit_form.weekStartDay) }} 28 | {{ form_row(edit_form.weekStartDayClock) }} 29 | {{ form_row(edit_form.defaultTimeResolution) }} 30 | {{ form_label(edit_form.startHour) }} 31 |
    32 | {{ form_widget(edit_form.startHour) }} 33 | 34 |
    35 | {{ form_label(edit_form.endHour) }} 36 |
    37 | {{ form_widget(edit_form.endHour) }} 38 | 39 |
    40 | {{ form_rest(edit_form) }} 41 | 42 |
    43 | 44 |
    45 |
    46 |
    47 | {% endblock %} 48 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Shift/past.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - My Past Shifts{% endblock %} 3 | {% block javascripts %} 4 | 9 | {% endblock %} 10 | {% block modulecontent %} 11 | 20 | {% if entities is empty %} 21 |
    22 | Sorry! You've not picked up any shifts. 23 |
    24 | {% else %} 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | {% for entity in entities %} 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | {% endfor %} 47 | 48 |
    PositionShift StartShift EndStatusPosted ByActions
    {{ entity.position.area.name }} - {{ entity.position.name }}{{ entity.startTime|date('Y-m-d h:i A') }}{{ entity.endTime|date('Y-m-d h:i A') }}{{ entity.status|capitalize }}{{ entity.user.name }}
    on {{ entity.creationTime|date('Y-m-d h:i A') }}
    Details
    49 |
    50 | {{ pagerfanta(paginator, 'twitter_bootstrap') }} 51 |
    52 | {% endif %} 53 | {% endblock %} 54 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/Shift/view.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - {{ entity.position }} - {{ entity.startTime|date('Y-m-d g:i A') }}-{{ entity.endTime|date('Y-m-d g:i A') }}{% endblock %} 3 | {% block modulecontent %} 4 |
    5 | 10 |

    {{ entity.position }}

    11 |

    {{ entity.startTime|date('M d, Y') }}

    12 |
    {{ entity.startTime|date('g:i A') }} to {{ entity.endTime|date('g:i A') }}
    13 |
    Status: 14 | {% if entity.status == 'approved' %} 15 | {% elseif entity.status == 'unapproved' %} 16 | {% else %}{% endif %}{{ entity.status|capitalize }} 17 |
    18 | {% if is_granted('ROLE_ADMIN') or (entity.user.id == app.user.id and entity.pickedUpBy == null) %} 19 |
    20 |
    21 | Edit 22 | {{ form_widget(delete_form) }} 23 | 24 |
    25 |
    26 | {% endif %} 27 |
    28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | {% if entity.pickedUpBy %} 39 | 40 | 41 | 42 | 43 | {% endif %} 44 | 45 | 46 | 47 | 48 | 49 |
    Posted{{ entity.creationTime|date('Y-m-d g:i A') }}
    Posted By{{ entity.user.name }}
    Picked Up By{{ entity.pickedUpBy.name }}
    Notes{{ entity.notes }}
    50 |
    51 | {% endblock %} 52 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/User/edit.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block stylesheets %} 3 | {{ parent() }} 4 | 5 | {% endblock %} 6 | {% block javascripts %} 7 | {{ parent() }} 8 | 9 | 10 | {% endblock %} 11 | {% block modulecontent %} 12 |
    13 |

    {{ entity.name }}

    14 |
    15 | {% if app.user.id != entity.id and delete_form is defined %} 16 |
    17 | {{ form_widget(delete_form) }} 18 | 19 |
    20 | {% endif %} 21 |
    22 |
    23 |
    24 | {{ form_errors(edit_form) }} 25 | 26 | {{ form_row(edit_form.username) }} 27 | {{ form_row(edit_form.password) }} 28 | {{ form_row(edit_form.name) }} 29 | {{ form_row(edit_form.workphone) }} 30 | {{ form_row(edit_form.homephone) }} 31 | {{ form_row(edit_form.location) }} 32 | {{ form_row(edit_form.email) }} 33 | {% if entity.id != app.user.id %} 34 | {{ form_row(edit_form.min) }} 35 | {{ form_row(edit_form.max) }} 36 | {% endif %} 37 | {{ form_row(edit_form.hours) }} 38 | {{ form_row(edit_form.notes) }} 39 | {% if is_granted('ROLE_ADMIN') %} 40 | {{ form_label(edit_form.color) }} 41 |
    42 | {{ form_widget(edit_form.color) }} 43 | 44 |
    45 | {% if entity.id != app.user.id %} 46 | {{ form_row(edit_form.supnotes) }} 47 | {{ form_row(edit_form.group) }} 48 | {{ form_row(edit_form.supervisors) }} 49 | 52 | {% endif %} 53 | {% endif %} 54 | 55 | {{ form_rest(edit_form) }} 56 |
    57 | 58 | Back 59 |
    60 |
    61 |
    62 | {% endblock %} 63 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/User/new.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block stylesheets %} 3 | {{ parent() }} 4 | 5 | {% endblock %} 6 | {% block javascripts %} 7 | {{ parent() }} 8 | 9 | 10 | {% endblock %} 11 | {% block modulecontent %} 12 |
    13 |

    Create a New User

    14 |
    15 | {% include 'OpenSkedgeBundle:User:new_form_fields.html.twig' %} 16 |
    17 | 18 | Back to Users 19 |
    20 |
    21 |
    22 | {% endblock %} 23 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/User/new_form_fields.html.twig: -------------------------------------------------------------------------------- 1 | {{ form_errors(form) }} 2 | 3 | {{ form_row(form.username) }} 4 | {{ form_row(form.password) }} 5 | {{ form_row(form.name) }} 6 | {{ form_row(form.email) }} 7 | 8 |
    9 | Min: {{ form_widget(form.min, { 'attr': { 'class': 'input-mini' } }) }} 10 | Max: {{ form_widget(form.max, { 'attr': { 'class': 'input-mini' } }) }} 11 | Desired: {{ form_widget(form.hours, { 'attr': { 'class': 'input-mini' } }) }} 12 |
    13 | {{ form_label(form.color) }} 14 |
    15 | {{ form_widget(form.color) }} 16 | 17 |
    18 | {{ form_row(form.supnotes) }} 19 | {{ form_row(form.group) }} 20 | {{ form_row(form.supervisors) }} 21 | 24 | {{ form_row(form._token) }} 25 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/base.html.twig: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | {% block title %}{{ app_brand_name() }} - {{ get_controller_name()|capitalize }} {% if get_action_name() != 'index' and get_action_name() != 'view' %}- {{ get_action_name()|capitalize }}{% endif %}{% endblock %} 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | {% spaceless %}{% block stylesheets %}{% endblock %}{% endspaceless %} 16 | 17 | 18 | {% block content %}{% endblock %} 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | {% spaceless %}{% block javascripts %}{% endblock %}{% endspaceless %} 30 |
    31 |
    32 |

    Powered by OpenSkedge · Copyright © 2012-{{ "now"|date("Y") }} OpenSkedge contributors · Licensed under the GNU GPL version 3 · Report a bug {% if deploy_commit != null %}commit {{ deploy_commit }}{% endif %}

    33 |
    34 |
    35 | 36 | 37 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Resources/views/error.html.twig: -------------------------------------------------------------------------------- 1 | {% extends 'OpenSkedgeBundle:Dashboard:index.html.twig' %} 2 | {% block title %}{{ app_brand_name() }} - Error - {{ error.title }}{% endblock %} 3 | {% block modulecontent %} 4 |
    5 |

    {{ action }}

    6 |
    7 |
    8 | Error! {{ error.msg }} 9 |
    10 |
    11 | {% endblock %} 12 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Services/AppSettingsService.php: -------------------------------------------------------------------------------- 1 | em = $em; 14 | } 15 | 16 | public function getAppSettings() 17 | { 18 | // Grab the settings row from os_settings 19 | $appSettings = $this->em->getRepository('OpenSkedgeBundle:Settings')->find(1); 20 | if (!$appSettings instanceof \OpenSkedge\AppBundle\Entity\Settings) { 21 | throw new \Exception('OpenSkedge settings could not be found'); 22 | } 23 | return $appSettings; 24 | } 25 | 26 | public function getAllowedClockIps() 27 | { 28 | $ipObjs = $this->em->getRepository('OpenSkedgeBundle:IP')->findBy(array('clockEnabled'=> true)); 29 | $ips = array(); 30 | foreach ($ipObjs as $ipObj) { 31 | $ips[] = $ipObj->getIp(); 32 | } 33 | return $ips; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Tests/Entity/AreaTest.php: -------------------------------------------------------------------------------- 1 | 13 | * @license GNU General Public License, version 3 14 | * @version GIT: $Id$ 15 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 16 | */ 17 | class AreaTest extends \PHPUnit_Framework_TestCase 18 | { 19 | /** 20 | * Run a test to ensure instantiation of Area objects is working. 21 | * 22 | * @return void 23 | */ 24 | public function testInstantiation() 25 | { 26 | $area = new Area(); 27 | 28 | $this->assertInstanceOf('\OpenSkedge\AppBundle\Entity\Area', $area); 29 | } 30 | 31 | /** 32 | * Run tests to ensure the output is correct for set/getName 33 | * 34 | * @return void 35 | */ 36 | public function testName() 37 | { 38 | $area = new Area(); 39 | 40 | $area->setName("Test Area"); 41 | $this->assertEquals("Test Area", $area->getName()); 42 | } 43 | 44 | /** 45 | * Run tests to ensure the output is correct for set/getDescription 46 | * 47 | * @return void 48 | */ 49 | public function testDescription() 50 | { 51 | $area = new Area(); 52 | 53 | $area->setDescription("DAS IST EIN TEST AREA"); 54 | $this->assertEquals("DAS IST EIN TEST AREA", $area->getDescription()); 55 | } 56 | 57 | /** 58 | * Run tests to ensure the output is correct for add/remove/getPosition(s) 59 | * 60 | * @return void 61 | */ 62 | public function testPosition() 63 | { 64 | $testPosition = $this->getMock('\OpenSkedge\AppBundle\Entity\Position'); 65 | 66 | $area = new Area(); 67 | $area->addPosition($testPosition); 68 | 69 | $positions = $area->getPositions(); 70 | $this->assertInstanceOf('\OpenSkedge\AppBundle\Entity\Position', $positions[0]); 71 | 72 | $area->removePosition($testPosition); 73 | $this->assertTrue($area->getPositions()->isEmpty()); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Tests/Entity/GroupTest.php: -------------------------------------------------------------------------------- 1 | 13 | * @license GNU General Public License, version 3 14 | * @version GIT: $Id$ 15 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 16 | */ 17 | class GroupTest extends \PHPUnit_Framework_TestCase 18 | { 19 | /** 20 | * Run a test to ensure instantiation of Group objects is working. 21 | * 22 | * @return void 23 | */ 24 | public function testInstantiation() 25 | { 26 | $group = new Group(); 27 | $this->assertInstanceOf('\OpenSkedge\AppBundle\Entity\Group', $group); 28 | } 29 | 30 | /** 31 | * Run tests to ensure the output is correct for set/getName 32 | * 33 | * @return void 34 | */ 35 | public function testName() 36 | { 37 | $group = new Group(); 38 | 39 | $group->setName("Test Group"); 40 | $this->assertEquals("Test Group", $group->getName()); 41 | } 42 | 43 | /** 44 | * Run tests to ensure the output is correct for set/getRole 45 | * 46 | * @return void 47 | */ 48 | public function testRole() 49 | { 50 | $group = new Group(); 51 | 52 | $group->setRole("ROLE_TEST"); 53 | $this->assertEquals("ROLE_TEST", $group->getRole()); 54 | } 55 | 56 | /** 57 | * Run tests to ensure the output is correct for add/remove/getPosition(s) 58 | * 59 | * @return void 60 | */ 61 | public function testUser() 62 | { 63 | $testUser = $this->getMock('\OpenSkedge\AppBundle\Entity\User'); 64 | 65 | $group = new Group(); 66 | $group->addUser($testUser); 67 | 68 | $groups = $group->getUsers(); 69 | $this->assertInstanceOf('\OpenSkedge\AppBundle\Entity\User', $groups[0]); 70 | 71 | $group->removeUser($testUser); 72 | $this->assertTrue($group->getUsers()->isEmpty()); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Tests/Entity/IPTest.php: -------------------------------------------------------------------------------- 1 | 13 | * @license GNU General Public License, version 3 14 | * @version GIT: $Id$ 15 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 16 | */ 17 | class IPTest extends \PHPUnit_Framework_TestCase 18 | { 19 | /** 20 | * Run a test to ensure instantiation of IP objects is working. 21 | * 22 | * @return void 23 | */ 24 | public function testInstantiation() 25 | { 26 | $ip = new IP(); 27 | 28 | $this->assertInstanceOf('\OpenSkedge\AppBundle\Entity\IP', $ip); 29 | } 30 | 31 | /** 32 | * Run tests to ensure the output is correct for set/getIP 33 | * 34 | * @return void 35 | */ 36 | public function testIP() 37 | { 38 | $ip = new IP(); 39 | 40 | $ip->setIP("127.0.0.1"); 41 | $this->assertEquals("127.0.0.1", $ip->getIP()); 42 | } 43 | 44 | /** 45 | * Run tests to ensure the output is correct for set/getName 46 | * 47 | * @return void 48 | */ 49 | public function testName() 50 | { 51 | $ip = new IP(); 52 | 53 | $ip->setName("Localhost"); 54 | $this->assertEquals("Localhost", $ip->getName()); 55 | } 56 | 57 | /** 58 | * Run tests to ensure the output is correct for is/setClockEnabled 59 | * 60 | * @return void 61 | */ 62 | public function testClockEnabled() 63 | { 64 | $ip = new IP(); 65 | 66 | $ip->setClockEnabled(true); 67 | $this->assertTrue($ip->isClockEnabled()); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Tests/Twig/Extension/SettingsExtensionTest.php: -------------------------------------------------------------------------------- 1 | 13 | * @license GNU General Public License, version 3 14 | * @version GIT: $Id$ 15 | * @link https://github.com/maxfierke/OpenSkedge OpenSkedge Github 16 | */ 17 | class SettingsExtensionTest extends \PHPUnit_Framework_TestCase 18 | { 19 | /* 20 | * @var SettingsExtension 21 | */ 22 | protected $settingsExt; 23 | 24 | /** 25 | * Setup a DateTimeUtils object for the tests with various mocks. 26 | * 27 | * @return void 28 | */ 29 | public function setUp() 30 | { 31 | $appSettings = $this->getMock('\OpenSkedge\AppBundle\Entity\Settings'); 32 | $appSettings->expects($this->any())->method('getStartHour')->will($this->returnValue('07:00 AM')); 33 | $appSettings->expects($this->any())->method('getEndHour')->will($this->returnValue('10:00 PM')); 34 | $appSettings->expects($this->any())->method('getBrandName')->will($this->returnValue('OpenSkedge')); 35 | $appSettings->expects($this->any())->method('getDefaultTimeResolution')->will($this->returnValue('15 mins')); 36 | 37 | $em = $this->getMock('\Doctrine\Common\Persistence\ObjectManager'); 38 | $appSettingsService = $this->getMock('\OpenSkedge\AppBundle\Services\AppSettingsService', array(), array($em)); 39 | $appSettingsService->expects($this->any())->method('getAppSettings')->will($this->returnValue($appSettings)); 40 | 41 | $this->settingsExt = new SettingsExtension($appSettingsService); 42 | } 43 | 44 | public function testInstantiation() 45 | { 46 | $this->assertInstanceOf('\OpenSkedge\AppBundle\Twig\Extension\SettingsExtension', $this->settingsExt); 47 | } 48 | 49 | public function testFunctions() 50 | { 51 | $funcs = $this->settingsExt->getFunctions(); 52 | 53 | foreach($funcs as $func) { 54 | $this->assertInstanceOf('\Twig_Function_Method', $func); 55 | } 56 | } 57 | 58 | public function testBrandName() 59 | { 60 | $this->assertEquals('OpenSkedge', $this->settingsExt->getBrandName()); 61 | } 62 | 63 | public function testStartHour() 64 | { 65 | $this->assertEquals('07:00 AM', $this->settingsExt->getStartHour()); 66 | } 67 | 68 | public function testEndHour() 69 | { 70 | $this->assertEquals('10:00 PM', $this->settingsExt->getEndHour()); 71 | } 72 | 73 | public function testTimeResolution() 74 | { 75 | $this->assertEquals('15 mins', $this->settingsExt->getTimeResolution()); 76 | } 77 | 78 | public function testName() 79 | { 80 | $this->assertEquals('app_settings', $this->settingsExt->getName()); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Twig/Extension/PageExtension.php: -------------------------------------------------------------------------------- 1 | request = $request; 21 | } 22 | 23 | public function initRuntime(\Twig_Environment $environment) 24 | { 25 | $this->environment = $environment; 26 | } 27 | 28 | public function getFunctions() 29 | { 30 | return array( 31 | 'get_controller_name' => new \Twig_Function_Method($this, 'getControllerName'), 32 | 'get_action_name' => new \Twig_Function_Method($this, 'getActionName'), 33 | ); 34 | } 35 | 36 | /** 37 | * Get current controller name 38 | */ 39 | public function getControllerName() 40 | { 41 | $pattern = "#Controller\\\([a-zA-Z]*)Controller#"; 42 | $matches = array(); 43 | preg_match($pattern, $this->request->get('_controller'), $matches); 44 | 45 | return strtolower($matches[1]); 46 | } 47 | 48 | /** 49 | * Get current action name 50 | */ 51 | public function getActionName() 52 | { 53 | $pattern = "#::([a-zA-Z]*)Action#"; 54 | $matches = array(); 55 | preg_match($pattern, $this->request->get('_controller'), $matches); 56 | 57 | return $matches[1]; 58 | } 59 | 60 | public function getName() 61 | { 62 | return 'page'; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/OpenSkedge/AppBundle/Twig/Extension/SettingsExtension.php: -------------------------------------------------------------------------------- 1 | appSettings = $appSettingsService->getAppSettings(); 25 | } 26 | 27 | public function initRuntime(\Twig_Environment $environment) 28 | { 29 | $this->environment = $environment; 30 | } 31 | 32 | public function getFunctions() 33 | { 34 | return array( 35 | 'app_brand_name' => new \Twig_Function_Method($this, 'getBrandName'), 36 | 'start_time' => new \Twig_Function_Method($this, 'getStartHour'), 37 | 'end_time' => new \Twig_Function_Method($this, 'getEndHour'), 38 | 'default_time_res' => new \Twig_Function_Method($this, 'getTimeResolution'), 39 | ); 40 | } 41 | 42 | public function getBrandName() 43 | { 44 | return $this->appSettings->getBrandName(); 45 | } 46 | 47 | public function getTimeResolution() 48 | { 49 | return $this->appSettings->getDefaultTimeResolution(); 50 | } 51 | 52 | public function getStartHour() 53 | { 54 | return $this->appSettings->getStartHour(); 55 | } 56 | 57 | public function getEndHour() 58 | { 59 | return $this->appSettings->getEndHour(); 60 | } 61 | 62 | public function getName() 63 | { 64 | return 'app_settings'; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /web/.htaccess: -------------------------------------------------------------------------------- 1 | # Use the front controller as index file. It serves as fallback solution when 2 | # every other rewrite/redirect fails (e.g. in an aliased environment without 3 | # mod_rewrite). Additionally, this reduces the matching process for the 4 | # startpage (path "/") because otherwise Apache will apply the rewritting rules 5 | # to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl). 6 | DirectoryIndex app.php 7 | 8 | 9 | RewriteEngine On 10 | 11 | # Redirect to URI without front controller to prevent duplicate content 12 | # (with and without `/app.php`). Only do this redirect on the initial 13 | # rewrite by Apache and not on subsequent cycles. Otherwise we would get an 14 | # endless redirect loop (request -> rewrite to front controller -> 15 | # redirect -> request -> ...). 16 | # So in case you get a "too many redirects" error or you always get redirected 17 | # to the startpage because your Apache does not expose the REDIRECT_STATUS 18 | # environment variable, you have 2 choices: 19 | # - disable this feature by commenting the following 2 lines or 20 | # - use Apache >= 2.3.9 and replace all L flags by END flags and remove the 21 | # following RewriteCond (best solution) 22 | RewriteCond %{ENV:REDIRECT_STATUS} ^$ 23 | RewriteRule ^app\.php(/(.*)|$) %{CONTEXT_PREFIX}/$2 [R=301,L] 24 | 25 | # If the requested filename exists, simply serve it. 26 | # We only want to let Apache serve files and not directories. 27 | RewriteCond %{REQUEST_FILENAME} -f 28 | RewriteRule .? - [L] 29 | 30 | # The following rewrites all other queries to the front controller. The 31 | # condition ensures that if you are using Apache aliases to do mass virtual 32 | # hosting, the base path will be prepended to allow proper resolution of the 33 | # app.php file; it will work in non-aliased environments as well, providing 34 | # a safe, one-size fits all solution. 35 | RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ 36 | RewriteRule ^(.*) - [E=BASE:%1] 37 | RewriteRule .? %{ENV:BASE}app.php [L] 38 | 39 | 40 | 41 | 42 | # When mod_rewrite is not available, we instruct a temporary redirect of 43 | # the startpage to the front controller explicitly so that the website 44 | # and the generated links can still be used. 45 | RedirectMatch 302 ^/$ /app.php/ 46 | # RedirectTemp cannot be used instead 47 | 48 | 49 | -------------------------------------------------------------------------------- /web/app.php: -------------------------------------------------------------------------------- 1 | register(true); 12 | } 13 | 14 | require_once __DIR__.'/../app/AppKernel.php'; 15 | //require_once __DIR__.'/../app/AppCache.php'; 16 | 17 | $kernel = new AppKernel('prod', false); 18 | $kernel->loadClassCache(); 19 | //$kernel = new AppCache($kernel); 20 | $request = Request::createFromGlobals(); 21 | $response = $kernel->handle($request); 22 | $response->send(); 23 | $kernel->terminate($request, $response); 24 | -------------------------------------------------------------------------------- /web/app_dev.php: -------------------------------------------------------------------------------- 1 | loadClassCache(); 24 | $request = Request::createFromGlobals(); 25 | $response = $kernel->handle($request); 26 | $response->send(); 27 | $kernel->terminate($request, $response); 28 | -------------------------------------------------------------------------------- /web/css/colorpicker.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | Colorpicker for Bootstrap 3 | Copyright 2012 Stefan Petre 4 | Licensed under the Apache License v2.0 5 | http://www.apache.org/licenses/LICENSE-2.0 6 | */ 7 | .colorpicker-saturation{width:100px;height:100px;background-image:url(/img/saturation.png);cursor:crosshair;float:left}.colorpicker-saturation i{display:block;height:5px;width:5px;border:1px solid #000;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;position:absolute;top:0;left:0;margin:-4px 0 0 -4px}.colorpicker-saturation i b{display:block;height:5px;width:5px;border:1px solid #fff;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.colorpicker-hue,.colorpicker-alpha{width:15px;height:100px;float:left;cursor:row-resize;margin-left:4px;margin-bottom:4px}.colorpicker-hue i,.colorpicker-alpha i{display:block;height:1px;background:#000;border-top:1px solid #fff;position:absolute;top:0;left:0;width:100%;margin-top:-1px}.colorpicker-hue{background-image:url(/img/hue.png)}.colorpicker-alpha{background-image:url(/img/alpha.png);display:none}.colorpicker{*zoom:1;top:0;left:0;padding:4px;min-width:120px;margin-top:1px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.colorpicker:before,.colorpicker:after{display:table;content:""}.colorpicker:after{clear:both}.colorpicker:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0,0,0,0.2);position:absolute;top:-7px;left:6px}.colorpicker:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;top:-6px;left:7px}.colorpicker div{position:relative}.colorpicker.alpha{min-width:140px}.colorpicker.alpha .colorpicker-alpha{display:block}.colorpicker-color{height:10px;margin-top:5px;clear:both;background-image:url(/img/alpha.png);background-position:0 100%}.colorpicker-color div{height:10px}.input-append.color .add-on i,.input-prepend.color .add-on i{display:block;cursor:pointer;width:16px;height:16px} 8 | -------------------------------------------------------------------------------- /web/css/login.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 40px; 3 | padding-bottom: 40px; 4 | background-color: #f5f5f5; 5 | background-image: url('../img/bg.png'); 6 | } 7 | .container { 8 | max-width: 400px; 9 | margin: 0 auto 20px; 10 | } 11 | .form-signin { 12 | padding: 19px 29px 29px; 13 | background-color: #fff; 14 | border: 1px solid #e5e5e5; 15 | -webkit-border-radius: 5px; 16 | -moz-border-radius: 5px; 17 | border-radius: 5px; 18 | -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.05); 19 | -moz-box-shadow: 0 1px 2px rgba(0,0,0,.05); 20 | box-shadow: 0 1px 2px rgba(0,0,0,.05); 21 | text-align: left; 22 | } 23 | .form-signin .form-signin-heading { 24 | margin-bottom: 10px; 25 | } 26 | .form-signin input[type="text"], 27 | .form-signin input[type="password"] { 28 | font-size: 16px; 29 | height: auto; 30 | margin-bottom: 15px; 31 | padding: 7px 9px; 32 | } 33 | p { text-align: center; } 34 | .muted { color: #777; } 35 | 36 | .branding-logo-login { 37 | margin: 0 auto; 38 | } 39 | -------------------------------------------------------------------------------- /web/css/timepicker.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Timepicker Component for Twitter Bootstrap 3 | * 4 | * Copyright 2013 Joris de Wit 5 | * 6 | * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors 7 | * 8 | * For the full copyright and license information, please view the LICENSE 9 | * file that was distributed with this source code. 10 | */.bootstrap-timepicker{position:relative}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu{left:auto;right:0}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:before{left:auto;right:12px}.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:after{left:auto;right:13px}.bootstrap-timepicker .add-on{cursor:pointer}.bootstrap-timepicker .add-on i{display:inline-block;width:16px;height:16px}.bootstrap-timepicker-widget.dropdown-menu{padding:2px 3px 2px 2px}.bootstrap-timepicker-widget.dropdown-menu.open{display:inline-block}.bootstrap-timepicker-widget.dropdown-menu:before{border-bottom:7px solid rgba(0,0,0,0.2);border-left:7px solid transparent;border-right:7px solid transparent;content:"";display:inline-block;left:9px;position:absolute;top:-7px}.bootstrap-timepicker-widget.dropdown-menu:after{border-bottom:6px solid #fff;border-left:6px solid transparent;border-right:6px solid transparent;content:"";display:inline-block;left:10px;position:absolute;top:-6px}.bootstrap-timepicker-widget a.btn,.bootstrap-timepicker-widget input{border-radius:4px}.bootstrap-timepicker-widget table{width:100%;margin:0}.bootstrap-timepicker-widget table td{text-align:center;height:30px;margin:0;padding:2px}.bootstrap-timepicker-widget table td:not(.separator){min-width:30px}.bootstrap-timepicker-widget table td span{width:100%}.bootstrap-timepicker-widget table td a{border:1px transparent solid;width:100%;display:inline-block;margin:0;padding:8px 0;outline:0;color:#333}.bootstrap-timepicker-widget table td a:hover{text-decoration:none;background-color:#eee;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;border-color:#ddd}.bootstrap-timepicker-widget table td a i{margin-top:2px}.bootstrap-timepicker-widget table td input{width:25px;margin:0;text-align:center}.bootstrap-timepicker-widget .modal-content{padding:4px}@media(min-width:767px){.bootstrap-timepicker-widget.modal{width:200px;margin-left:-100px}}@media(max-width:767px){.bootstrap-timepicker{width:100%}.bootstrap-timepicker .dropdown-menu{width:100%}} -------------------------------------------------------------------------------- /web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/favicon.ico -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/favicon.png -------------------------------------------------------------------------------- /web/img/alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/alpha.png -------------------------------------------------------------------------------- /web/img/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/bg.png -------------------------------------------------------------------------------- /web/img/branding_logo_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/branding_logo_large.png -------------------------------------------------------------------------------- /web/img/branding_logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/branding_logo_small.png -------------------------------------------------------------------------------- /web/img/checkmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/checkmark.png -------------------------------------------------------------------------------- /web/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /web/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /web/img/hue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/hue.png -------------------------------------------------------------------------------- /web/img/navbar_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/navbar_bg.png -------------------------------------------------------------------------------- /web/img/openskedge_logo_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/openskedge_logo_blue.png -------------------------------------------------------------------------------- /web/img/saturation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/saturation.png -------------------------------------------------------------------------------- /web/img/select2-spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/select2-spinner.gif -------------------------------------------------------------------------------- /web/img/select2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/select2.png -------------------------------------------------------------------------------- /web/img/select2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/select2x2.png -------------------------------------------------------------------------------- /web/img/well_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OfficeStack/OpenSkedge/7560970a6e7cb7ae63ecc6ec11fdb1adc6c10b70/web/img/well_bg.png -------------------------------------------------------------------------------- /web/js/application.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | $('select').each(function() { 3 | $(this).select2({ minimumResultsForSearch: 6 }); 4 | }); 5 | $.tablesorter.themes.oskedge = {icons: '',sortNone: 'bootstrap-icon-unsorted',sortAsc: 'icon-chevron-up',sortDesc : 'icon-chevron-down'}; 6 | }); 7 | 8 | -------------------------------------------------------------------------------- /web/js/jquery.tickingclock.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery Ticking Clock by Max Fierke 3 | * Part of OpenSkedge (https://github.com/maxfierke/OpenSkedge) 4 | * Licensed under the GNU General Public License, version 3 or later. 5 | */ 6 | (function($) { 7 | $.fn.tickingClock = function(theDate) { 8 | var currentTime = new Date(theDate); 9 | update = function () { 10 | var seconds = currentTime.getSeconds(); 11 | currentTime.setSeconds(seconds + 1); 12 | var hours = currentTime.getHours(); 13 | var meridian; 14 | var minutes = currentTime.getMinutes(); 15 | seconds = currentTime.getSeconds(); 16 | if (seconds < 10) seconds = "0" + seconds; 17 | if (minutes < 10) minutes = "0" + minutes; 18 | if (hours > 11) meridian = "PM"; 19 | else meridian = "AM"; 20 | hours = hours % 12; 21 | if (hours === 0) hours = 12; 22 | $("#clockTime").html(hours + ":" + minutes + ":" + seconds + " " + meridian); 23 | }; 24 | update(); 25 | return this.each(function () { 26 | setInterval(update, 1000); 27 | }); 28 | }; 29 | })(jQuery); 30 | -------------------------------------------------------------------------------- /web/robots.txt: -------------------------------------------------------------------------------- 1 | # www.robotstxt.org/ 2 | # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 3 | 4 | User-agent: * 5 | --------------------------------------------------------------------------------