diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b5bdba41..c15a59db 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -29,15 +29,14 @@ before_script: - &before_install_xdebug |- pecl install xdebug docker-php-ext-enable xdebug - # MySQL DB - - &before_setup_mysql |- - apt install -yqq mariadb-client - mysql -h "$MYSQL_HOST" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" < db/install.sql - mysql -h "$MYSQL_HOST" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" < db/update.sql # Install Composer - &before_install_composer |- curl -sS https://getcomposer.org/installer | php -- --no-ansi --install-dir /usr/local/bin/ --filename composer composer --no-ansi install + # MySQL DB + - &before_setup_mysql |- + chmod +x ./bin/migrate + ./bin/migrate # Install Node.js and Yarn - &before_install_yarn |- apt -yqq install gnupg2 apt-transport-https @@ -86,7 +85,7 @@ test:7.1: # Install project and dependencies - &deployment_dependencies |- - chmod +x ./deploy.sh + chmod +x ./bin/deploy.sh apt update && apt install -yqq rsync openssh-client composer --no-ansi install --no-dev composer --no-ansi dump-autoload --optimize @@ -116,7 +115,7 @@ deploy_staging: - *deployment_ssh - *deployment_dependencies # Deploy to server - - ./deploy.sh -r "${STAGING_REMOTE}" -p "${STAGING_REMOTE_PATH}" -i "${CI_JOB_ID}-${CI_COMMIT_SHA}" + - ./bin/deploy.sh -r "${STAGING_REMOTE}" -p "${STAGING_REMOTE_PATH}" -i "${CI_JOB_ID}-${CI_COMMIT_SHA}" deploy_production: <<: *deploy_definition @@ -133,4 +132,4 @@ deploy_production: - *deployment_ssh - *deployment_dependencies # Deploy to server - - ./deploy.sh -r "${PRODUCTION_REMOTE}" -p "${PRODUCTION_REMOTE_PATH}" -i "${CI_JOB_ID}-${CI_COMMIT_SHA}" + - ./bin/deploy.sh -r "${PRODUCTION_REMOTE}" -p "${PRODUCTION_REMOTE_PATH}" -i "${CI_JOB_ID}-${CI_COMMIT_SHA}" diff --git a/README.md b/README.md index cd00d927..960d6b6d 100644 --- a/README.md +++ b/README.md @@ -41,8 +41,8 @@ To report bugs use [engelsystem/issues](https://github.com/engelsystem/engelsyst * Recommended: Directory Listing should be disabled. * There must a be MySQL database created with a user who has full rights to that database. - * It must be created by the ```db/install.sql``` and ```db/update.sql``` files. * If necessary, create a ```config/config.php``` to override values from ```config/config.default.php```. + * To import the database the ```bin/migrate``` script has to be called. * In the browser, login with credentials ```admin```:```asdfasdf``` and change the password. Engelsystem can now be used. @@ -103,10 +103,16 @@ docker exec -i db_container mysql -u engelsystem -pengelsystem engelsystem < db/ To be able to send mails a relay is needed. Set `SMTPHOST=[mail container]` to configure it. -#### deploy.sh -The `deploy.sh` script can be used to deploy the engelsystem. It uses rsync to deploy the application to a server over ssh. +#### Scripts +##### bin/deploy.sh +The `bin/deploy.sh` script can be used to deploy the engelsystem. It uses rsync to deploy the application to a server over ssh. -For usage see `./deploy.sh -h` +For usage see `./bin/deploy.sh -h` + +##### bin/migrate +The `bin/migrate` script can be used to import and update the database of the engelsystem. + +For more information on how to use it call `bin/migrate help` ### Codestyle Please ensure that your pull requests follow [PSR-2](http://www.php-fig.org/psr/psr-2/) and [PSR-4](http://www.php-fig.org/psr/psr-4/). diff --git a/deploy.sh b/bin/deploy.sh similarity index 100% rename from deploy.sh rename to bin/deploy.sh diff --git a/bin/migrate b/bin/migrate new file mode 100755 index 00000000..ab3598d4 --- /dev/null +++ b/bin/migrate @@ -0,0 +1,38 @@ +#!/usr/bin/env php +register(MigrationServiceProvider::class); + +/** @var Migrate $migration */ +$migration = $app->get('db.migration'); +$migration->setOutput(function ($text) { echo $text . PHP_EOL; }); + +if (isset($argv[1]) && strtolower($argv[1]) == 'help') { + echo PHP_EOL . 'Usage: ' . $argv[1] . ' [up|down] [one-step]' . PHP_EOL . PHP_EOL; + exit; +} + +$method = Migrate::UP; +if (isset($argv[1]) && strtolower($argv[1]) == 'down') { + $argv = array_values($argv); + $method = Migrate::DOWN; +} + +$oneStep = false; +if (isset($argv[2]) && strtolower($argv[2]) == 'one-step') { + $oneStep = true; +} + +$migration->run($baseDir, $method, $oneStep); diff --git a/composer.json b/composer.json index 0d599564..6716721d 100644 --- a/composer.json +++ b/composer.json @@ -17,6 +17,8 @@ "php": ">=7.0.0", "erusev/parsedown": "^1.6", "illuminate/container": "5.5.*", + "illuminate/database": "5.5.*", + "illuminate/support": "^5.5", "psr/container": "^1.0", "psr/log": "^1.0", "symfony/http-foundation": "^3.3" diff --git a/config/config.default.php b/config/config.default.php index 3299b07f..a0764bcc 100644 --- a/config/config.default.php +++ b/config/config.default.php @@ -5,10 +5,10 @@ return [ // MySQL-Connection Settings 'database' => [ - 'host' => env('MYSQL_HOST', (env('CI', false) ? 'mariadb' : 'localhost')), - 'user' => env('MYSQL_USER', 'root'), - 'pw' => env('MYSQL_PASSWORD', ''), - 'db' => env('MYSQL_DATABASE', 'engelsystem'), + 'host' => env('MYSQL_HOST', (env('CI', false) ? 'mariadb' : 'localhost')), + 'database' => env('MYSQL_DATABASE', 'engelsystem'), + 'username' => env('MYSQL_USER', 'root'), + 'password' => env('MYSQL_PASSWORD', ''), ], // For accessing stats diff --git a/db/migrations/2018_01_01_000001_import_install_sql.php b/db/migrations/2018_01_01_000001_import_install_sql.php new file mode 100644 index 00000000..bd7ec7ae --- /dev/null +++ b/db/migrations/2018_01_01_000001_import_install_sql.php @@ -0,0 +1,59 @@ +oldTables as $table) { + if ($this->schema->hasTable($table)) { + return; + } + } + + $sql = file_get_contents(__DIR__ . '/../install.sql'); + $this->schema->getConnection()->unprepared($sql); + } + + + /** + * Reverse the migration + */ + public + function down() + { + $this->schema->getConnection()->statement('SET FOREIGN_KEY_CHECKS=0;'); + + foreach ($this->oldTables as $table) { + if ($this->schema->hasTable($table)) { + $this->schema->dropIfExists($table); + } + } + } +} diff --git a/db/migrations/2018_01_01_000002_import_update_sql.php b/db/migrations/2018_01_01_000002_import_update_sql.php new file mode 100644 index 00000000..58687d6c --- /dev/null +++ b/db/migrations/2018_01_01_000002_import_update_sql.php @@ -0,0 +1,27 @@ +schema->hasTable('UserWorkLog')) { + return; + } + + $sql = file_get_contents(__DIR__ . '/../update.sql'); + $this->schema->getConnection()->unprepared($sql); + } + + /** + * Reverse the migration + */ + public function down() + { + $this->schema->dropIfExists('UserWorkLog'); + } +} diff --git a/includes/application.php b/includes/application.php new file mode 100644 index 00000000..418dd08d --- /dev/null +++ b/includes/application.php @@ -0,0 +1,37 @@ +make(Config::class); +$appConfig->set(require config_path('app.php')); +$app->bootstrap($appConfig); + + +/** + * Configure application + */ +date_default_timezone_set($app->get('config')->get('timezone')); + +if (config('environment') == 'development') { + $errorHandler = $app->get('error.handler'); + $errorHandler->setEnvironment(Handler::ENV_DEVELOPMENT); + $app->bind(HandlerInterface::class, 'error.handler.development'); + ini_set('display_errors', true); + error_reporting(E_ALL); +} else { + ini_set('display_errors', false); +} diff --git a/includes/autoload.php b/includes/autoload.php index 0cd9d355..f2e90b16 100644 --- a/includes/autoload.php +++ b/includes/autoload.php @@ -2,7 +2,8 @@ // Check for autoloader if (!is_readable(__DIR__ . '/../vendor/autoload.php')) { - die('Please run composer.phar install'); + echo 'Please run composer.phar install'; + exit(1); } // Include composer autoloader diff --git a/includes/controller/angeltypes_controller.php b/includes/controller/angeltypes_controller.php index 399930c2..210b6209 100644 --- a/includes/controller/angeltypes_controller.php +++ b/includes/controller/angeltypes_controller.php @@ -154,7 +154,7 @@ function angeltype_edit_controller() $angeltype['contact_email'] = strip_request_item('contact_email', $angeltype['contact_email']); if ($valid) { - if ($angeltype['id'] != null) { + if (!empty($angeltype['id'])) { AngelType_update($angeltype); } else { $angeltype = AngelType_create($angeltype); @@ -308,7 +308,7 @@ function angeltypes_list_controller() } $angeltype['membership'] = AngelType_render_membership($angeltype); - if ($angeltype['user_angeltype_id'] != null) { + if (!empty($angeltype['user_angeltype_id'])) { $actions[] = button( page_link_to('user_angeltypes', ['action' => 'delete', 'user_angeltype_id' => $angeltype['user_angeltype_id']] @@ -355,7 +355,7 @@ function load_angeltype() } $angeltype = AngelType($request->input('angeltype_id')); - if ($angeltype == null) { + if (empty($angeltype)) { error(_('Angeltype doesn\'t exist . ')); redirect(page_link_to('angeltypes')); } diff --git a/includes/controller/event_config_controller.php b/includes/controller/event_config_controller.php index 4422f046..e64f47fd 100644 --- a/includes/controller/event_config_controller.php +++ b/includes/controller/event_config_controller.php @@ -28,7 +28,7 @@ function event_config_edit_controller() $teardown_end_date = null; $event_config = EventConfig(); - if ($event_config != null) { + if (!empty($event_config)) { $event_name = $event_config['event_name']; $buildup_start_date = $event_config['buildup_start_date']; $event_start_date = $event_config['event_start_date']; @@ -70,22 +70,22 @@ function event_config_edit_controller() $teardown_end_date = $result->getValue(); $valid &= $result->isValid(); - if ($buildup_start_date != null && $event_start_date != null && $buildup_start_date > $event_start_date) { + if (!is_null($buildup_start_date) && !is_null($event_start_date) && $buildup_start_date > $event_start_date) { $valid = false; error(_('The buildup start date has to be before the event start date.')); } - if ($event_start_date != null && $event_end_date != null && $event_start_date > $event_end_date) { + if (!is_null($event_start_date) && !is_null($event_end_date) && $event_start_date > $event_end_date) { $valid = false; error(_('The event start date has to be before the event end date.')); } - if ($event_end_date != null && $teardown_end_date != null && $event_end_date > $teardown_end_date) { + if (!is_null($event_end_date) && !is_null($teardown_end_date) && $event_end_date > $teardown_end_date) { $valid = false; error(_('The event end date has to be before the teardown end date.')); } - if ($buildup_start_date != null && $teardown_end_date != null && $buildup_start_date > $teardown_end_date) { + if (!is_null($buildup_start_date) && !is_null($teardown_end_date) && $buildup_start_date > $teardown_end_date) { $valid = false; error(_('The buildup start date has to be before the teardown end date.')); } diff --git a/includes/controller/rooms_controller.php b/includes/controller/rooms_controller.php index 596cb6d7..f95184f0 100644 --- a/includes/controller/rooms_controller.php +++ b/includes/controller/rooms_controller.php @@ -110,7 +110,7 @@ function load_room() } $room = Room(request()->input('room_id')); - if ($room == null) { + if (empty($room)) { redirect(page_link_to()); } diff --git a/includes/controller/shift_entries_controller.php b/includes/controller/shift_entries_controller.php index ea5e319e..dbed09af 100644 --- a/includes/controller/shift_entries_controller.php +++ b/includes/controller/shift_entries_controller.php @@ -16,7 +16,7 @@ function shift_entries_controller() } $action = strip_request_item('action'); - if ($action == null) { + if (empty($action)) { redirect(user_link($user)); } @@ -43,7 +43,7 @@ function shift_entry_create_controller() } $shift = Shift($request->input('shift_id')); - if ($shift == null) { + if (empty($shift)) { redirect(user_link($user)); } @@ -53,7 +53,7 @@ function shift_entry_create_controller() return shift_entry_create_controller_admin($shift, $angeltype); } - if ($angeltype == null) { + if (empty($angeltype)) { redirect(user_link($user)); } @@ -81,7 +81,7 @@ function shift_entry_create_controller_admin($shift, $angeltype) if ($request->has('user_id')) { $signup_user = User($request->input('user_id')); } - if ($signup_user == null) { + if (empty($signup_user)) { redirect(shift_link($shift)); } @@ -89,7 +89,7 @@ function shift_entry_create_controller_admin($shift, $angeltype) if ($request->has('angeltype_id')) { $angeltype = AngelType($request->input('angeltype_id')); } - if ($angeltype == null) { + if (empty($angeltype)) { if (count($angeltypes) == 0) { redirect(shift_link($shift)); } @@ -321,7 +321,7 @@ function shift_entry_load() redirect(page_link_to('user_shifts')); } $shiftEntry = ShiftEntry($request->input('shift_entry_id')); - if ($shiftEntry == null) { + if (empty($shiftEntry)) { error(_('Shift entry not found.')); redirect(page_link_to('user_shifts')); } diff --git a/includes/controller/shifts_controller.php b/includes/controller/shifts_controller.php index 73a5d29f..7cac5b4a 100644 --- a/includes/controller/shifts_controller.php +++ b/includes/controller/shifts_controller.php @@ -217,7 +217,7 @@ function shift_delete_controller() $shift_id = $request->input('delete_shift'); $shift = Shift($shift_id); - if ($shift == null) { + if (empty($shift)) { redirect(page_link_to('user_shifts')); } @@ -264,7 +264,7 @@ function shift_controller() } $shift = Shift($request->input('shift_id')); - if ($shift == null) { + if (empty($shift)) { error(_('Shift could not be found.')); redirect(page_link_to('user_shifts')); } @@ -277,6 +277,10 @@ function shift_controller() $shift_signup_state = new ShiftSignupState(ShiftSignupState::OCCUPIED, 0); foreach ($angeltypes as &$angeltype) { $needed_angeltype = NeededAngeltype_by_Shift_and_Angeltype($shift, $angeltype); + if(empty($needed_angeltype)) { + continue; + } + $shift_entries = ShiftEntries_by_shift_and_angeltype($shift['SID'], $angeltype['id']); $angeltype_signup_state = Shift_signup_allowed( @@ -288,11 +292,7 @@ function shift_controller() $needed_angeltype, $shift_entries ); - if ($shift_signup_state == null) { - $shift_signup_state = $angeltype_signup_state; - } else { - $shift_signup_state->combineWith($angeltype_signup_state); - } + $shift_signup_state->combineWith($angeltype_signup_state); $angeltype['shift_signup_state'] = $angeltype_signup_state; } @@ -361,7 +361,7 @@ function shifts_json_export_controller() $key = $request->input('key'); $user = User_by_api_key($key); - if ($user == null) { + if (empty($user)) { engelsystem_error('Key invalid.'); } if (!in_array('shifts_json_export', privileges_for_user($user['UID']))) { diff --git a/includes/controller/shifttypes_controller.php b/includes/controller/shifttypes_controller.php index 4e7cd92c..bc9c5c52 100644 --- a/includes/controller/shifttypes_controller.php +++ b/includes/controller/shifttypes_controller.php @@ -22,8 +22,7 @@ function shifttype_delete_controller() } $shifttype = ShiftType($request->input('shifttype_id')); - - if ($shifttype == null) { + if (empty($shifttype)) { redirect(page_link_to('shifttypes')); } @@ -58,7 +57,7 @@ function shifttype_edit_controller() if ($request->has('shifttype_id')) { $shifttype = ShiftType($request->input('shifttype_id')); - if ($shifttype == null) { + if (empty($shifttype)) { error(_('Shifttype not found.')); redirect(page_link_to('shifttypes')); } @@ -120,12 +119,12 @@ function shifttype_controller() redirect(page_link_to('shifttypes')); } $shifttype = ShiftType($request->input('shifttype_id')); - if ($shifttype == null) { + if (empty($shifttype)) { redirect(page_link_to('shifttypes')); } - $angeltype = null; - if ($shifttype['angeltype_id'] != null) { + $angeltype = []; + if (!empty($shifttype['angeltype_id'])) { $angeltype = AngelType($shifttype['angeltype_id']); } diff --git a/includes/controller/user_angeltypes_controller.php b/includes/controller/user_angeltypes_controller.php index 340de2a4..5dae0595 100644 --- a/includes/controller/user_angeltypes_controller.php +++ b/includes/controller/user_angeltypes_controller.php @@ -45,7 +45,7 @@ function user_angeltypes_delete_all_controller() } $angeltype = AngelType($request->input('angeltype_id')); - if ($angeltype == null) { + if (empty($angeltype)) { error(_('Angeltype doesn\'t exist.')); redirect(page_link_to('angeltypes')); } @@ -85,7 +85,7 @@ function user_angeltypes_confirm_all_controller() } $angeltype = AngelType($request->input('angeltype_id')); - if ($angeltype == null) { + if (empty($angeltype)) { error(_('Angeltype doesn\'t exist.')); redirect(page_link_to('angeltypes')); } @@ -125,13 +125,13 @@ function user_angeltype_confirm_controller() } $user_angeltype = UserAngelType($request->input('user_angeltype_id')); - if ($user_angeltype == null) { + if (empty($user_angeltype)) { error(_('User angeltype doesn\'t exist.')); redirect(page_link_to('angeltypes')); } $angeltype = AngelType($user_angeltype['angeltype_id']); - if ($angeltype == null) { + if (empty($angeltype)) { error(_('Angeltype doesn\'t exist.')); redirect(page_link_to('angeltypes')); } @@ -142,7 +142,7 @@ function user_angeltype_confirm_controller() } $user_source = User($user_angeltype['user_id']); - if ($user_source == null) { + if (empty($user_source)) { error(_('User doesn\'t exist.')); redirect(page_link_to('angeltypes')); } @@ -185,19 +185,19 @@ function user_angeltype_delete_controller() } $user_angeltype = UserAngelType($request->input('user_angeltype_id')); - if ($user_angeltype == null) { + if (empty($user_angeltype)) { error(_('User angeltype doesn\'t exist.')); redirect(page_link_to('angeltypes')); } $angeltype = AngelType($user_angeltype['angeltype_id']); - if ($angeltype == null) { + if (empty($angeltype)) { error(_('Angeltype doesn\'t exist.')); redirect(page_link_to('angeltypes')); } $user_source = User($user_angeltype['user_id']); - if ($user_source == null) { + if (empty($user_source)) { error(_('User doesn\'t exist.')); redirect(page_link_to('angeltypes')); } @@ -252,19 +252,19 @@ function user_angeltype_update_controller() } $user_angeltype = UserAngelType($request->input('user_angeltype_id')); - if ($user_angeltype == null) { + if (empty($user_angeltype)) { error(_('User angeltype doesn\'t exist.')); redirect(page_link_to('angeltypes')); } $angeltype = AngelType($user_angeltype['angeltype_id']); - if ($angeltype == null) { + if (empty($angeltype)) { error(_('Angeltype doesn\'t exist.')); redirect(page_link_to('angeltypes')); } $user_source = User($user_angeltype['user_id']); - if ($user_source == null) { + if (empty($user_source)) { error(_('User doesn\'t exist.')); redirect(page_link_to('angeltypes')); } @@ -359,7 +359,7 @@ function user_angeltype_join_controller($angeltype) global $user, $privileges; $user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype); - if ($user_angeltype != null) { + if (!empty($user_angeltype)) { error(sprintf(_('You are already a %s.'), $angeltype['name'])); redirect(page_link_to('angeltypes')); } diff --git a/includes/controller/user_driver_licenses_controller.php b/includes/controller/user_driver_licenses_controller.php index 3db31eff..889b03e3 100644 --- a/includes/controller/user_driver_licenses_controller.php +++ b/includes/controller/user_driver_licenses_controller.php @@ -14,7 +14,7 @@ function user_driver_license_required_hint() $user_driver_license = UserDriverLicense($user['UID']); // User has already entered data, no hint needed. - if ($user_driver_license != null) { + if (!empty($user_driver_license)) { return null; } @@ -60,7 +60,7 @@ function user_driver_licenses_controller() */ function user_driver_license_edit_link($user = null) { - if ($user == null) { + if (empty($user)) { return page_link_to('user_driver_licenses'); } return page_link_to('user_driver_licenses', ['user_id' => $user['UID']]); @@ -79,7 +79,7 @@ function user_driver_license_load_user() if ($request->has('user_id')) { $user_source = User($request->input('user_id')); - if ($user_source == null) { + if (empty($user_source)) { redirect(user_driver_license_edit_link()); } } @@ -104,7 +104,7 @@ function user_driver_license_edit_controller() } $user_driver_license = UserDriverLicense($user_source['UID']); - if ($user_driver_license == null) { + if (empty($user_driver_license)) { $wants_to_drive = false; $user_driver_license = UserDriverLicense_new(); } else { @@ -122,7 +122,7 @@ function user_driver_license_edit_controller() $user_driver_license['has_license_forklift'] = $request->has('has_license_forklift'); if (UserDriverLicense_valid($user_driver_license)) { - if ($user_driver_license['user_id'] == null) { + if (empty($user_driver_license['user_id'])) { $user_driver_license = UserDriverLicenses_create($user_driver_license, $user_source); } else { UserDriverLicenses_update($user_driver_license); @@ -133,7 +133,7 @@ function user_driver_license_edit_controller() } else { error(_('Please select at least one driving license.')); } - } elseif ($user_driver_license['user_id'] != null) { + } elseif (!empty($user_driver_license['user_id'])) { UserDriverLicenses_delete($user_source['UID']); engelsystem_log('Driver license information removed.'); success(_('Your driver license information has been removed.')); diff --git a/includes/controller/user_worklog_controller.php b/includes/controller/user_worklog_controller.php index bd62c83c..a7218071 100644 --- a/includes/controller/user_worklog_controller.php +++ b/includes/controller/user_worklog_controller.php @@ -2,25 +2,27 @@ /** * Delete a work log entry. + * + * @return array */ function user_worklog_delete_controller() { global $user; - + $request = request(); $userWorkLog = UserWorkLog($request->input('user_worklog_id')); if (empty($userWorkLog)) { redirect(user_link($user)); } $user_source = User($userWorkLog['user_id']); - + if ($request->has('confirmed')) { UserWorkLog_delete($userWorkLog); - + success(_('Work log entry deleted.')); redirect(user_link($user_source)); } - + return [ UserWorkLog_delete_title(), UserWorkLog_delete_view($user_source, $userWorkLog) @@ -29,29 +31,31 @@ function user_worklog_delete_controller() /** * Edit work log for user. + * + * @return array */ function user_worklog_edit_controller() { global $user; - + $request = request(); $userWorkLog = UserWorkLog($request->input('user_worklog_id')); if (empty($userWorkLog)) { redirect(user_link($user)); } $user_source = User($userWorkLog['user_id']); - + if ($request->has('submit')) { list ($valid, $userWorkLog) = user_worklog_from_request($userWorkLog); - + if ($valid) { UserWorkLog_update($userWorkLog); - + success(_('Work log entry updated.')); redirect(user_link($user_source)); } } - + return [ UserWorkLog_edit_title(), UserWorkLog_edit_view($user_source, $userWorkLog) @@ -59,34 +63,38 @@ function user_worklog_edit_controller() } /** + * Handle form * - * @param UserWorkLog $userWorkLog - * @return [bool $valid, UserWorkLog $userWorkLog] + * @param array $userWorkLog + * @return array [bool $valid, UserWorkLog $userWorkLog] */ function user_worklog_from_request($userWorkLog) { $request = request(); - + $valid = true; - - $userWorkLog['work_timestamp'] = parse_date('Y-m-d H:i', $request->input('work_timestamp') . ' 00:00'); - if ($userWorkLog['work_timestamp'] == null) { + + $userWorkLog['work_timestamp'] = parse_date( + 'Y-m-d H:i', + $request->input('work_timestamp') . ' 00:00' + ); + if (is_null($userWorkLog['work_timestamp'])) { $valid = false; error(_('Please enter work date.')); } - + $userWorkLog['work_hours'] = $request->input('work_hours'); - if (! preg_match("/[0-9]+(\.[0-9]+)?/", $userWorkLog['work_hours'])) { + if (!preg_match("/[0-9]+(\.[0-9]+)?/", $userWorkLog['work_hours'])) { $valid = false; error(_('Please enter work hours in format ##[.##].')); } - + $userWorkLog['comment'] = $request->input('comment'); if (empty($userWorkLog['comment'])) { $valid = false; error(_('Please enter a comment.')); } - + return [ $valid, $userWorkLog @@ -95,30 +103,32 @@ function user_worklog_from_request($userWorkLog) /** * Add work log entry to user. + * + * @return array */ function user_worklog_add_controller() { global $user; - + $request = request(); $user_source = User($request->input('user_id')); if (empty($user_source)) { redirect(user_link($user)); } - + $userWorkLog = UserWorkLog_new($user_source); - + if ($request->has('submit')) { list ($valid, $userWorkLog) = user_worklog_from_request($userWorkLog); - + if ($valid) { UserWorkLog_create($userWorkLog); - + success(_('Work log entry created.')); redirect(user_link($user_source)); } } - + return [ UserWorkLog_add_title(), UserWorkLog_add_view($user_source, $userWorkLog) @@ -128,12 +138,14 @@ function user_worklog_add_controller() /** * Link to work log entry add for given user. * - * @param User $user + * @param array $user + * + * @return string */ function user_worklog_add_link($user) { return page_link_to('user_worklog', [ - 'action' => 'add', + 'action' => 'add', 'user_id' => $user['UID'] ]); } @@ -141,12 +153,13 @@ function user_worklog_add_link($user) /** * Link to work log entry edit. * - * @param UserWorkLog $userWorkLog + * @param array $userWorkLog + * @return string */ function user_worklog_edit_link($userWorkLog) { return page_link_to('user_worklog', [ - 'action' => 'edit', + 'action' => 'edit', 'user_worklog_id' => $userWorkLog['id'] ]); } @@ -154,34 +167,37 @@ function user_worklog_edit_link($userWorkLog) /** * Link to work log entry delete. * - * @param UserWorkLog $userWorkLog - * @param array[] $parameters + * @param array $userWorkLog + * @param array[] $parameters + * @return string */ function user_worklog_delete_link($userWorkLog, $parameters = []) { return page_link_to('user_worklog', array_merge([ - 'action' => 'delete', + 'action' => 'delete', 'user_worklog_id' => $userWorkLog['id'] ], $parameters)); } /** * Work log entry actions + * + * @return array */ -function user_worklogs_controller() +function user_worklog_controller() { global $user, $privileges; - - if (! in_array('admin_user_worklog', $privileges)) { + + if (!in_array('admin_user_worklog', $privileges)) { redirect(user_link($user)); } - + $request = request(); $action = $request->input('action'); - if (! $request->has('action')) { + if (!$request->has('action')) { redirect(user_link($user)); } - + switch ($action) { case 'add': return user_worklog_add_controller(); @@ -191,5 +207,3 @@ function user_worklogs_controller() return user_worklog_delete_controller(); } } - -?> \ No newline at end of file diff --git a/includes/controller/users_controller.php b/includes/controller/users_controller.php index 8a325621..b6334803 100644 --- a/includes/controller/users_controller.php +++ b/includes/controller/users_controller.php @@ -190,7 +190,7 @@ function user_controller() $user_source = $user; if ($request->has('user_id')) { $user_source = User($request->input('user_id')); - if ($user_source == null) { + if (empty($user_source)) { error(_('User not found.')); redirect(page_link_to('/')); } @@ -220,12 +220,12 @@ function user_controller() ); } } - + if ($user_source['api_key'] == '') { User_reset_api_key($user_source, false); } - - if($user_source['force_active']) { + + if ($user_source['force_active']) { $tshirt_score = _('Enough'); } else { $tshirt_score = sprintf('%.2f', User_tshirt_score($user_source)) . ' h'; @@ -297,7 +297,7 @@ function user_password_recovery_set_new_controller() { $request = request(); $user_source = User_by_password_recovery_token($request->input('token')); - if ($user_source == null) { + if (empty($user_source)) { error(_('Token is not correct.')); redirect(page_link_to('login')); } @@ -343,7 +343,7 @@ function user_password_recovery_start_controller() $email = strip_request_item('email'); if (check_email($email)) { $user_source = User_by_email($email); - if ($user_source == null) { + if (empty($user_source)) { $valid = false; error(_('E-mail address is not correct.')); } @@ -412,8 +412,7 @@ function load_user() } $user = User($request->input('user_id')); - - if ($user == null) { + if (empty($user)) { error(_('User doesn\'t exist.')); redirect(page_link_to()); } diff --git a/includes/engelsystem.php b/includes/engelsystem.php index 07abbb42..f7d813c5 100644 --- a/includes/engelsystem.php +++ b/includes/engelsystem.php @@ -1,14 +1,9 @@ make(Config::class); -$appConfig->set(require config_path('app.php')); -$app->bootstrap($appConfig); - - -/** - * Configure application - */ -date_default_timezone_set($app->get('config')->get('timezone')); - -if (config('environment') == 'development') { - $errorHandler = $app->get('error.handler'); - $errorHandler->setEnvironment(Handler::ENV_DEVELOPMENT); - $app->bind(HandlerInterface::class, 'error.handler.development'); - ini_set('display_errors', true); - error_reporting(E_ALL); -} else { - ini_set('display_errors', false); -} - - /** * Check for maintenance */ diff --git a/includes/helper/internationalization_helper.php b/includes/helper/internationalization_helper.php index 01aca71f..bb6d0abd 100644 --- a/includes/helper/internationalization_helper.php +++ b/includes/helper/internationalization_helper.php @@ -48,7 +48,7 @@ function gettext_init() */ function gettext_locale($locale = null) { - if ($locale == null) { + if (empty($locale)) { $locale = session()->get('locale'); } diff --git a/includes/model/AngelType_model.php b/includes/model/AngelType_model.php index 6feb9dd0..2dff7019 100644 --- a/includes/model/AngelType_model.php +++ b/includes/model/AngelType_model.php @@ -159,7 +159,7 @@ function AngelType_validate_name($name, $angeltype) if ($name == '') { return new ValidationResult(false, ''); } - if ($angeltype != null && isset($angeltype['id'])) { + if (!empty($angeltype) && isset($angeltype['id'])) { $valid = (count(DB::select(' SELECT `id` FROM `AngelTypes` @@ -229,8 +229,10 @@ function AngelType_ids() */ function AngelType($angeltype_id) { - return DB::selectOne( + $angelType = DB::selectOne( 'SELECT * FROM `AngelTypes` WHERE `id`=?', [$angeltype_id] ); + + return empty($angelType) ? null : $angelType; } diff --git a/includes/model/EventConfig_model.php b/includes/model/EventConfig_model.php index 646d19c5..766a5849 100644 --- a/includes/model/EventConfig_model.php +++ b/includes/model/EventConfig_model.php @@ -9,7 +9,9 @@ use Engelsystem\Database\DB; */ function EventConfig() { - return DB::selectOne('SELECT * FROM `EventConfig` LIMIT 1'); + $config = DB::selectOne('SELECT * FROM `EventConfig` LIMIT 1'); + + return empty($config) ? null : $config; } /** @@ -21,7 +23,7 @@ function EventConfig() * @param int $event_end_date * @param int $teardown_end_date * @param string $event_welcome_msg - * @return int Rows updated + * @return bool */ function EventConfig_update( $event_name, @@ -31,7 +33,8 @@ function EventConfig_update( $teardown_end_date, $event_welcome_msg ) { - if (EventConfig() == null) { + $eventConfig = EventConfig(); + if (empty($eventConfig)) { return DB::insert(' INSERT INTO `EventConfig` ( `event_name`, @@ -54,7 +57,7 @@ function EventConfig_update( ); } - return DB::update(' + return (bool)DB::update(' UPDATE `EventConfig` SET `event_name` = ?, `buildup_start_date` = ?, diff --git a/includes/model/LogEntries_model.php b/includes/model/LogEntries_model.php index f0ee6673..b16c598c 100644 --- a/includes/model/LogEntries_model.php +++ b/includes/model/LogEntries_model.php @@ -58,5 +58,5 @@ function LogEntries_filter($keyword) */ function LogEntries_clear_all() { - return DB::statement('TRUNCATE `LogEntries`'); + return DB::connection()->statement('TRUNCATE `LogEntries`'); } diff --git a/includes/model/Message_model.php b/includes/model/Message_model.php index 5185785a..3f66f74a 100644 --- a/includes/model/Message_model.php +++ b/includes/model/Message_model.php @@ -20,7 +20,9 @@ function Message_ids() */ function Message($message_id) { - return DB::selectOne('SELECT * FROM `Messages` WHERE `id`=? LIMIT 1', [$message_id]); + $message = DB::selectOne('SELECT * FROM `Messages` WHERE `id`=? LIMIT 1', [$message_id]); + + return empty($message) ? null : $message; } /** diff --git a/includes/model/Room_model.php b/includes/model/Room_model.php index f153cd52..b29f68fe 100644 --- a/includes/model/Room_model.php +++ b/includes/model/Room_model.php @@ -148,14 +148,16 @@ function Room_update($room_id, $name, $from_frab, $map_url, $description) * Returns room by id. * * @param int $room_id RID - * @return array|false + * @return array|null */ function Room($room_id) { - return DB::selectOne(' + $room = DB::selectOne(' SELECT * FROM `Room` WHERE `RID` = ?', [ $room_id ]); + + return empty($room) ? null : $room; } diff --git a/includes/model/ShiftEntry_model.php b/includes/model/ShiftEntry_model.php index bb9db49d..ebf600f3 100644 --- a/includes/model/ShiftEntry_model.php +++ b/includes/model/ShiftEntry_model.php @@ -138,7 +138,9 @@ function ShiftEntry_update($shift_entry) */ function ShiftEntry($shift_entry_id) { - return DB::selectOne('SELECT * FROM `ShiftEntry` WHERE `id` = ?', [$shift_entry_id]); + $shiftEntry = DB::selectOne('SELECT * FROM `ShiftEntry` WHERE `id` = ?', [$shift_entry_id]); + + return empty($shiftEntry) ? null : $shiftEntry; } /** diff --git a/includes/model/ShiftTypes_model.php b/includes/model/ShiftTypes_model.php index 3d2dc9fe..599810be 100644 --- a/includes/model/ShiftTypes_model.php +++ b/includes/model/ShiftTypes_model.php @@ -70,7 +70,9 @@ function ShiftType_create($name, $angeltype_id, $description) */ function ShiftType($shifttype_id) { - return DB::selectOne('SELECT * FROM `ShiftTypes` WHERE `id`=?', [$shifttype_id]); + $shiftType = DB::selectOne('SELECT * FROM `ShiftTypes` WHERE `id`=?', [$shifttype_id]); + + return empty($shiftType) ? null : $shiftType; } /** diff --git a/includes/model/ShiftsFilter.php b/includes/model/ShiftsFilter.php index 5ad7a9b3..fe3bfa56 100644 --- a/includes/model/ShiftsFilter.php +++ b/includes/model/ShiftsFilter.php @@ -48,7 +48,7 @@ class ShiftsFilter * @param int[] $rooms * @param int[] $types */ - public function __construct($user_shifts_admin, $rooms, $types) + public function __construct($user_shifts_admin = false, $rooms = [], $types = []) { $this->rooms = $rooms; $this->types = $types; @@ -62,6 +62,34 @@ class ShiftsFilter } } + /** + * @return array + */ + public function sessionExport() + { + return [ + 'userShiftsAdmin' => $this->userShiftsAdmin, + 'filled' => $this->filled, + 'rooms' => $this->rooms, + 'types' => $this->types, + 'startTime' => $this->startTime, + 'endTime' => $this->endTime, + ]; + } + + /** + * @param array $data + */ + public function sessionImport($data) + { + $this->userShiftsAdmin = $data['userShiftsAdmin']; + $this->filled = $data['filled']; + $this->rooms = $data['rooms']; + $this->types = $data['types']; + $this->startTime = $data['startTime']; + $this->endTime = $data['endTime']; + } + /** * @return int unix timestamp */ diff --git a/includes/model/Shifts_model.php b/includes/model/Shifts_model.php index 62335882..b5e3a205 100644 --- a/includes/model/Shifts_model.php +++ b/includes/model/Shifts_model.php @@ -323,7 +323,7 @@ function Shift_signup_allowed_angel( return new ShiftSignupState(ShiftSignupState::NOT_ARRIVED, $free_entries); } - if ($user_shifts == null) { + if (empty($user_shifts)) { $user_shifts = Shifts_by_user($user); } @@ -349,14 +349,14 @@ function Shift_signup_allowed_angel( return new ShiftSignupState(ShiftSignupState::OCCUPIED, $free_entries); } - if ($user_angeltype == null) { + if (empty($user_angeltype)) { $user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype); } if ( - $user_angeltype == null - || ($angeltype['no_self_signup'] == 1 && $user_angeltype != null) - || ($angeltype['restricted'] == 1 && $user_angeltype != null && !isset($user_angeltype['confirm_user_id'])) + empty($user_angeltype) + || ($angeltype['no_self_signup'] == 1 && !empty($user_angeltype)) + || ($angeltype['restricted'] == 1 && !empty($user_angeltype) && !isset($user_angeltype['confirm_user_id'])) ) { // you cannot join if user is not of this angel type // you cannot join if you are not confirmed @@ -552,7 +552,7 @@ function Shift_update($shift) * Update a shift by its external id. * * @param array $shift - * @return bool|null + * @return int * @throws Exception */ function Shift_update_by_psid($shift) diff --git a/includes/model/UserAngelTypes_model.php b/includes/model/UserAngelTypes_model.php index 71901b97..b1005095 100644 --- a/includes/model/UserAngelTypes_model.php +++ b/includes/model/UserAngelTypes_model.php @@ -197,11 +197,13 @@ function UserAngelType_create($user, $angeltype) */ function UserAngelType($user_angeltype_id) { - return DB::selectOne(' + $angelType = DB::selectOne(' SELECT * FROM `UserAngelTypes` WHERE `id`=? LIMIT 1', [$user_angeltype_id]); + + return empty($angelType) ? null : $angelType; } /** @@ -213,7 +215,7 @@ function UserAngelType($user_angeltype_id) */ function UserAngelType_by_User_and_AngelType($user, $angeltype) { - return DB::selectOne(' + $angelType = DB::selectOne(' SELECT * FROM `UserAngelTypes` WHERE `user_id`=? @@ -225,6 +227,8 @@ function UserAngelType_by_User_and_AngelType($user, $angeltype) $angeltype['id'] ] ); + + return empty($angelType) ? null : $angelType; } /** diff --git a/includes/model/UserDriverLicenses_model.php b/includes/model/UserDriverLicenses_model.php index dc38368b..2c251d66 100644 --- a/includes/model/UserDriverLicenses_model.php +++ b/includes/model/UserDriverLicenses_model.php @@ -45,10 +45,12 @@ function UserDriverLicense_valid($user_driver_license) */ function UserDriverLicense($user_id) { - return DB::selectOne(' + $driverLicense = DB::selectOne(' SELECT * FROM `UserDriverLicenses` WHERE `user_id`=?', [$user_id]); + + return empty($driverLicense) ? null : $driverLicense; } /** diff --git a/includes/model/UserWorkLog_model.php b/includes/model/UserWorkLog_model.php index 36442943..ff39ba8f 100644 --- a/includes/model/UserWorkLog_model.php +++ b/includes/model/UserWorkLog_model.php @@ -1,22 +1,27 @@ $user['UID'], + 'user_id' => $user['UID'], 'work_timestamp' => $work_date, - 'work_hours' => 0, - 'comment' => '' + 'work_hours' => 0, + 'comment' => '' ]; } - -?> \ No newline at end of file diff --git a/includes/model/User_model.php b/includes/model/User_model.php index 7ea3ca3e..d2498462 100644 --- a/includes/model/User_model.php +++ b/includes/model/User_model.php @@ -20,12 +20,14 @@ function User_delete($user_id) /** * Returns the tshirt score (number of hours counted for tshirt). * Accounts only ended shifts. - * + * * @param array[] $user + * @return int */ -function User_tshirt_score($user) { +function User_tshirt_score($user) +{ $shift_sum_formula = config('shift_sum_formula'); - + $result_shifts = DB::selectOne(' SELECT ROUND((' . $shift_sum_formula . ') / 3600, 2) AS `tshirt_score` FROM `User` LEFT JOIN `ShiftEntry` ON `User`.`UID` = `ShiftEntry`.`UID` @@ -43,11 +45,11 @@ function User_tshirt_score($user) { LEFT JOIN `UserWorkLog` ON `User`.`UID` = `UserWorkLog`.`user_id` WHERE `User`.`UID` = ? AND `UserWorkLog`.`work_timestamp` < ? - ',[ + ', [ $user['UID'], time() ]); - + return $result_shifts['tshirt_score'] + $result_worklog['tshirt_score']; } @@ -347,12 +349,12 @@ function User_validate_jabber($jabber) */ function User_validate_planned_arrival_date($planned_arrival_date) { - if ($planned_arrival_date == null) { + if (is_null($planned_arrival_date)) { // null is not okay return new ValidationResult(false, time()); } $event_config = EventConfig(); - if ($event_config == null) { + if (empty($event_config)) { // Nothing to validate against return new ValidationResult(true, $planned_arrival_date); } @@ -376,7 +378,7 @@ function User_validate_planned_arrival_date($planned_arrival_date) */ function User_validate_planned_departure_date($planned_arrival_date, $planned_departure_date) { - if ($planned_departure_date == null) { + if (is_null($planned_departure_date)) { // null is okay return new ValidationResult(true, null); } @@ -385,7 +387,7 @@ function User_validate_planned_departure_date($planned_arrival_date, $planned_de return new ValidationResult(false, $planned_arrival_date); } $event_config = EventConfig(); - if ($event_config == null) { + if (empty($event_config)) { // Nothing to validate against return new ValidationResult(true, $planned_departure_date); } @@ -408,7 +410,9 @@ function User_validate_planned_departure_date($planned_arrival_date, $planned_de */ function User($user_id) { - return DB::selectOne('SELECT * FROM `User` WHERE `UID`=? LIMIT 1', [$user_id]); + $user = DB::selectOne('SELECT * FROM `User` WHERE `UID`=? LIMIT 1', [$user_id]); + + return empty($user) ? null : $user; } /** @@ -419,18 +423,22 @@ function User($user_id) */ function User_by_api_key($api_key) { - return DB::selectOne('SELECT * FROM `User` WHERE `api_key`=? LIMIT 1', [$api_key]); + $user = DB::selectOne('SELECT * FROM `User` WHERE `api_key`=? LIMIT 1', [$api_key]); + + return empty($user) ? null : $user; } /** * Returns User by email. * * @param string $email - * @return array|null Matching user, null on error + * @return array|null Matching user, null when not found */ function User_by_email($email) { - return DB::selectOne('SELECT * FROM `User` WHERE `email`=? LIMIT 1', [$email]); + $user = DB::selectOne('SELECT * FROM `User` WHERE `email`=? LIMIT 1', [$email]); + + return empty($user) ? null : $user; } /** @@ -441,7 +449,9 @@ function User_by_email($email) */ function User_by_password_recovery_token($token) { - return DB::selectOne('SELECT * FROM `User` WHERE `password_recovery_token`=? LIMIT 1', [$token]); + $user = DB::selectOne('SELECT * FROM `User` WHERE `password_recovery_token`=? LIMIT 1', [$token]); + + return empty($user) ? null : $user; } /** diff --git a/includes/pages/admin_active.php b/includes/pages/admin_active.php index 2616de6c..33a7e01e 100644 --- a/includes/pages/admin_active.php +++ b/includes/pages/admin_active.php @@ -101,7 +101,7 @@ function admin_active() if ($request->has('active') && preg_match('/^\d+$/', $request->input('active'))) { $user_id = $request->input('active'); $user_source = User($user_id); - if ($user_source != null) { + if (!empty($user_source)) { DB::update('UPDATE `User` SET `Aktiv`=1 WHERE `UID`=? LIMIT 1', [$user_id]); engelsystem_log('User ' . User_Nick_render($user_source) . ' is active now.'); $msg = success(_('Angel has been marked as active.'), true); @@ -111,7 +111,7 @@ function admin_active() } elseif ($request->has('not_active') && preg_match('/^\d+$/', $request->input('not_active'))) { $user_id = $request->input('not_active'); $user_source = User($user_id); - if ($user_source != null) { + if (!empty($user_source)) { DB::update('UPDATE `User` SET `Aktiv`=0 WHERE `UID`=? LIMIT 1', [$user_id]); engelsystem_log('User ' . User_Nick_render($user_source) . ' is NOT active now.'); $msg = success(_('Angel has been marked as not active.'), true); @@ -121,7 +121,7 @@ function admin_active() } elseif ($request->has('tshirt') && preg_match('/^\d+$/', $request->input('tshirt'))) { $user_id = $request->input('tshirt'); $user_source = User($user_id); - if ($user_source != null) { + if (!empty($user_source)) { DB::update('UPDATE `User` SET `Tshirt`=1 WHERE `UID`=? LIMIT 1', [$user_id]); engelsystem_log('User ' . User_Nick_render($user_source) . ' has tshirt now.'); $msg = success(_('Angel has got a t-shirt.'), true); @@ -131,7 +131,7 @@ function admin_active() } elseif ($request->has('not_tshirt') && preg_match('/^\d+$/', $request->input('not_tshirt'))) { $user_id = $request->input('not_tshirt'); $user_source = User($user_id); - if ($user_source != null) { + if (!empty($user_source)) { DB::update('UPDATE `User` SET `Tshirt`=0 WHERE `UID`=? LIMIT 1', [$user_id]); engelsystem_log('User ' . User_Nick_render($user_source) . ' has NO tshirt.'); $msg = success(_('Angel has got no t-shirt.'), true); @@ -252,8 +252,8 @@ function admin_active() $gc = array_shift($gc); $shirt_statistics[] = [ - 'size' => $size, - 'given' => (int)$gc + 'size' => $size, + 'given' => (int)$gc ]; } } @@ -261,8 +261,8 @@ function admin_active() $shirtCount = User_tshirts_count(); $shirt_statistics[] = [ - 'size' => '' . _('Sum') . '', - 'given' => '' . $shirtCount . '' + 'size' => '' . _('Sum') . '', + 'given' => '' . $shirtCount . '' ]; return page_with_title(admin_active_title(), [ @@ -288,8 +288,8 @@ function admin_active() ], $matched_users), '

' . _('Shirt statistics') . '

', table([ - 'size' => _('Size'), - 'given' => _('Given shirts') + 'size' => _('Size'), + 'given' => _('Given shirts') ], $shirt_statistics) ]); } diff --git a/includes/pages/admin_arrive.php b/includes/pages/admin_arrive.php index e925bfd4..b1c38453 100644 --- a/includes/pages/admin_arrive.php +++ b/includes/pages/admin_arrive.php @@ -27,7 +27,7 @@ function admin_arrive() if ($request->has('reset') && preg_match('/^\d+$/', $request->input('reset'))) { $user_id = $request->input('reset'); $user_source = User($user_id); - if ($user_source != null) { + if (!empty($user_source)) { DB::update(' UPDATE `User` SET `Gekommen`=0, `arrival_date` = NULL @@ -43,7 +43,7 @@ function admin_arrive() } elseif ($request->has('arrived') && preg_match('/^\d+$/', $request->input('arrived'))) { $user_id = $request->input('arrived'); $user_source = User($user_id); - if ($user_source != null) { + if (!empty($user_source)) { DB::update(' UPDATE `User` SET `Gekommen`=1, `arrival_date`=? @@ -84,7 +84,7 @@ function admin_arrive() } $usr['nick'] = User_Nick_render($usr); - if ($usr['planned_departure_date'] != null) { + if (!is_null($usr['planned_departure_date'])) { $usr['rendered_planned_departure_date'] = date('Y-m-d', $usr['planned_departure_date']); } else { $usr['rendered_planned_departure_date'] = '-'; @@ -110,7 +110,7 @@ function admin_arrive() $arrival_count_at_day[$day]++; } - if ($usr['planned_arrival_date'] != null) { + if (!is_null($usr['planned_arrival_date'])) { $day = date('Y-m-d', $usr['planned_arrival_date']); if (!isset($planned_arrival_count_at_day[$day])) { $planned_arrival_count_at_day[$day] = 0; @@ -118,7 +118,7 @@ function admin_arrive() $planned_arrival_count_at_day[$day]++; } - if ($usr['planned_departure_date'] != null && $usr['Gekommen'] == 1) { + if (!is_null($usr['planned_departure_date']) && $usr['Gekommen'] == 1) { $day = date('Y-m-d', $usr['planned_departure_date']); if (!isset($planned_departure_count_at_day[$day])) { $planned_departure_count_at_day[$day] = 0; diff --git a/includes/pages/admin_questions.php b/includes/pages/admin_questions.php index 0636a1d9..2d058b0d 100644 --- a/includes/pages/admin_questions.php +++ b/includes/pages/admin_questions.php @@ -111,7 +111,7 @@ function admin_questions() 'SELECT * FROM `Questions` WHERE `QID`=? LIMIT 1', [$question_id] ); - if (!empty($question) && $question['AID'] == null) { + if (!empty($question) && empty($question['AID'])) { $answer = trim( preg_replace("/([^\p{L}\p{P}\p{Z}\p{N}\n]{1,})/ui", '', diff --git a/includes/pages/admin_rooms.php b/includes/pages/admin_rooms.php index 8144b328..bbbc24ae 100644 --- a/includes/pages/admin_rooms.php +++ b/includes/pages/admin_rooms.php @@ -55,7 +55,7 @@ function admin_rooms() if (test_request_int('id')) { $room = Room($request->input('id')); - if ($room == null) { + if (empty($room)) { redirect(page_link_to('admin_rooms')); } @@ -127,7 +127,7 @@ function admin_rooms() $needed_angeltype_info = []; foreach ($angeltypes_count as $angeltype_id => $angeltype_count) { $angeltype = AngelType($angeltype_id); - if ($angeltype != null) { + if (!empty($angeltype)) { NeededAngelType_add(null, $angeltype_id, $room_id, $angeltype_count); if ($angeltype_count > 0) { $needed_angeltype_info[] = $angeltype['name'] . ': ' . $angeltype_count; diff --git a/includes/pages/admin_shifts.php b/includes/pages/admin_shifts.php index c80603a1..3fecbcd5 100644 --- a/includes/pages/admin_shifts.php +++ b/includes/pages/admin_shifts.php @@ -53,7 +53,7 @@ function admin_shifts() if ($request->has('preview') || $request->has('back')) { if ($request->has('shifttype_id')) { $shifttype = ShiftType($request->input('shifttype_id')); - if ($shifttype == null) { + if (empty($shifttype)) { $valid = false; error(_('Please select a shift type.')); } else { diff --git a/includes/pages/admin_user.php b/includes/pages/admin_user.php index 8da09e81..514e4b1b 100644 --- a/includes/pages/admin_user.php +++ b/includes/pages/admin_user.php @@ -34,7 +34,7 @@ function admin_user() $user_id = $request->input('id'); if (!$request->has('action')) { $user_source = User($user_id); - if ($user_source == null) { + if (empty($user_source)) { error(_('This user does not exist.')); redirect(users_link()); } diff --git a/includes/pages/guest_login.php b/includes/pages/guest_login.php index bed42ee5..47e16915 100644 --- a/includes/pages/guest_login.php +++ b/includes/pages/guest_login.php @@ -279,7 +279,7 @@ function guest_register() } // If a welcome message is present, display registration success page. - if ($event_config != null && $event_config['event_welcome_msg'] != null) { + if (!empty($event_config) && !empty($event_config['event_welcome_msg'])) { return User_registration_success_view($event_config['event_welcome_msg']); } @@ -289,7 +289,7 @@ function guest_register() $buildup_start_date = time(); $teardown_end_date = null; - if ($event_config != null) { + if (!empty($event_config)) { if (isset($event_config['buildup_start_date'])) { $buildup_start_date = $event_config['buildup_start_date']; } diff --git a/includes/pages/user_atom.php b/includes/pages/user_atom.php index c36e1dfd..9934fb92 100644 --- a/includes/pages/user_atom.php +++ b/includes/pages/user_atom.php @@ -16,7 +16,7 @@ function user_atom() $key = $request->input('key'); $user = User_by_api_key($key); - if ($user == null) { + if (empty($user)) { engelsystem_error('Key invalid.'); } if (!in_array('atom', privileges_for_user($user['UID']))) { diff --git a/includes/pages/user_ical.php b/includes/pages/user_ical.php index 69a260a2..3430c3b3 100644 --- a/includes/pages/user_ical.php +++ b/includes/pages/user_ical.php @@ -14,7 +14,7 @@ function user_ical() $key = $request->input('key'); $user = User_by_api_key($key); - if ($user == null) { + if (empty($user)) { engelsystem_error('Key invalid.'); } diff --git a/includes/pages/user_myshifts.php b/includes/pages/user_myshifts.php index f605792f..b61fc1e4 100644 --- a/includes/pages/user_myshifts.php +++ b/includes/pages/user_myshifts.php @@ -32,7 +32,6 @@ function user_myshifts() } $shifts_user = DB::selectOne('SELECT * FROM `User` WHERE `UID`=? LIMIT 1', [$shift_entry_id]); - if ($request->has('reset')) { if ($request->input('reset') == 'ack') { User_reset_api_key($user); @@ -72,7 +71,7 @@ function user_myshifts() $shifts_user['UID'], ] ); - if (count($shift) > 0) { + if (!empty($shift)) { $freeloaded = $shift['freeloaded']; $freeload_comment = $shift['freeload_comment']; diff --git a/includes/pages/user_settings.php b/includes/pages/user_settings.php index bdc8b70d..b3a5bdf5 100644 --- a/includes/pages/user_settings.php +++ b/includes/pages/user_settings.php @@ -215,7 +215,7 @@ function user_settings() $buildup_start_date = null; $teardown_end_date = null; $event_config = EventConfig(); - if ($event_config != null) { + if (!empty($event_config)) { if (isset($event_config['buildup_start_date'])) { $buildup_start_date = $event_config['buildup_start_date']; } diff --git a/includes/pages/user_shifts.php b/includes/pages/user_shifts.php index f3ffd501..186301db 100644 --- a/includes/pages/user_shifts.php +++ b/includes/pages/user_shifts.php @@ -47,7 +47,7 @@ function user_shifts() function update_ShiftsFilter_timerange(ShiftsFilter $shiftsFilter, $days) { $start_time = $shiftsFilter->getStartTime(); - if ($start_time == null) { + if (is_null($start_time)) { $start_time = time(); } @@ -177,18 +177,19 @@ function view_user_shifts() $rooms = load_rooms(); $types = load_types(); - if (!$session->has('ShiftsFilter')) { + if (!$session->has('shifts-filter')) { $room_ids = [ $rooms[0]['id'] ]; $type_ids = array_map('get_ids_from_array', $types); $shiftsFilter = new ShiftsFilter(in_array('user_shifts_admin', $privileges), $room_ids, $type_ids); - $session->set('ShiftsFilter', $shiftsFilter); + $session->set('shifts-filter', $shiftsFilter->sessionExport()); } - /** @var ShiftsFilter $shiftsFilter */ - $shiftsFilter = $session->get('ShiftsFilter'); + $shiftsFilter = new ShiftsFilter(); + $shiftsFilter->sessionImport($session->get('shifts-filter')); update_ShiftsFilter($shiftsFilter, in_array('user_shifts_admin', $privileges), $days); + $session->set('shifts-filter', $shiftsFilter->sessionExport()); $shiftCalendarRenderer = shiftCalendarRendererByShiftFilter($shiftsFilter); diff --git a/includes/sys_page.php b/includes/sys_page.php index 33ec18b9..55fb3b38 100644 --- a/includes/sys_page.php +++ b/includes/sys_page.php @@ -42,9 +42,10 @@ function check_request_datetime($date_name, $time_name, $allowed_days, $default_ function parse_date($pattern, $value) { $datetime = DateTime::createFromFormat($pattern, trim($value)); - if ($datetime == null) { + if (!$datetime) { return null; } + return $datetime->getTimestamp(); } diff --git a/includes/view/AngelTypes_view.php b/includes/view/AngelTypes_view.php index 6cefbb24..93fa03b5 100644 --- a/includes/view/AngelTypes_view.php +++ b/includes/view/AngelTypes_view.php @@ -28,9 +28,9 @@ function AngelType_name_render($angeltype) */ function AngelType_render_membership($user_angeltype) { - if ($user_angeltype['user_angeltype_id'] != null) { + if (!empty($user_angeltype['user_angeltype_id'])) { if ($user_angeltype['restricted']) { - if ($user_angeltype['confirm_user_id'] == null) { + if (empty($user_angeltype['confirm_user_id'])) { return glyph('lock') . _('Unconfirmed'); } elseif ($user_angeltype['supporter']) { return glyph_bool(true) . _('Supporter'); @@ -145,18 +145,18 @@ function AngelType_view_buttons($angeltype, $user_angeltype, $admin_angeltypes, ); } - if ($user_angeltype == null) { + if (is_null($user_angeltype)) { $buttons[] = button( page_link_to('user_angeltypes', ['action' => 'add', 'angeltype_id' => $angeltype['id']]), _('join'), 'add' ); } else { - if ($angeltype['requires_driver_license'] && $user_driver_license == null) { + if ($angeltype['requires_driver_license'] && empty($user_driver_license)) { error(_('This angeltype requires a driver license. Please enter your driver license information!')); } - if ($angeltype['restricted'] && $user_angeltype['confirm_user_id'] == null) { + if ($angeltype['restricted'] && empty($user_angeltype['confirm_user_id'])) { error(sprintf( _('You are unconfirmed for this angeltype. Please go to the introduction for %s to get confirmed.'), $angeltype['name'] @@ -212,7 +212,7 @@ function AngelType_view_members($angeltype, $members, $admin_user_angeltypes, $a $member['has_license_forklift'] = glyph_bool($member['has_license_forklift']); } - if ($angeltype['restricted'] && $member['confirm_user_id'] == null) { + if ($angeltype['restricted'] && empty($member['confirm_user_id'])) { $member['actions'] = table_buttons([ button( page_link_to( @@ -526,7 +526,7 @@ function AngelTypes_about_view_angeltype($angeltype) if (isset($angeltype['user_angeltype_id'])) { $buttons = []; - if ($angeltype['user_angeltype_id'] != null) { + if (!empty($angeltype['user_angeltype_id'])) { $buttons[] = button( page_link_to( 'user_angeltypes', diff --git a/includes/view/EventConfig_view.php b/includes/view/EventConfig_view.php index 25c4b225..fe6de670 100644 --- a/includes/view/EventConfig_view.php +++ b/includes/view/EventConfig_view.php @@ -8,7 +8,7 @@ */ function EventConfig_countdown_page($event_config) { - if ($event_config == null) { + if (empty($event_config)) { return div('col-md-12 text-center', [ heading(sprintf(_('Welcome to the %s!'), ' ENGELSYSTEM'), 2) ]); @@ -16,7 +16,7 @@ function EventConfig_countdown_page($event_config) $elements = []; - if ($event_config['event_name'] != null) { + if (!is_null($event_config['event_name'])) { $elements[] = div('col-sm-12 text-center', [ heading(sprintf( _('Welcome to the %s!'), @@ -25,7 +25,7 @@ function EventConfig_countdown_page($event_config) ]); } - if ($event_config['buildup_start_date'] != null && time() < $event_config['buildup_start_date']) { + if (!is_null($event_config['buildup_start_date']) && time() < $event_config['buildup_start_date']) { $elements[] = div('col-sm-3 text-center hidden-xs', [ heading(_('Buildup starts'), 4), '%c', @@ -33,7 +33,7 @@ function EventConfig_countdown_page($event_config) ]); } - if ($event_config['event_start_date'] != null && time() < $event_config['event_start_date']) { + if (!is_null($event_config['event_start_date']) && time() < $event_config['event_start_date']) { $elements[] = div('col-sm-3 text-center hidden-xs', [ heading(_('Event starts'), 4), '%c', @@ -41,7 +41,7 @@ function EventConfig_countdown_page($event_config) ]); } - if ($event_config['event_end_date'] != null && time() < $event_config['event_end_date']) { + if (!is_null($event_config['event_end_date']) && time() < $event_config['event_end_date']) { $elements[] = div('col-sm-3 text-center hidden-xs', [ heading(_('Event ends'), 4), '%c', @@ -49,7 +49,7 @@ function EventConfig_countdown_page($event_config) ]); } - if ($event_config['teardown_end_date'] != null && time() < $event_config['teardown_end_date']) { + if (!is_null($event_config['teardown_end_date']) && time() < $event_config['teardown_end_date']) { $elements[] = div('col-sm-3 text-center hidden-xs', [ heading(_('Teardown ends'), 4), '%c', @@ -68,15 +68,15 @@ function EventConfig_countdown_page($event_config) */ function EventConfig_info($event_config) { - if ($event_config == null) { + if (empty($event_config)) { return ''; } // Event name, start+end date are set if ( - $event_config['event_name'] != null - && $event_config['event_start_date'] != null - && $event_config['event_end_date'] != null + !is_null($event_config['event_name']) + && !is_null($event_config['event_start_date']) + && !is_null($event_config['event_end_date']) ) { return sprintf( _('%s, from %s to %s'), @@ -87,7 +87,7 @@ function EventConfig_info($event_config) } // Event name, start date are set - if ($event_config['event_name'] != null && $event_config['event_start_date'] != null) { + if (!is_null($event_config['event_name']) && !is_null($event_config['event_start_date'])) { return sprintf( _('%s, starting %s'), $event_config['event_name'], date(_('Y-m-d'), $event_config['event_start_date']) @@ -95,7 +95,7 @@ function EventConfig_info($event_config) } // Event start+end date are set - if ($event_config['event_start_date'] != null && $event_config['event_end_date'] != null) { + if (!is_null($event_config['event_start_date']) && !is_null($event_config['event_end_date'])) { return sprintf( _('Event from %s to %s'), date(_('Y-m-d'), $event_config['event_start_date']), @@ -104,7 +104,7 @@ function EventConfig_info($event_config) } // Only event name is set - if ($event_config['event_name'] != null) { + if (!is_null($event_config['event_name'])) { return sprintf($event_config['event_name']); } diff --git a/includes/view/ShiftCalendarRenderer.php b/includes/view/ShiftCalendarRenderer.php index 98f40d49..731d063a 100644 --- a/includes/view/ShiftCalendarRenderer.php +++ b/includes/view/ShiftCalendarRenderer.php @@ -129,7 +129,7 @@ class ShiftCalendarRenderer */ public function getBlocksPerSlot() { - if ($this->blocksPerSlot == null) { + if (is_null($this->blocksPerSlot)) { $this->blocksPerSlot = $this->calcBlocksPerSlot(); } return $this->blocksPerSlot; diff --git a/includes/view/ShiftCalendarShiftRenderer.php b/includes/view/ShiftCalendarShiftRenderer.php index 8bfb18ea..9643f195 100644 --- a/includes/view/ShiftCalendarShiftRenderer.php +++ b/includes/view/ShiftCalendarShiftRenderer.php @@ -116,7 +116,7 @@ class ShiftCalendarShiftRenderer $angeltype, $user ); - if ($shift_signup_state == null) { + if (is_null($shift_signup_state)) { $shift_signup_state = $angeltype_signup_state; } else { $shift_signup_state->combineWith($angeltype_signup_state); @@ -124,7 +124,7 @@ class ShiftCalendarShiftRenderer $html .= $angeltype_html; } } - if ($shift_signup_state == null) { + if (is_null($shift_signup_state)) { $shift_signup_state = new ShiftSignupState(ShiftSignupState::SHIFT_ENDED, 0); } diff --git a/includes/view/Shifts_view.php b/includes/view/Shifts_view.php index 755fab74..c5680578 100644 --- a/includes/view/Shifts_view.php +++ b/includes/view/Shifts_view.php @@ -50,14 +50,14 @@ function Shift_view_header($shift, $room) function Shift_editor_info_render($shift) { $info = []; - if ($shift['created_by_user_id'] != null) { + if (!empty($shift['created_by_user_id'])) { $info[] = sprintf( glyph('plus') . _('created at %s by %s'), date('Y-m-d H:i', $shift['created_at_timestamp']), User_Nick_render(User($shift['created_by_user_id'])) ); } - if ($shift['edited_by_user_id'] != null) { + if (!empty($shift['edited_by_user_id'])) { $info[] = sprintf( glyph('pencil') . _('edited at %s by %s'), date('Y-m-d H:i', $shift['edited_at_timestamp']), @@ -77,13 +77,13 @@ function Shift_signup_button_render($shift, $angeltype, $user_angeltype = null) { global $user; - if ($user_angeltype == null) { + if (empty($user_angeltype)) { $user_angeltype = UserAngelType_by_User_and_AngelType($user, $angeltype); } if ($angeltype['shift_signup_state']->isSignupAllowed()) { return button(shift_entry_create_link($shift, $angeltype), _('Sign up')); - } elseif ($user_angeltype == null) { + } elseif (empty($user_angeltype)) { return button( page_link_to('angeltypes', ['action' => 'view', 'angeltype_id' => $angeltype['id']]), sprintf(_('Become %s'), diff --git a/includes/view/UserHintsRenderer.php b/includes/view/UserHintsRenderer.php index a2bc62f9..8d749ee9 100644 --- a/includes/view/UserHintsRenderer.php +++ b/includes/view/UserHintsRenderer.php @@ -36,7 +36,7 @@ class UserHintsRenderer */ public function addHint($hint, $important = false) { - if ($hint != null && $hint != '') { + if (!empty($hint)) { if ($important) { $this->important = true; $this->hints[] = error($hint, true); diff --git a/includes/view/UserWorkLog_view.php b/includes/view/UserWorkLog_view.php index 79c049b3..772d4aee 100644 --- a/includes/view/UserWorkLog_view.php +++ b/includes/view/UserWorkLog_view.php @@ -2,13 +2,18 @@ /** * Delete work log entry. - * @param User $user_source - * @param UserWorkLog $userWorkLog + * + * @param array $user_source + * @param array $userWorkLog + * @return string */ function UserWorkLog_delete_view($user_source, $userWorkLog) { return page_with_title(UserWorkLog_delete_title(), [ - info(sprintf(_('Do you want to delete the worklog entry for %s?'), User_Nick_render($user_source)), true), + info(sprintf( + _('Do you want to delete the worklog entry for %s?'), + User_Nick_render($user_source) + ), true), buttons([ button(user_link($user_source), glyph('remove') . _('cancel')), button(user_worklog_delete_link($userWorkLog, [ @@ -28,9 +33,10 @@ function UserWorkLog_delete_title() /** * Render edit table. - * - * @param User $user_source - * @param UserWorkLog $userWorkLog + * + * @param array $user_source + * @param array $userWorkLog + * @return string */ function UserWorkLog_edit_form($user_source, $userWorkLog) { @@ -46,8 +52,9 @@ function UserWorkLog_edit_form($user_source, $userWorkLog) /** * Form for edit a user work log entry. * - * @param User $user_source - * @param UserWorkLog $userWorkLog + * @param array $user_source + * @param array $userWorkLog + * @return string */ function UserWorkLog_edit_view($user_source, $userWorkLog) { @@ -63,8 +70,9 @@ function UserWorkLog_edit_view($user_source, $userWorkLog) /** * Form for adding a user work log entry. * - * @param User $user_source - * @param UserWorkLog $userWorkLog + * @param array $user_source + * @param array $userWorkLog + * @return string */ function UserWorkLog_add_view($user_source, $userWorkLog) { @@ -92,5 +100,3 @@ function UserWorkLog_add_title() { return _('Add work log entry'); } - -?> \ No newline at end of file diff --git a/includes/view/User_view.php b/includes/view/User_view.php index 2f53e641..8eee610a 100644 --- a/includes/view/User_view.php +++ b/includes/view/User_view.php @@ -406,10 +406,21 @@ function User_view_myshift($shift, $user_source, $its_me) * @param array[] $shifts * @param array $user_source * @param bool $its_me + * @param int $tshirt_score + * @param bool $tshirt_admin + * @param array[] $user_worklogs + * @param $admin_user_worklog_privilege * @return array */ -function User_view_myshifts($shifts, $user_source, $its_me, $tshirt_score, $tshirt_admin, $user_worklogs, $admin_user_worklog_privilege) -{ +function User_view_myshifts( + $shifts, + $user_source, + $its_me, + $tshirt_score, + $tshirt_admin, + $user_worklogs, + $admin_user_worklog_privilege +) { $myshifts_table = []; $timesum = 0; foreach ($shifts as $shift) { @@ -420,8 +431,8 @@ function User_view_myshifts($shifts, $user_source, $its_me, $tshirt_score, $tshi } } - if($its_me || $admin_user_worklog_privilege) { - foreach($user_worklogs as $worklog) { + if ($its_me || $admin_user_worklog_privilege) { + foreach ($user_worklogs as $worklog) { $myshifts_table[$worklog['work_timestamp']] = User_view_worklog($worklog, $admin_user_worklog_privilege); $timesum += $worklog['work_hours'] * 3600; } @@ -453,12 +464,15 @@ function User_view_myshifts($shifts, $user_source, $its_me, $tshirt_score, $tshi /** * Renders table entry for user work log - * @param UserWorkLog $worklog - * @param bool $admin_user_worklog_privilege + * + * @param array $worklog + * @param bool $admin_user_worklog_privilege + * @return array */ -function User_view_worklog($worklog, $admin_user_worklog_privilege) { +function User_view_worklog($worklog, $admin_user_worklog_privilege) +{ $actions = ''; - if($admin_user_worklog_privilege) { + if ($admin_user_worklog_privilege) { $actions = table_buttons([ button( user_worklog_edit_link($worklog), @@ -472,18 +486,18 @@ function User_view_worklog($worklog, $admin_user_worklog_privilege) { ) ]); } - + return [ 'date' => glyph('calendar') . date('Y-m-d', $worklog['work_timestamp']), 'duration' => '' . sprintf('%.2f', $worklog['work_hours']) . '', 'room' => '', 'shift_info' => _('Work log entry'), 'comment' => $worklog['comment'] . '
' - . sprintf( - _('Added by %s at %s'), - User_Nick_render(User($worklog['created_user_id'])), - date('Y-m-d H:i', $worklog['created_timestamp']) - ), + . sprintf( + _('Added by %s at %s'), + User_Nick_render(User($worklog['created_user_id'])), + date('Y-m-d H:i', $worklog['created_timestamp']) + ), 'actions' => $actions ]; } @@ -500,6 +514,8 @@ function User_view_worklog($worklog, $admin_user_worklog_privilege) { * @param bool $its_me * @param int $tshirt_score * @param bool $tshirt_admin + * @param bool $admin_user_worklog_privilege + * @param array[] $user_worklogs * @return string */ function User_view( @@ -517,9 +533,17 @@ function User_view( ) { $user_name = htmlspecialchars($user_source['Vorname']) . ' ' . htmlspecialchars($user_source['Name']); $myshifts_table = ''; - if($its_me || $admin_user_privilege) { - $my_shifts = User_view_myshifts($shifts, $user_source, $its_me, $tshirt_score, $tshirt_admin, $user_worklogs, $admin_user_worklog_privilege); - if(count($my_shifts) > 0) { + if ($its_me || $admin_user_privilege) { + $my_shifts = User_view_myshifts( + $shifts, + $user_source, + $its_me, + $tshirt_score, + $tshirt_admin, + $user_worklogs, + $admin_user_worklog_privilege + ); + if (count($my_shifts) > 0) { $myshifts_table = table([ 'date' => _('Day & time'), 'duration' => _('Duration'), @@ -528,7 +552,7 @@ function User_view( 'comment' => _('Comment'), 'actions' => _('Action') ], $my_shifts); - } elseif($user_source['force_active']) { + } elseif ($user_source['force_active']) { $myshifts_table = success(_('You have done enough to get a t-shirt.'), true); } } @@ -748,7 +772,7 @@ function User_angeltypes_render($user_angeltypes) $output = []; foreach ($user_angeltypes as $angeltype) { $class = 'text-success'; - if ($angeltype['restricted'] == 1 && $angeltype['confirm_user_id'] == null) { + if ($angeltype['restricted'] == 1 && empty($angeltype['confirm_user_id'])) { $class = 'text-warning'; } $output[] = '' @@ -821,7 +845,7 @@ function render_user_departure_date_hint() { global $user; - if (!isset($user['planned_departure_date']) || $user['planned_departure_date'] == null) { + if (!isset($user['planned_departure_date']) || empty($user['planned_departure_date'])) { $text = _('Please enter your planned date of departure on your settings page to give us a feeling for teardown capacities.'); return render_profile_link($text, null, 'alert-link'); } @@ -857,7 +881,7 @@ function render_user_arrived_hint() if ($user['Gekommen'] == 0) { $event_config = EventConfig(); - if (!is_null($event_config) + if (!empty($event_config) && !is_null($event_config['buildup_start_date']) && time() > $event_config['buildup_start_date']) { return _('You are not marked as arrived. Please go to heaven\'s desk, get your angel badge and/or tell them that you arrived already.'); diff --git a/public/index.php b/public/index.php index 2b480723..35c85955 100755 --- a/public/index.php +++ b/public/index.php @@ -127,7 +127,7 @@ if ( $content = user_shifts(); break; case 'user_worklog': - list($title, $content) = user_worklogs_controller(); + list($title, $content) = user_worklog_controller(); break; case 'user_messages': $title = messages_title(); diff --git a/src/Application.php b/src/Application.php index c9023c7b..68ce9e33 100644 --- a/src/Application.php +++ b/src/Application.php @@ -5,6 +5,7 @@ namespace Engelsystem; use Engelsystem\Config\Config; use Engelsystem\Container\Container; use Engelsystem\Container\ServiceProvider; +use Illuminate\Container\Container as IlluminateContainer; use Psr\Container\ContainerInterface; class Application extends Container @@ -44,6 +45,7 @@ class Application extends Container $this->instance('container', $this); $this->instance(Container::class, $this); $this->instance(Application::class, $this); + $this->instance(IlluminateContainer::class, $this); $this->bind(ContainerInterface::class, Application::class); } diff --git a/src/Config/Config.php b/src/Config/Config.php index 34c21a78..b1a93324 100644 --- a/src/Config/Config.php +++ b/src/Config/Config.php @@ -2,14 +2,16 @@ namespace Engelsystem\Config; -class Config +use Illuminate\Support\Fluent; + +class Config extends Fluent { /** * The config values * * @var array */ - protected $data = []; + protected $attributes = []; /** * @param string|null $key @@ -19,11 +21,11 @@ class Config public function get($key, $default = null) { if (is_null($key)) { - return $this->data; + return $this->attributes; } if ($this->has($key)) { - return $this->data[$key]; + return $this->attributes[$key]; } return $default; @@ -43,7 +45,7 @@ class Config return; } - $this->data[$key] = $value; + $this->attributes[$key] = $value; } /** @@ -52,7 +54,7 @@ class Config */ public function has($key) { - return isset($this->data[$key]); + return $this->offsetExists($key); } /** @@ -60,41 +62,6 @@ class Config */ public function remove($key) { - unset($this->data[$key]); - } - - /** - * @param string $key - * @return mixed - */ - public function __get($key) - { - return $this->get($key); - } - - /** - * @param string $key - * @param mixed $value - */ - public function __set($key, $value) - { - $this->set($key, $value); - } - - /** - * @param string $key - * @return bool - */ - public function __isset($key) - { - return $this->has($key); - } - - /** - * @param string $key - */ - public function __unset($key) - { - $this->remove($key); + $this->offsetUnset($key); } } diff --git a/src/Database/DatabaseServiceProvider.php b/src/Database/DatabaseServiceProvider.php index 49fb4af5..7328bc4e 100644 --- a/src/Database/DatabaseServiceProvider.php +++ b/src/Database/DatabaseServiceProvider.php @@ -4,23 +4,40 @@ namespace Engelsystem\Database; use Engelsystem\Container\ServiceProvider; use Exception; -use PDO; +use Illuminate\Database\Capsule\Manager as CapsuleManager; +use PDOException; class DatabaseServiceProvider extends ServiceProvider { public function register() { $config = $this->app->get('config'); - Db::connect( - 'mysql:host=' . $config->get('database')['host'] - . ';dbname=' . $config->get('database')['db'] - . ';charset=utf8', - $config->get('database')['user'], - $config->get('database')['pw'] - ) || $this->exitOnError(); + $capsule = $this->app->make(CapsuleManager::class); - Db::getPdo()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - Db::getPdo()->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); + $dbConfig = $config->get('database'); + $capsule->addConnection(array_merge([ + 'driver' => 'mysql', + 'host' => '', + 'database' => '', + 'username' => '', + 'password' => '', + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', + ], $dbConfig)); + + $capsule->setAsGlobal(); + $capsule->bootEloquent(); + $capsule->getConnection()->useDefaultSchemaGrammar(); + + try { + $capsule->getConnection()->getPdo(); + } catch (PDOException $e) { + $this->exitOnError(); + } + + $this->app->instance('db', $capsule); + Db::setDbManager($capsule); } /** diff --git a/src/Database/Db.php b/src/Database/Db.php index 114bd8fc..c0871e68 100644 --- a/src/Database/Db.php +++ b/src/Database/Db.php @@ -2,68 +2,23 @@ namespace Engelsystem\Database; +use Illuminate\Database\Capsule\Manager as CapsuleManager; +use Illuminate\Database\Connection as DatabaseConnection; use PDO; -use PDOException; -use PDOStatement; class Db { - /** @var PDO */ - protected static $db; - - /** @var PDOStatement */ - protected static $stm = null; - - /** @var bool */ - protected static $lastStatus = true; + /** @var CapsuleManager */ + protected static $dbManager; /** - * Connect to database + * Set the database connection manager * - * @param string $dsn - * @param string $username - * @param string $password - * @param array $options - * @return bool + * @param CapsuleManager $dbManager */ - public static function connect($dsn, $username = null, $password = null, $options = []) + public static function setDbManager($dbManager) { - try { - self::$db = new PDO($dsn, $username, $password, $options); - } catch (PDOException $e) { - return false; - } - - return true; - } - - /** - * Run a prepared query - * - * @param string $query - * @param array $bindings - * @return PDOStatement - */ - public static function query($query, array $bindings = []) - { - self::$stm = self::$db->prepare($query); - self::$lastStatus = self::$stm->execute($bindings); - - return self::$stm; - } - - /** - * Run a sql query - * - * @param string $query - * @return bool - */ - public static function unprepared($query) - { - self::$stm = self::$db->query($query); - self::$lastStatus = (self::$stm instanceof PDOStatement); - - return self::$lastStatus; + self::$dbManager = $dbManager; } /** @@ -75,9 +30,14 @@ class Db */ public static function select($query, array $bindings = []) { - self::query($query, $bindings); + $return = self::connection()->select($query, $bindings); - return self::$stm->fetchAll(PDO::FETCH_ASSOC); + // @TODO: Remove type casting + foreach ($return as $key => $value) { + $return[$key] = (array)$value; + } + + return $return; } /** @@ -89,13 +49,15 @@ class Db */ public static function selectOne($query, array $bindings = []) { - $result = self::select($query, $bindings); + $result = self::connection()->selectOne($query, $bindings); + // @TODO: remove typecast + $result = (array)$result; if (empty($result)) { return null; } - return array_shift($result); + return $result; } /** @@ -103,13 +65,11 @@ class Db * * @param string $query * @param array $bindings - * @return int Row count + * @return bool */ public static function insert($query, array $bindings = []) { - self::query($query, $bindings); - - return self::$stm->rowCount(); + return self::connection()->insert($query, $bindings); } /** @@ -121,9 +81,7 @@ class Db */ public static function update($query, array $bindings = []) { - self::query($query, $bindings); - - return self::$stm->rowCount(); + return self::connection()->update($query, $bindings); } /** @@ -135,37 +93,15 @@ class Db */ public static function delete($query, array $bindings = []) { - self::query($query, $bindings); - - return self::$stm->rowCount(); + return self::connection()->delete($query, $bindings); } /** - * Run a single statement - * - * @param string $query - * @param array $bindings - * @return bool + * @return DatabaseConnection */ - public static function statement($query, array $bindings = []) + public static function connection() { - self::query($query, $bindings); - - return self::$lastStatus; - } - - /** - * Returns the last error - * - * @return array - */ - public static function getError() - { - if (!self::$stm instanceof PDOStatement) { - return [-1, null, null]; - } - - return self::$stm->errorInfo(); + return self::$dbManager->getConnection(); } /** @@ -175,14 +111,6 @@ class Db */ public static function getPdo() { - return self::$db; - } - - /** - * @return PDOStatement|false|null - */ - public static function getStm() - { - return self::$stm; + return self::connection()->getPdo(); } } diff --git a/src/Database/Migration/Migrate.php b/src/Database/Migration/Migrate.php new file mode 100644 index 00000000..3a08bb6e --- /dev/null +++ b/src/Database/Migration/Migrate.php @@ -0,0 +1,192 @@ +app = $app; + $this->scheme = $scheme; + $this->output = function () { }; + } + + /** + * Run a migration + * + * @param string $path + * @param string $type (up|down) + * @param bool $oneStep + */ + public function run($path, $type = self::UP, $oneStep = false) + { + $this->initMigration(); + $migrations = $this->getMigrations($path); + $migrated = $this->getMigrated(); + + if ($type == self::DOWN) { + $migrations = array_reverse($migrations, true); + } + + foreach ($migrations as $file => $migration) { + if ( + ($type == self::UP && $migrated->contains('migration', $migration)) + || ($type == self::DOWN && !$migrated->contains('migration', $migration)) + ) { + call_user_func($this->output, 'Skipping ' . $migration); + continue; + } + + call_user_func($this->output, 'Migrating ' . $migration . ' (' . $type . ')'); + + $this->migrate($file, $migration, $type); + $this->setMigrated($migration, $type); + + if ($oneStep) { + return; + } + } + } + + /** + * Get all migrated migrations + * + * @return Collection + */ + protected function getMigrated() + { + return $this->getTableQuery()->get(); + } + + /** + * Migrate a migration + * + * @param string $file + * @param string $migration + * @param string $type (up|down) + */ + protected function migrate($file, $migration, $type = self::UP) + { + require_once $file; + + $className = Str::studly(preg_replace('/\d+_/', '', $migration)); + /** @var Migration $class */ + $class = $this->app->make($className); + + if (method_exists($class, $type)) { + $class->{$type}(); + } + } + + /** + * Set a migration to migrated + * + * @param string $migration + * @param string $type (up|down) + */ + protected function setMigrated($migration, $type = self::UP) + { + $table = $this->getTableQuery(); + + if ($type == self::DOWN) { + $table->where(['migration' => $migration])->delete(); + return; + } + + $table->insert(['migration' => $migration]); + } + + /** + * Get a list of migration files + * + * @param string $dir + * @return array + */ + protected function getMigrations($dir) + { + $files = $this->getMigrationFiles($dir); + + $migrations = []; + foreach ($files as $dir) { + $name = str_replace('.php', '', basename($dir)); + $migrations[$dir] = $name; + } + + asort($migrations); + return $migrations; + } + + /** + * List all migration files from the given directory + * + * @param string $dir + * @return array + */ + protected function getMigrationFiles($dir) + { + return glob($dir . '/*_*.php'); + } + + /** + * Setup migration tables + */ + protected function initMigration() + { + if ($this->scheme->hasTable($this->table)) { + return; + } + + $this->scheme->create($this->table, function (Blueprint $table) { + $table->increments('id'); + $table->string('migration'); + }); + } + + /** + * Init a table query + * + * @return Builder + */ + protected function getTableQuery() + { + return $this->scheme->getConnection()->table($this->table); + } + + /** + * Set the output function + * + * @param callable $output + */ + public function setOutput(callable $output) + { + $this->output = $output; + } +} diff --git a/src/Database/Migration/Migration.php b/src/Database/Migration/Migration.php new file mode 100644 index 00000000..fcc57b82 --- /dev/null +++ b/src/Database/Migration/Migration.php @@ -0,0 +1,16 @@ +schema = $schemaBuilder; + } +} diff --git a/src/Database/Migration/MigrationServiceProvider.php b/src/Database/Migration/MigrationServiceProvider.php new file mode 100644 index 00000000..15d06eaf --- /dev/null +++ b/src/Database/Migration/MigrationServiceProvider.php @@ -0,0 +1,20 @@ +getSchemaBuilder(); + $this->app->instance('db.scheme', $schema); + $this->app->bind(SchemaBuilder::class, 'db.scheme'); + + $migration = $this->app->make(Migrate::class); + $this->app->instance('db.migration', $migration); + } +} diff --git a/src/helpers.php b/src/helpers.php index 3f118bf3..339936e3 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -64,21 +64,6 @@ function config_path($path = '') return app('path.config') . (empty($path) ? '' : DIRECTORY_SEPARATOR . $path); } -/** - * @param string $key - * @param mixed $default - * @return mixed - */ -function env($key, $default = null) -{ - $value = getenv($key); - if ($value === false) { - return $default; - } - - return $value; -} - /** * @param string $key * @param mixed $default diff --git a/tests/Feature/Model/RoomModelTest.php b/tests/Feature/Model/RoomModelTest.php index 4edb20c3..22aa4b8e 100644 --- a/tests/Feature/Model/RoomModelTest.php +++ b/tests/Feature/Model/RoomModelTest.php @@ -24,11 +24,11 @@ class RoomModelTest extends TestCase $room = Room($this->room_id); - $this->assertNotFalse($room); + $this->assertNotEmpty($room); $this->assertNotNull($room); $this->assertEquals($room['Name'], 'test'); - $this->assertNull(Room(-1)); + $this->assertEmpty(Room(-1)); } public function tearDown() diff --git a/tests/Unit/Database/DatabaseServiceProviderTest.php b/tests/Unit/Database/DatabaseServiceProviderTest.php index 61848c35..8f7898cd 100644 --- a/tests/Unit/Database/DatabaseServiceProviderTest.php +++ b/tests/Unit/Database/DatabaseServiceProviderTest.php @@ -6,32 +6,86 @@ use Engelsystem\Config\Config; use Engelsystem\Database\DatabaseServiceProvider; use Engelsystem\Test\Unit\ServiceProviderTest; use Exception; -use PHPUnit_Framework_MockObject_MockObject; +use Illuminate\Database\Capsule\Manager as CapsuleManager; +use Illuminate\Database\Connection; +use PDOException; +use PHPUnit_Framework_MockObject_MockObject as MockObject; class DatabaseServiceProviderTest extends ServiceProviderTest { /** * @covers \Engelsystem\Database\DatabaseServiceProvider::register() - * @covers \Engelsystem\Database\DatabaseServiceProvider::exitOnError() */ public function testRegister() { - /** @var PHPUnit_Framework_MockObject_MockObject|Config $config */ - $config = $this->getMockBuilder(Config::class) - ->getMock(); + list($app, $dbManager) = $this->prepare(['driver' => 'sqlite', 'database' => ':memory:']); - $app = $this->getApp(['get']); + $this->setExpects($app, 'instance', ['db', $dbManager]); + + $serviceProvider = new DatabaseServiceProvider($app); + $serviceProvider->register(); + } + + /** + * @covers \Engelsystem\Database\DatabaseServiceProvider::register() + * @covers \Engelsystem\Database\DatabaseServiceProvider::exitOnError() + */ + public function testRegisterError() + { + list($app) = $this->prepare([ + 'host' => 'localhost', + 'database' => 'database', + 'username' => 'user', + 'password' => 'password', + ], true); - $this->setExpects($app, 'get', ['config'], $config); - $this->setExpects($config, 'get', ['database'], [ - 'host' => 'localhost', - 'db' => 'database', - 'user' => 'user', - 'pw' => 'password', - ], $this->atLeastOnce()); $this->expectException(Exception::class); $serviceProvider = new DatabaseServiceProvider($app); $serviceProvider->register(); } + + /** + * Prepare some mocks + * + * @param array $dbConfigData + * @param bool $getPdoThrowException + * @return array + */ + protected function prepare($dbConfigData, $getPdoThrowException = false) + { + /** @var MockObject|Config $config */ + $config = $this->getMockBuilder(Config::class) + ->getMock(); + /** @var MockObject|CapsuleManager $config */ + $dbManager = $this->getMockBuilder(CapsuleManager::class) + ->getMock(); + /** @var MockObject|Connection $connection */ + $connection = $this->getMockBuilder(Connection::class) + ->disableOriginalConstructor() + ->getMock(); + + $app = $this->getApp(['get', 'make', 'instance']); + + $this->setExpects($app, 'get', ['config'], $config); + $this->setExpects($app, 'make', [CapsuleManager::class], $dbManager); + $this->setExpects($config, 'get', ['database'], $dbConfigData, $this->atLeastOnce()); + + $this->setExpects($dbManager, 'setAsGlobal'); + $this->setExpects($dbManager, 'bootEloquent'); + + $this->setExpects($connection, 'useDefaultSchemaGrammar'); + $connection->expects($this->once()) + ->method('getPdo') + ->willReturnCallback(function () use ($getPdoThrowException) { + if ($getPdoThrowException) { + throw new PDOException(); + } + + return ''; + }); + $this->setExpects($dbManager, 'getConnection', [], $connection, $this->atLeastOnce()); + + return [$app, $dbManager]; + } } diff --git a/tests/Unit/Database/DbTest.php b/tests/Unit/Database/DbTest.php index 63607cad..ca6ac52c 100644 --- a/tests/Unit/Database/DbTest.php +++ b/tests/Unit/Database/DbTest.php @@ -3,45 +3,45 @@ namespace Engelsystem\Test\Unit\Database; use Engelsystem\Database\Db; +use Illuminate\Database\Capsule\Manager as CapsuleManager; +use Illuminate\Database\Connection as DatabaseConnection; use PDO; -use PDOStatement; use PHPUnit\Framework\TestCase; -use ReflectionObject; -use Throwable; +use PHPUnit_Framework_MockObject_MockObject as MockObject; class DbTest extends TestCase { /** - * @covers \Engelsystem\Database\Db::connect() + * @covers \Engelsystem\Database\Db::setDbManager() + * @covers \Engelsystem\Database\Db::connection() */ - public function testConnect() + public function testSetDbManager() { - $result = Db::connect('mysql:host=localhost;dbname=someTestDatabaseThatDoesNotExist;charset=utf8'); - $this->assertFalse($result); + /** @var MockObject|Pdo $pdo */ + $pdo = $this->getMockBuilder(Pdo::class) + ->disableOriginalConstructor() + ->getMock(); + /** @var MockObject|CapsuleManager $dbManager */ + $dbManager = $this->getMockBuilder(CapsuleManager::class) + ->disableOriginalConstructor() + ->getMock(); + /** @var MockObject|DatabaseConnection $dbManager */ + $databaseConnection = $this->getMockBuilder(DatabaseConnection::class) + ->disableOriginalConstructor() + ->getMock(); - $result = Db::connect('sqlite::memory:'); - $this->assertTrue($result); - } + $dbManager + ->expects($this->atLeastOnce()) + ->method('getConnection') + ->willReturn($databaseConnection); + $databaseConnection + ->expects($this->atLeastOnce()) + ->method('getPdo') + ->willReturn($pdo); - /** - * @covers \Engelsystem\Database\Db::query() - */ - public function testQuery() - { - $stm = Db::query('SELECT * FROM test_data'); - $this->assertEquals('00000', $stm->errorCode()); - - $stm = Db::query('SELECT * FROM test_data WHERE id = ?', [4]); - $this->assertEquals('00000', $stm->errorCode()); - } - - /** - * @covers \Engelsystem\Database\Db::unprepared() - */ - public function testUnprepared() - { - $return = Db::unprepared('SELECT * FROM test_data WHERE id = 3'); - $this->assertTrue($return); + Db::setDbManager($dbManager); + $this->assertEquals($pdo, Db::getPdo()); + $this->assertEquals($databaseConnection, Db::connection()); } /** @@ -77,11 +77,8 @@ class DbTest extends TestCase */ public function testInsert() { - $count = Db::insert("INSERT INTO test_data (id, data) VALUES (5, 'Some random text'), (6, 'another text')"); - $this->assertEquals(2, $count); - - $count = Db::insert('INSERT INTO test_data(id, data) VALUES (:id, :alias)', ['id' => 7, 'alias' => 'Blafoo']); - $this->assertEquals(1, $count); + $result = Db::insert("INSERT INTO test_data (id, data) VALUES (5, 'Some random text'), (6, 'another text')"); + $this->assertTrue($result); } /** @@ -108,42 +105,6 @@ class DbTest extends TestCase $this->assertEquals(3, $count); } - /** - * @covers \Engelsystem\Database\Db::statement() - */ - public function testStatement() - { - $return = Db::statement('SELECT * FROM test_data WHERE id = 3'); - $this->assertTrue($return); - - $return = Db::statement('SELECT * FROM test_data WHERE id = ?', [2]); - $this->assertTrue($return); - } - - /** - * @covers \Engelsystem\Database\Db::getError() - */ - public function testGetError() - { - try { - Db::statement('foo'); - } catch (Throwable $e) { - } - - $error = Db::getError(); - $this->assertTrue(is_array($error)); - $this->assertEquals('near "foo": syntax error', $error[2]); - - $db = new Db(); - $refObject = new ReflectionObject($db); - $refProperty = $refObject->getProperty('stm'); - $refProperty->setAccessible(true); - $refProperty->setValue(null, null); - - $error = Db::getError(); - $this->assertEquals([-1, null, null], $error); - } - /** * @covers \Engelsystem\Database\Db::getPdo() */ @@ -153,30 +114,26 @@ class DbTest extends TestCase $this->assertInstanceOf(PDO::class, $pdo); } - /** - * @covers \Engelsystem\Database\Db::getStm() - */ - public function testGetStm() - { - $stm = Db::getStm(); - $this->assertInstanceOf(PDOStatement::class, $stm); - } - /** * Setup in memory database */ protected function setUp() { - Db::connect('sqlite::memory:'); + $dbManager = new CapsuleManager(); + $dbManager->addConnection(['driver' => 'sqlite', 'database' => ':memory:']); + $dbManager->setAsGlobal(); + $dbManager->bootEloquent(); + + Db::setDbManager($dbManager); Db::getPdo()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - Db::query( + Db::connection()->statement( ' CREATE TABLE test_data( id INT PRIMARY KEY NOT NULL, data TEXT NOT NULL ); '); - Db::query('CREATE UNIQUE INDEX test_data_id_uindex ON test_data (id);'); + Db::connection()->statement('CREATE UNIQUE INDEX test_data_id_uindex ON test_data (id);'); Db::insert(" INSERT INTO test_data (id, data) VALUES diff --git a/tests/Unit/Database/Migration/MigrateTest.php b/tests/Unit/Database/Migration/MigrateTest.php new file mode 100644 index 00000000..c88ad777 --- /dev/null +++ b/tests/Unit/Database/Migration/MigrateTest.php @@ -0,0 +1,160 @@ +getMockBuilder(Application::class) + ->setMethods(['instance']) + ->getMock(); + /** @var MockObject|SchemaBuilder $builder */ + $builder = $this->getMockBuilder(SchemaBuilder::class) + ->disableOriginalConstructor() + ->getMock(); + /** @var MockObject|Migrate $migration */ + $migration = $this->getMockBuilder(Migrate::class) + ->setConstructorArgs([$builder, $app]) + ->setMethods(['initMigration', 'getMigrationFiles', 'getMigrated', 'migrate', 'setMigrated']) + ->getMock(); + + $migration->expects($this->atLeastOnce()) + ->method('initMigration'); + $migration->expects($this->atLeastOnce()) + ->method('getMigrationFiles') + ->willReturn([ + 'foo/1234_01_23_123456_init_foo.php', + 'foo/9876_03_22_210000_random_hack.php', + 'foo/4567_11_01_000000_do_stuff.php', + 'foo/9999_99_99_999999_another_foo.php', + ]); + $migration->expects($this->atLeastOnce()) + ->method('getMigrated') + ->willReturn(new Collection([ + ['id' => 1, 'migration' => '1234_01_23_123456_init_foo'], + ['id' => 2, 'migration' => '4567_11_01_000000_do_stuff'], + ])); + $migration->expects($this->atLeastOnce()) + ->method('migrate') + ->withConsecutive( + ['foo/9876_03_22_210000_random_hack.php', '9876_03_22_210000_random_hack', Migrate::UP], + ['foo/9999_99_99_999999_another_foo.php', '9999_99_99_999999_another_foo', Migrate::UP], + ['foo/9876_03_22_210000_random_hack.php', '9876_03_22_210000_random_hack', Migrate::UP], + ['foo/4567_11_01_000000_do_stuff.php', '4567_11_01_000000_do_stuff', Migrate::DOWN] + ); + $migration->expects($this->atLeastOnce()) + ->method('setMigrated') + ->withConsecutive( + ['9876_03_22_210000_random_hack', Migrate::UP], + ['9999_99_99_999999_another_foo', Migrate::UP], + ['9876_03_22_210000_random_hack', Migrate::UP], + ['4567_11_01_000000_do_stuff', Migrate::DOWN] + ); + + $messages = []; + $migration->setOutput(function ($text) use (&$messages) { + $messages[] = $text; + }); + + $migration->run('foo', Migrate::UP); + + $this->assertCount(4, $messages); + foreach ( + [ + 'init_foo' => 'skipping', + 'do_stuff' => 'skipping', + 'random_hack' => 'migrating', + 'another_foo' => 'migrating', + ] as $value => $type + ) { + $contains = false; + foreach ($messages as $message) { + if (!Str::contains(strtolower($message), $type) || !Str::contains(strtolower($message), $value)) { + continue; + } + + $contains = true; + break; + } + + $this->assertTrue($contains, sprintf('Missing message "%s: %s"', $type, $value)); + } + + $messages = []; + $migration->run('foo', Migrate::UP, true); + $this->assertCount(3, $messages); + + $migration->run('foo', Migrate::DOWN, true); + } + + /** + * @covers \Engelsystem\Database\Migration\Migrate::getMigrated + * @covers \Engelsystem\Database\Migration\Migrate::migrate + * @covers \Engelsystem\Database\Migration\Migrate::setMigrated + * @covers \Engelsystem\Database\Migration\Migrate::getMigrationFiles + * @covers \Engelsystem\Database\Migration\Migrate::initMigration + * @covers \Engelsystem\Database\Migration\Migrate::getTableQuery + */ + public function testRunIntegration() + { + $app = new Application(); + $dbManager = new CapsuleManager($app); + $dbManager->addConnection(['driver' => 'sqlite', 'database' => ':memory:']); + $dbManager->bootEloquent(); + $db = $dbManager->getConnection(); + $db->useDefaultSchemaGrammar(); + $scheme = $db->getSchemaBuilder(); + + $app->instance('scheme', $scheme); + $app->bind(SchemaBuilder::class, 'scheme'); + + $migration = new Migrate($scheme, $app); + + $messages = []; + $migration->setOutput(function ($msg) use (&$messages) { + $messages[] = $msg; + }); + + $migration->run(__DIR__ . '/Stub', Migrate::UP); + + $this->assertTrue($scheme->hasTable('migrations')); + + $migrations = $db->table('migrations')->get(); + $this->assertCount(3, $migrations); + + $this->assertTrue($migrations->contains('migration', '2001_04_11_123456_create_lorem_ipsum_table')); + $this->assertTrue($migrations->contains('migration', '2017_12_24_053300_another_stuff')); + $this->assertTrue($migrations->contains('migration', '2022_12_22_221222_add_some_feature')); + + $this->assertTrue($scheme->hasTable('lorem_ipsum')); + + $migration->run(__DIR__ . '/Stub', Migrate::DOWN, true); + + $migrations = $db->table('migrations')->get(); + $this->assertCount(2, $migrations); + + $migration->run(__DIR__ . '/Stub', Migrate::DOWN); + + $migrations = $db->table('migrations')->get(); + $this->assertCount(0, $migrations); + + $this->assertFalse($scheme->hasTable('lorem_ipsum')); + } +} diff --git a/tests/Unit/Database/Migration/MigrationServiceProviderTest.php b/tests/Unit/Database/Migration/MigrationServiceProviderTest.php new file mode 100644 index 00000000..a99cdebe --- /dev/null +++ b/tests/Unit/Database/Migration/MigrationServiceProviderTest.php @@ -0,0 +1,55 @@ +getMockBuilder(Migrate::class) + ->disableOriginalConstructor() + ->getMock(); + /** @var MockObject|CapsuleManager $dbManager */ + $dbManager = $this->getMockBuilder(CapsuleManager::class) + ->disableOriginalConstructor() + ->getMock(); + /** @var MockObject|Connection $dbConnection */ + $dbConnection = $this->getMockBuilder(Connection::class) + ->disableOriginalConstructor() + ->getMock(); + /** @var MockObject|SchemaBuilder $schemaBuilder */ + $schemaBuilder = $this->getMockBuilder(SchemaBuilder::class) + ->disableOriginalConstructor() + ->getMock(); + + $app = $this->getApp(['make', 'instance', 'bind']); + + $app->expects($this->atLeastOnce()) + ->method('instance') + ->withConsecutive(['db.scheme'], ['db.migration']) + ->willReturnOnConsecutiveCalls($schemaBuilder, $migration); + + $this->setExpects($app, 'bind', [SchemaBuilder::class, 'db.scheme']); + $this->setExpects($app, 'make', [Migrate::class], $migration); + + $this->setExpects($dbConnection, 'getSchemaBuilder', null, $schemaBuilder); + $this->setExpects($dbManager, 'getConnection', null, $dbConnection); + Db::setDbManager($dbManager); + + $serviceProvider = new MigrationServiceProvider($app); + $serviceProvider->register(); + } +} diff --git a/tests/Unit/Database/Migration/MigrationTest.php b/tests/Unit/Database/Migration/MigrationTest.php new file mode 100644 index 00000000..43bded09 --- /dev/null +++ b/tests/Unit/Database/Migration/MigrationTest.php @@ -0,0 +1,24 @@ +getMockBuilder(SchemaBuilder::class) + ->disableOriginalConstructor() + ->getMock(); + + $instance = new AnotherStuff($schemaBuilder); + $this->assertAttributeEquals($schemaBuilder, 'schema', $instance); + } +} diff --git a/tests/Unit/Database/Migration/Stub/2001_04_11_123456_create_lorem_ipsum_table.php b/tests/Unit/Database/Migration/Stub/2001_04_11_123456_create_lorem_ipsum_table.php new file mode 100644 index 00000000..0cc89e07 --- /dev/null +++ b/tests/Unit/Database/Migration/Stub/2001_04_11_123456_create_lorem_ipsum_table.php @@ -0,0 +1,27 @@ +schema->create('lorem_ipsum', function (Blueprint $table) { + $table->increments('id'); + $table->string('name')->unique(); + $table->string('email'); + }); + } + + /** + * Reverse the migration + */ + public function down() + { + $this->schema->dropIfExists('lorem_ipsum'); + } +} diff --git a/tests/Unit/Database/Migration/Stub/2017_12_24_053300_another_stuff.php b/tests/Unit/Database/Migration/Stub/2017_12_24_053300_another_stuff.php new file mode 100644 index 00000000..d4d7e5f8 --- /dev/null +++ b/tests/Unit/Database/Migration/Stub/2017_12_24_053300_another_stuff.php @@ -0,0 +1,22 @@ +